Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b30889c authored by Trond Myklebust's avatar Trond Myklebust
Browse files

SUNRPC: Ensure we always close the socket after a connection shuts down



Ensure that we release the TCP socket once it is in the TCP_CLOSE or
TCP_TIME_WAIT state (and only then) so that we don't confuse rkhunter
and its ilk.

Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent e231c687
Loading
Loading
Loading
Loading
+10 −13
Original line number Diff line number Diff line
@@ -807,13 +807,6 @@ static void xs_sock_reset_connection_flags(struct rpc_xprt *xprt)
	smp_mb__after_atomic();
}

static void xs_sock_mark_closed(struct rpc_xprt *xprt)
{
	xs_sock_reset_connection_flags(xprt);
	/* Mark transport as closed and wake up all pending tasks */
	xprt_disconnect_done(xprt);
}

/**
 * xs_error_report - callback to handle TCP socket state errors
 * @sk: socket
@@ -833,9 +826,6 @@ static void xs_error_report(struct sock *sk)
	err = -sk->sk_err;
	if (err == 0)
		goto out;
	/* Is this a reset event? */
	if (sk->sk_state == TCP_CLOSE)
		xs_sock_mark_closed(xprt);
	dprintk("RPC:       xs_error_report client %p, error=%d...\n",
			xprt, -err);
	trace_rpc_socket_error(xprt, sk->sk_socket, err);
@@ -1655,9 +1645,11 @@ static void xs_tcp_state_change(struct sock *sk)
		if (test_and_clear_bit(XPRT_SOCK_CONNECTING,
					&transport->sock_state))
			xprt_clear_connecting(xprt);
		clear_bit(XPRT_CLOSING, &xprt->state);
		if (sk->sk_err)
			xprt_wake_pending_tasks(xprt, -sk->sk_err);
		xs_sock_mark_closed(xprt);
		/* Trigger the socket release */
		xs_tcp_force_close(xprt);
	}
 out:
	read_unlock_bh(&sk->sk_callback_lock);
@@ -2265,15 +2257,20 @@ static void xs_tcp_shutdown(struct rpc_xprt *xprt)
{
	struct sock_xprt *transport = container_of(xprt, struct sock_xprt, xprt);
	struct socket *sock = transport->sock;
	int skst = transport->inet ? transport->inet->sk_state : TCP_CLOSE;

	if (sock == NULL)
		return;
	if (xprt_connected(xprt)) {
	switch (skst) {
	default:
		kernel_sock_shutdown(sock, SHUT_RDWR);
		trace_rpc_socket_shutdown(xprt, sock);
	} else
		break;
	case TCP_CLOSE:
	case TCP_TIME_WAIT:
		xs_reset_transport(transport);
	}
}

static void xs_tcp_set_socket_timeouts(struct rpc_xprt *xprt,
		struct socket *sock)