diff options
author | David S. Miller <davem@davemloft.net> | 2014-01-28 18:04:18 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-28 18:04:18 -0800 |
commit | cd0c75a78d737935c5ca8e7e2bfe7415d851bbce (patch) | |
tree | 3689494de76a71ef9f2e2f17381948fb981fb53a | |
parent | 0f1a24c9a9f4682dd61f5c39b9952f915c5e952c (diff) | |
parent | 1ea427359dde1573815e19c411ce08fdf0c42cfe (diff) |
Merge tag 'rxrpc-20140126' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs
David Howells says:
====================
RxRPC fixes
Here are some small AF_RXRPC fixes.
(1) Fix a place where a spinlock is taken conditionally but is released
unconditionally.
(2) Fix a double-free that happens when cleaning up on a checksum error.
(3) Fix handling of CHECKSUM_PARTIAL whilst delivering messages to userspace.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/rxrpc/ar-connection.c | 2 | ||||
-rw-r--r-- | net/rxrpc/ar-recvmsg.c | 7 |
2 files changed, 8 insertions, 1 deletions
diff --git a/net/rxrpc/ar-connection.c b/net/rxrpc/ar-connection.c index 4106ca95ec86..7bf5b5b9e8b9 100644 --- a/net/rxrpc/ar-connection.c +++ b/net/rxrpc/ar-connection.c @@ -381,6 +381,8 @@ static int rxrpc_connect_exclusive(struct rxrpc_sock *rx, rxrpc_assign_connection_id(conn); rx->conn = conn; + } else { + spin_lock(&trans->client_lock); } /* we've got a connection with a free channel and we can now attach the diff --git a/net/rxrpc/ar-recvmsg.c b/net/rxrpc/ar-recvmsg.c index 898492a8d61b..34b5490dde65 100644 --- a/net/rxrpc/ar-recvmsg.c +++ b/net/rxrpc/ar-recvmsg.c @@ -180,7 +180,8 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, if (copy > len - copied) copy = len - copied; - if (skb->ip_summed == CHECKSUM_UNNECESSARY) { + if (skb->ip_summed == CHECKSUM_UNNECESSARY || + skb->ip_summed == CHECKSUM_PARTIAL) { ret = skb_copy_datagram_iovec(skb, offset, msg->msg_iov, copy); } else { @@ -353,6 +354,10 @@ csum_copy_error: if (continue_call) rxrpc_put_call(continue_call); rxrpc_kill_skb(skb); + if (!(flags & MSG_PEEK)) { + if (skb_dequeue(&rx->sk.sk_receive_queue) != skb) + BUG(); + } skb_kill_datagram(&rx->sk, skb, flags); rxrpc_put_call(call); return -EAGAIN; |