conn_service.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /* Service connection management
  3. *
  4. * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
  5. * Written by David Howells (dhowells@redhat.com)
  6. */
  7. #include <linux/slab.h>
  8. #include "ar-internal.h"
  9. /*
  10. * Find a service connection under RCU conditions.
  11. *
  12. * We could use a hash table, but that is subject to bucket stuffing by an
  13. * attacker as the client gets to pick the epoch and cid values and would know
  14. * the hash function. So, instead, we use a hash table for the peer and from
  15. * that an rbtree to find the service connection. Under ordinary circumstances
  16. * it might be slower than a large hash table, but it is at least limited in
  17. * depth.
  18. */
  19. struct rxrpc_connection *rxrpc_find_service_conn_rcu(struct rxrpc_peer *peer,
  20. struct sk_buff *skb)
  21. {
  22. struct rxrpc_connection *conn = NULL;
  23. struct rxrpc_conn_proto k;
  24. struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
  25. struct rb_node *p;
  26. unsigned int seq = 1;
  27. k.epoch = sp->hdr.epoch;
  28. k.cid = sp->hdr.cid & RXRPC_CIDMASK;
  29. do {
  30. /* Unfortunately, rbtree walking doesn't give reliable results
  31. * under just the RCU read lock, so we have to check for
  32. * changes.
  33. */
  34. seq++; /* 2 on the 1st/lockless path, otherwise odd */
  35. read_seqbegin_or_lock(&peer->service_conn_lock, &seq);
  36. p = rcu_dereference_raw(peer->service_conns.rb_node);
  37. while (p) {
  38. conn = rb_entry(p, struct rxrpc_connection, service_node);
  39. if (conn->proto.index_key < k.index_key)
  40. p = rcu_dereference_raw(p->rb_left);
  41. else if (conn->proto.index_key > k.index_key)
  42. p = rcu_dereference_raw(p->rb_right);
  43. else
  44. break;
  45. conn = NULL;
  46. }
  47. } while (need_seqretry(&peer->service_conn_lock, seq));
  48. done_seqretry(&peer->service_conn_lock, seq);
  49. _leave(" = %d", conn ? conn->debug_id : -1);
  50. return conn;
  51. }
  52. /*
  53. * Insert a service connection into a peer's tree, thereby making it a target
  54. * for incoming packets.
  55. */
  56. static void rxrpc_publish_service_conn(struct rxrpc_peer *peer,
  57. struct rxrpc_connection *conn)
  58. {
  59. struct rxrpc_connection *cursor = NULL;
  60. struct rxrpc_conn_proto k = conn->proto;
  61. struct rb_node **pp, *parent;
  62. write_seqlock(&peer->service_conn_lock);
  63. pp = &peer->service_conns.rb_node;
  64. parent = NULL;
  65. while (*pp) {
  66. parent = *pp;
  67. cursor = rb_entry(parent,
  68. struct rxrpc_connection, service_node);
  69. if (cursor->proto.index_key < k.index_key)
  70. pp = &(*pp)->rb_left;
  71. else if (cursor->proto.index_key > k.index_key)
  72. pp = &(*pp)->rb_right;
  73. else
  74. goto found_extant_conn;
  75. }
  76. rb_link_node_rcu(&conn->service_node, parent, pp);
  77. rb_insert_color(&conn->service_node, &peer->service_conns);
  78. conn_published:
  79. set_bit(RXRPC_CONN_IN_SERVICE_CONNS, &conn->flags);
  80. write_sequnlock(&peer->service_conn_lock);
  81. _leave(" = %d [new]", conn->debug_id);
  82. return;
  83. found_extant_conn:
  84. if (refcount_read(&cursor->ref) == 0)
  85. goto replace_old_connection;
  86. write_sequnlock(&peer->service_conn_lock);
  87. /* We should not be able to get here. rxrpc_incoming_connection() is
  88. * called in a non-reentrant context, so there can't be a race to
  89. * insert a new connection.
  90. */
  91. BUG();
  92. replace_old_connection:
  93. /* The old connection is from an outdated epoch. */
  94. _debug("replace conn");
  95. rb_replace_node_rcu(&cursor->service_node,
  96. &conn->service_node,
  97. &peer->service_conns);
  98. clear_bit(RXRPC_CONN_IN_SERVICE_CONNS, &cursor->flags);
  99. goto conn_published;
  100. }
  101. /*
  102. * Preallocate a service connection. The connection is placed on the proc and
  103. * reap lists so that we don't have to get the lock from BH context.
  104. */
  105. struct rxrpc_connection *rxrpc_prealloc_service_connection(struct rxrpc_net *rxnet,
  106. gfp_t gfp)
  107. {
  108. struct rxrpc_connection *conn = rxrpc_alloc_connection(rxnet, gfp);
  109. if (conn) {
  110. /* We maintain an extra ref on the connection whilst it is on
  111. * the rxrpc_connections list.
  112. */
  113. conn->state = RXRPC_CONN_SERVICE_PREALLOC;
  114. refcount_set(&conn->ref, 2);
  115. atomic_inc(&rxnet->nr_conns);
  116. write_lock(&rxnet->conn_lock);
  117. list_add_tail(&conn->link, &rxnet->service_conns);
  118. list_add_tail(&conn->proc_link, &rxnet->conn_proc_list);
  119. write_unlock(&rxnet->conn_lock);
  120. rxrpc_see_connection(conn, rxrpc_conn_new_service);
  121. }
  122. return conn;
  123. }
  124. /*
  125. * Set up an incoming connection. This is called in BH context with the RCU
  126. * read lock held.
  127. */
  128. void rxrpc_new_incoming_connection(struct rxrpc_sock *rx,
  129. struct rxrpc_connection *conn,
  130. const struct rxrpc_security *sec,
  131. struct sk_buff *skb)
  132. {
  133. struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
  134. _enter("");
  135. conn->proto.epoch = sp->hdr.epoch;
  136. conn->proto.cid = sp->hdr.cid & RXRPC_CIDMASK;
  137. conn->orig_service_id = sp->hdr.serviceId;
  138. conn->service_id = sp->hdr.serviceId;
  139. conn->security_ix = sp->hdr.securityIndex;
  140. conn->out_clientflag = 0;
  141. conn->security = sec;
  142. if (conn->security_ix)
  143. conn->state = RXRPC_CONN_SERVICE_UNSECURED;
  144. else
  145. conn->state = RXRPC_CONN_SERVICE;
  146. /* See if we should upgrade the service. This can only happen on the
  147. * first packet on a new connection. Once done, it applies to all
  148. * subsequent calls on that connection.
  149. */
  150. if (sp->hdr.userStatus == RXRPC_USERSTATUS_SERVICE_UPGRADE &&
  151. conn->service_id == rx->service_upgrade.from)
  152. conn->service_id = rx->service_upgrade.to;
  153. atomic_set(&conn->active, 1);
  154. /* Make the connection a target for incoming packets. */
  155. rxrpc_publish_service_conn(conn->peer, conn);
  156. }
  157. /*
  158. * Remove the service connection from the peer's tree, thereby removing it as a
  159. * target for incoming packets.
  160. */
  161. void rxrpc_unpublish_service_conn(struct rxrpc_connection *conn)
  162. {
  163. struct rxrpc_peer *peer = conn->peer;
  164. write_seqlock(&peer->service_conn_lock);
  165. if (test_and_clear_bit(RXRPC_CONN_IN_SERVICE_CONNS, &conn->flags))
  166. rb_erase(&conn->service_node, &peer->service_conns);
  167. write_sequnlock(&peer->service_conn_lock);
  168. }