cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

conn_object.c (12887B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/* RxRPC virtual connection handler, common bits.
      3 *
      4 * Copyright (C) 2007, 2016 Red Hat, Inc. All Rights Reserved.
      5 * Written by David Howells (dhowells@redhat.com)
      6 */
      7
      8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      9
     10#include <linux/module.h>
     11#include <linux/slab.h>
     12#include <linux/net.h>
     13#include <linux/skbuff.h>
     14#include "ar-internal.h"
     15
     16/*
     17 * Time till a connection expires after last use (in seconds).
     18 */
     19unsigned int __read_mostly rxrpc_connection_expiry = 10 * 60;
     20unsigned int __read_mostly rxrpc_closed_conn_expiry = 10;
     21
     22static void rxrpc_destroy_connection(struct rcu_head *);
     23
     24static void rxrpc_connection_timer(struct timer_list *timer)
     25{
     26	struct rxrpc_connection *conn =
     27		container_of(timer, struct rxrpc_connection, timer);
     28
     29	rxrpc_queue_conn(conn);
     30}
     31
     32/*
     33 * allocate a new connection
     34 */
     35struct rxrpc_connection *rxrpc_alloc_connection(gfp_t gfp)
     36{
     37	struct rxrpc_connection *conn;
     38
     39	_enter("");
     40
     41	conn = kzalloc(sizeof(struct rxrpc_connection), gfp);
     42	if (conn) {
     43		INIT_LIST_HEAD(&conn->cache_link);
     44		timer_setup(&conn->timer, &rxrpc_connection_timer, 0);
     45		INIT_WORK(&conn->processor, &rxrpc_process_connection);
     46		INIT_LIST_HEAD(&conn->proc_link);
     47		INIT_LIST_HEAD(&conn->link);
     48		skb_queue_head_init(&conn->rx_queue);
     49		conn->security = &rxrpc_no_security;
     50		spin_lock_init(&conn->state_lock);
     51		conn->debug_id = atomic_inc_return(&rxrpc_debug_id);
     52		conn->idle_timestamp = jiffies;
     53	}
     54
     55	_leave(" = %p{%d}", conn, conn ? conn->debug_id : 0);
     56	return conn;
     57}
     58
     59/*
     60 * Look up a connection in the cache by protocol parameters.
     61 *
     62 * If successful, a pointer to the connection is returned, but no ref is taken.
     63 * NULL is returned if there is no match.
     64 *
     65 * When searching for a service call, if we find a peer but no connection, we
     66 * return that through *_peer in case we need to create a new service call.
     67 *
     68 * The caller must be holding the RCU read lock.
     69 */
     70struct rxrpc_connection *rxrpc_find_connection_rcu(struct rxrpc_local *local,
     71						   struct sk_buff *skb,
     72						   struct rxrpc_peer **_peer)
     73{
     74	struct rxrpc_connection *conn;
     75	struct rxrpc_conn_proto k;
     76	struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
     77	struct sockaddr_rxrpc srx;
     78	struct rxrpc_peer *peer;
     79
     80	_enter(",%x", sp->hdr.cid & RXRPC_CIDMASK);
     81
     82	if (rxrpc_extract_addr_from_skb(&srx, skb) < 0)
     83		goto not_found;
     84
     85	if (srx.transport.family != local->srx.transport.family &&
     86	    (srx.transport.family == AF_INET &&
     87	     local->srx.transport.family != AF_INET6)) {
     88		pr_warn_ratelimited("AF_RXRPC: Protocol mismatch %u not %u\n",
     89				    srx.transport.family,
     90				    local->srx.transport.family);
     91		goto not_found;
     92	}
     93
     94	k.epoch	= sp->hdr.epoch;
     95	k.cid	= sp->hdr.cid & RXRPC_CIDMASK;
     96
     97	if (rxrpc_to_server(sp)) {
     98		/* We need to look up service connections by the full protocol
     99		 * parameter set.  We look up the peer first as an intermediate
    100		 * step and then the connection from the peer's tree.
    101		 */
    102		peer = rxrpc_lookup_peer_rcu(local, &srx);
    103		if (!peer)
    104			goto not_found;
    105		*_peer = peer;
    106		conn = rxrpc_find_service_conn_rcu(peer, skb);
    107		if (!conn || refcount_read(&conn->ref) == 0)
    108			goto not_found;
    109		_leave(" = %p", conn);
    110		return conn;
    111	} else {
    112		/* Look up client connections by connection ID alone as their
    113		 * IDs are unique for this machine.
    114		 */
    115		conn = idr_find(&rxrpc_client_conn_ids,
    116				sp->hdr.cid >> RXRPC_CIDSHIFT);
    117		if (!conn || refcount_read(&conn->ref) == 0) {
    118			_debug("no conn");
    119			goto not_found;
    120		}
    121
    122		if (conn->proto.epoch != k.epoch ||
    123		    conn->params.local != local)
    124			goto not_found;
    125
    126		peer = conn->params.peer;
    127		switch (srx.transport.family) {
    128		case AF_INET:
    129			if (peer->srx.transport.sin.sin_port !=
    130			    srx.transport.sin.sin_port ||
    131			    peer->srx.transport.sin.sin_addr.s_addr !=
    132			    srx.transport.sin.sin_addr.s_addr)
    133				goto not_found;
    134			break;
    135#ifdef CONFIG_AF_RXRPC_IPV6
    136		case AF_INET6:
    137			if (peer->srx.transport.sin6.sin6_port !=
    138			    srx.transport.sin6.sin6_port ||
    139			    memcmp(&peer->srx.transport.sin6.sin6_addr,
    140				   &srx.transport.sin6.sin6_addr,
    141				   sizeof(struct in6_addr)) != 0)
    142				goto not_found;
    143			break;
    144#endif
    145		default:
    146			BUG();
    147		}
    148
    149		_leave(" = %p", conn);
    150		return conn;
    151	}
    152
    153not_found:
    154	_leave(" = NULL");
    155	return NULL;
    156}
    157
    158/*
    159 * Disconnect a call and clear any channel it occupies when that call
    160 * terminates.  The caller must hold the channel_lock and must release the
    161 * call's ref on the connection.
    162 */
    163void __rxrpc_disconnect_call(struct rxrpc_connection *conn,
    164			     struct rxrpc_call *call)
    165{
    166	struct rxrpc_channel *chan =
    167		&conn->channels[call->cid & RXRPC_CHANNELMASK];
    168
    169	_enter("%d,%x", conn->debug_id, call->cid);
    170
    171	if (rcu_access_pointer(chan->call) == call) {
    172		/* Save the result of the call so that we can repeat it if necessary
    173		 * through the channel, whilst disposing of the actual call record.
    174		 */
    175		trace_rxrpc_disconnect_call(call);
    176		switch (call->completion) {
    177		case RXRPC_CALL_SUCCEEDED:
    178			chan->last_seq = call->rx_hard_ack;
    179			chan->last_type = RXRPC_PACKET_TYPE_ACK;
    180			break;
    181		case RXRPC_CALL_LOCALLY_ABORTED:
    182			chan->last_abort = call->abort_code;
    183			chan->last_type = RXRPC_PACKET_TYPE_ABORT;
    184			break;
    185		default:
    186			chan->last_abort = RX_CALL_DEAD;
    187			chan->last_type = RXRPC_PACKET_TYPE_ABORT;
    188			break;
    189		}
    190
    191		/* Sync with rxrpc_conn_retransmit(). */
    192		smp_wmb();
    193		chan->last_call = chan->call_id;
    194		chan->call_id = chan->call_counter;
    195
    196		rcu_assign_pointer(chan->call, NULL);
    197	}
    198
    199	_leave("");
    200}
    201
    202/*
    203 * Disconnect a call and clear any channel it occupies when that call
    204 * terminates.
    205 */
    206void rxrpc_disconnect_call(struct rxrpc_call *call)
    207{
    208	struct rxrpc_connection *conn = call->conn;
    209
    210	call->peer->cong_cwnd = call->cong_cwnd;
    211
    212	if (!hlist_unhashed(&call->error_link)) {
    213		spin_lock_bh(&call->peer->lock);
    214		hlist_del_rcu(&call->error_link);
    215		spin_unlock_bh(&call->peer->lock);
    216	}
    217
    218	if (rxrpc_is_client_call(call))
    219		return rxrpc_disconnect_client_call(conn->bundle, call);
    220
    221	spin_lock(&conn->bundle->channel_lock);
    222	__rxrpc_disconnect_call(conn, call);
    223	spin_unlock(&conn->bundle->channel_lock);
    224
    225	set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
    226	conn->idle_timestamp = jiffies;
    227}
    228
    229/*
    230 * Kill off a connection.
    231 */
    232void rxrpc_kill_connection(struct rxrpc_connection *conn)
    233{
    234	struct rxrpc_net *rxnet = conn->params.local->rxnet;
    235
    236	ASSERT(!rcu_access_pointer(conn->channels[0].call) &&
    237	       !rcu_access_pointer(conn->channels[1].call) &&
    238	       !rcu_access_pointer(conn->channels[2].call) &&
    239	       !rcu_access_pointer(conn->channels[3].call));
    240	ASSERT(list_empty(&conn->cache_link));
    241
    242	write_lock(&rxnet->conn_lock);
    243	list_del_init(&conn->proc_link);
    244	write_unlock(&rxnet->conn_lock);
    245
    246	/* Drain the Rx queue.  Note that even though we've unpublished, an
    247	 * incoming packet could still be being added to our Rx queue, so we
    248	 * will need to drain it again in the RCU cleanup handler.
    249	 */
    250	rxrpc_purge_queue(&conn->rx_queue);
    251
    252	/* Leave final destruction to RCU.  The connection processor work item
    253	 * must carry a ref on the connection to prevent us getting here whilst
    254	 * it is queued or running.
    255	 */
    256	call_rcu(&conn->rcu, rxrpc_destroy_connection);
    257}
    258
    259/*
    260 * Queue a connection's work processor, getting a ref to pass to the work
    261 * queue.
    262 */
    263bool rxrpc_queue_conn(struct rxrpc_connection *conn)
    264{
    265	const void *here = __builtin_return_address(0);
    266	int r;
    267
    268	if (!__refcount_inc_not_zero(&conn->ref, &r))
    269		return false;
    270	if (rxrpc_queue_work(&conn->processor))
    271		trace_rxrpc_conn(conn->debug_id, rxrpc_conn_queued, r + 1, here);
    272	else
    273		rxrpc_put_connection(conn);
    274	return true;
    275}
    276
    277/*
    278 * Note the re-emergence of a connection.
    279 */
    280void rxrpc_see_connection(struct rxrpc_connection *conn)
    281{
    282	const void *here = __builtin_return_address(0);
    283	if (conn) {
    284		int n = refcount_read(&conn->ref);
    285
    286		trace_rxrpc_conn(conn->debug_id, rxrpc_conn_seen, n, here);
    287	}
    288}
    289
    290/*
    291 * Get a ref on a connection.
    292 */
    293struct rxrpc_connection *rxrpc_get_connection(struct rxrpc_connection *conn)
    294{
    295	const void *here = __builtin_return_address(0);
    296	int r;
    297
    298	__refcount_inc(&conn->ref, &r);
    299	trace_rxrpc_conn(conn->debug_id, rxrpc_conn_got, r, here);
    300	return conn;
    301}
    302
    303/*
    304 * Try to get a ref on a connection.
    305 */
    306struct rxrpc_connection *
    307rxrpc_get_connection_maybe(struct rxrpc_connection *conn)
    308{
    309	const void *here = __builtin_return_address(0);
    310	int r;
    311
    312	if (conn) {
    313		if (__refcount_inc_not_zero(&conn->ref, &r))
    314			trace_rxrpc_conn(conn->debug_id, rxrpc_conn_got, r + 1, here);
    315		else
    316			conn = NULL;
    317	}
    318	return conn;
    319}
    320
    321/*
    322 * Set the service connection reap timer.
    323 */
    324static void rxrpc_set_service_reap_timer(struct rxrpc_net *rxnet,
    325					 unsigned long reap_at)
    326{
    327	if (rxnet->live)
    328		timer_reduce(&rxnet->service_conn_reap_timer, reap_at);
    329}
    330
    331/*
    332 * Release a service connection
    333 */
    334void rxrpc_put_service_conn(struct rxrpc_connection *conn)
    335{
    336	const void *here = __builtin_return_address(0);
    337	unsigned int debug_id = conn->debug_id;
    338	int r;
    339
    340	__refcount_dec(&conn->ref, &r);
    341	trace_rxrpc_conn(debug_id, rxrpc_conn_put_service, r - 1, here);
    342	if (r - 1 == 1)
    343		rxrpc_set_service_reap_timer(conn->params.local->rxnet,
    344					     jiffies + rxrpc_connection_expiry);
    345}
    346
    347/*
    348 * destroy a virtual connection
    349 */
    350static void rxrpc_destroy_connection(struct rcu_head *rcu)
    351{
    352	struct rxrpc_connection *conn =
    353		container_of(rcu, struct rxrpc_connection, rcu);
    354
    355	_enter("{%d,u=%d}", conn->debug_id, refcount_read(&conn->ref));
    356
    357	ASSERTCMP(refcount_read(&conn->ref), ==, 0);
    358
    359	_net("DESTROY CONN %d", conn->debug_id);
    360
    361	del_timer_sync(&conn->timer);
    362	rxrpc_purge_queue(&conn->rx_queue);
    363
    364	conn->security->clear(conn);
    365	key_put(conn->params.key);
    366	rxrpc_put_bundle(conn->bundle);
    367	rxrpc_put_peer(conn->params.peer);
    368
    369	if (atomic_dec_and_test(&conn->params.local->rxnet->nr_conns))
    370		wake_up_var(&conn->params.local->rxnet->nr_conns);
    371	rxrpc_put_local(conn->params.local);
    372
    373	kfree(conn);
    374	_leave("");
    375}
    376
    377/*
    378 * reap dead service connections
    379 */
    380void rxrpc_service_connection_reaper(struct work_struct *work)
    381{
    382	struct rxrpc_connection *conn, *_p;
    383	struct rxrpc_net *rxnet =
    384		container_of(work, struct rxrpc_net, service_conn_reaper);
    385	unsigned long expire_at, earliest, idle_timestamp, now;
    386
    387	LIST_HEAD(graveyard);
    388
    389	_enter("");
    390
    391	now = jiffies;
    392	earliest = now + MAX_JIFFY_OFFSET;
    393
    394	write_lock(&rxnet->conn_lock);
    395	list_for_each_entry_safe(conn, _p, &rxnet->service_conns, link) {
    396		ASSERTCMP(refcount_read(&conn->ref), >, 0);
    397		if (likely(refcount_read(&conn->ref) > 1))
    398			continue;
    399		if (conn->state == RXRPC_CONN_SERVICE_PREALLOC)
    400			continue;
    401
    402		if (rxnet->live && !conn->params.local->dead) {
    403			idle_timestamp = READ_ONCE(conn->idle_timestamp);
    404			expire_at = idle_timestamp + rxrpc_connection_expiry * HZ;
    405			if (conn->params.local->service_closed)
    406				expire_at = idle_timestamp + rxrpc_closed_conn_expiry * HZ;
    407
    408			_debug("reap CONN %d { u=%d,t=%ld }",
    409			       conn->debug_id, refcount_read(&conn->ref),
    410			       (long)expire_at - (long)now);
    411
    412			if (time_before(now, expire_at)) {
    413				if (time_before(expire_at, earliest))
    414					earliest = expire_at;
    415				continue;
    416			}
    417		}
    418
    419		/* The usage count sits at 1 whilst the object is unused on the
    420		 * list; we reduce that to 0 to make the object unavailable.
    421		 */
    422		if (!refcount_dec_if_one(&conn->ref))
    423			continue;
    424		trace_rxrpc_conn(conn->debug_id, rxrpc_conn_reap_service, 0, NULL);
    425
    426		if (rxrpc_conn_is_client(conn))
    427			BUG();
    428		else
    429			rxrpc_unpublish_service_conn(conn);
    430
    431		list_move_tail(&conn->link, &graveyard);
    432	}
    433	write_unlock(&rxnet->conn_lock);
    434
    435	if (earliest != now + MAX_JIFFY_OFFSET) {
    436		_debug("reschedule reaper %ld", (long)earliest - (long)now);
    437		ASSERT(time_after(earliest, now));
    438		rxrpc_set_service_reap_timer(rxnet, earliest);
    439	}
    440
    441	while (!list_empty(&graveyard)) {
    442		conn = list_entry(graveyard.next, struct rxrpc_connection,
    443				  link);
    444		list_del_init(&conn->link);
    445
    446		ASSERTCMP(refcount_read(&conn->ref), ==, 0);
    447		rxrpc_kill_connection(conn);
    448	}
    449
    450	_leave("");
    451}
    452
    453/*
    454 * preemptively destroy all the service connection records rather than
    455 * waiting for them to time out
    456 */
    457void rxrpc_destroy_all_connections(struct rxrpc_net *rxnet)
    458{
    459	struct rxrpc_connection *conn, *_p;
    460	bool leak = false;
    461
    462	_enter("");
    463
    464	atomic_dec(&rxnet->nr_conns);
    465	rxrpc_destroy_all_client_connections(rxnet);
    466
    467	del_timer_sync(&rxnet->service_conn_reap_timer);
    468	rxrpc_queue_work(&rxnet->service_conn_reaper);
    469	flush_workqueue(rxrpc_workqueue);
    470
    471	write_lock(&rxnet->conn_lock);
    472	list_for_each_entry_safe(conn, _p, &rxnet->service_conns, link) {
    473		pr_err("AF_RXRPC: Leaked conn %p {%d}\n",
    474		       conn, refcount_read(&conn->ref));
    475		leak = true;
    476	}
    477	write_unlock(&rxnet->conn_lock);
    478	BUG_ON(leak);
    479
    480	ASSERT(list_empty(&rxnet->conn_proc_list));
    481
    482	/* We need to wait for the connections to be destroyed by RCU as they
    483	 * pin things that we still need to get rid of.
    484	 */
    485	wait_var_event(&rxnet->nr_conns, !atomic_read(&rxnet->nr_conns));
    486	_leave("");
    487}