diff options
| author | David S. Miller <davem@davemloft.net> | 2014-01-28 21:04:18 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2014-01-28 21:04:18 -0500 |
| 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, | |||
| 381 | 381 | ||
| 382 | rxrpc_assign_connection_id(conn); | 382 | rxrpc_assign_connection_id(conn); |
| 383 | rx->conn = conn; | 383 | rx->conn = conn; |
| 384 | } else { | ||
| 385 | spin_lock(&trans->client_lock); | ||
| 384 | } | 386 | } |
| 385 | 387 | ||
| 386 | /* we've got a connection with a free channel and we can now attach the | 388 | /* 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, | |||
| 180 | if (copy > len - copied) | 180 | if (copy > len - copied) |
| 181 | copy = len - copied; | 181 | copy = len - copied; |
| 182 | 182 | ||
| 183 | if (skb->ip_summed == CHECKSUM_UNNECESSARY) { | 183 | if (skb->ip_summed == CHECKSUM_UNNECESSARY || |
| 184 | skb->ip_summed == CHECKSUM_PARTIAL) { | ||
| 184 | ret = skb_copy_datagram_iovec(skb, offset, | 185 | ret = skb_copy_datagram_iovec(skb, offset, |
| 185 | msg->msg_iov, copy); | 186 | msg->msg_iov, copy); |
| 186 | } else { | 187 | } else { |
| @@ -353,6 +354,10 @@ csum_copy_error: | |||
| 353 | if (continue_call) | 354 | if (continue_call) |
| 354 | rxrpc_put_call(continue_call); | 355 | rxrpc_put_call(continue_call); |
| 355 | rxrpc_kill_skb(skb); | 356 | rxrpc_kill_skb(skb); |
| 357 | if (!(flags & MSG_PEEK)) { | ||
| 358 | if (skb_dequeue(&rx->sk.sk_receive_queue) != skb) | ||
| 359 | BUG(); | ||
| 360 | } | ||
| 356 | skb_kill_datagram(&rx->sk, skb, flags); | 361 | skb_kill_datagram(&rx->sk, skb, flags); |
| 357 | rxrpc_put_call(call); | 362 | rxrpc_put_call(call); |
| 358 | return -EAGAIN; | 363 | return -EAGAIN; |
