diff options
author | David Howells <dhowells@redhat.com> | 2017-11-02 16:06:55 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2017-11-02 16:20:43 +0100 |
commit | 1457cc4cfb93511de347d1d0a1c9da3e826b66fe (patch) | |
tree | b038ecca9f4b4cb63ab5c94fa0bc951ac843a638 /net | |
parent | rxrpc: Lock around calling a kernel service Rx notification (diff) | |
download | linux-1457cc4cfb93511de347d1d0a1c9da3e826b66fe.tar.xz linux-1457cc4cfb93511de347d1d0a1c9da3e826b66fe.zip |
rxrpc: Fix a null ptr deref in rxrpc_fill_out_ack()
rxrpc_fill_out_ack() needs to be passed the connection pointer from its
caller rather than using call->conn as the call may be disconnected in
parallel with it, clearing call->conn, leading to:
BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
IP: rxrpc_send_ack_packet+0x231/0x6a4
Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/rxrpc/output.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/net/rxrpc/output.c b/net/rxrpc/output.c index 71e6f713fbe7..8ee8b2d4a3eb 100644 --- a/net/rxrpc/output.c +++ b/net/rxrpc/output.c @@ -35,7 +35,8 @@ struct rxrpc_abort_buffer { /* * Fill out an ACK packet. */ -static size_t rxrpc_fill_out_ack(struct rxrpc_call *call, +static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn, + struct rxrpc_call *call, struct rxrpc_ack_buffer *pkt, rxrpc_seq_t *_hard_ack, rxrpc_seq_t *_top, @@ -77,8 +78,8 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_call *call, } while (before_eq(seq, top)); } - mtu = call->conn->params.peer->if_mtu; - mtu -= call->conn->params.peer->hdrsize; + mtu = conn->params.peer->if_mtu; + mtu -= conn->params.peer->hdrsize; jmax = (call->nr_jumbo_bad > 3) ? 1 : rxrpc_rx_jumbo_max; pkt->ackinfo.rxMTU = htonl(rxrpc_rx_mtu); pkt->ackinfo.maxMTU = htonl(mtu); @@ -148,7 +149,7 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping) } call->ackr_reason = 0; } - n = rxrpc_fill_out_ack(call, pkt, &hard_ack, &top, reason); + n = rxrpc_fill_out_ack(conn, call, pkt, &hard_ack, &top, reason); spin_unlock_bh(&call->lock); |