diff options
Diffstat (limited to 'drivers/net/tap.c')
-rw-r--r-- | drivers/net/tap.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/net/tap.c b/drivers/net/tap.c index e9489b88407c..0a886fda0129 100644 --- a/drivers/net/tap.c +++ b/drivers/net/tap.c | |||
@@ -829,8 +829,11 @@ static ssize_t tap_do_read(struct tap_queue *q, | |||
829 | DEFINE_WAIT(wait); | 829 | DEFINE_WAIT(wait); |
830 | ssize_t ret = 0; | 830 | ssize_t ret = 0; |
831 | 831 | ||
832 | if (!iov_iter_count(to)) | 832 | if (!iov_iter_count(to)) { |
833 | if (skb) | ||
834 | kfree_skb(skb); | ||
833 | return 0; | 835 | return 0; |
836 | } | ||
834 | 837 | ||
835 | if (skb) | 838 | if (skb) |
836 | goto put; | 839 | goto put; |
@@ -1154,11 +1157,14 @@ static int tap_recvmsg(struct socket *sock, struct msghdr *m, | |||
1154 | size_t total_len, int flags) | 1157 | size_t total_len, int flags) |
1155 | { | 1158 | { |
1156 | struct tap_queue *q = container_of(sock, struct tap_queue, sock); | 1159 | struct tap_queue *q = container_of(sock, struct tap_queue, sock); |
1160 | struct sk_buff *skb = m->msg_control; | ||
1157 | int ret; | 1161 | int ret; |
1158 | if (flags & ~(MSG_DONTWAIT|MSG_TRUNC)) | 1162 | if (flags & ~(MSG_DONTWAIT|MSG_TRUNC)) { |
1163 | if (skb) | ||
1164 | kfree_skb(skb); | ||
1159 | return -EINVAL; | 1165 | return -EINVAL; |
1160 | ret = tap_do_read(q, &m->msg_iter, flags & MSG_DONTWAIT, | 1166 | } |
1161 | m->msg_control); | 1167 | ret = tap_do_read(q, &m->msg_iter, flags & MSG_DONTWAIT, skb); |
1162 | if (ret > total_len) { | 1168 | if (ret > total_len) { |
1163 | m->msg_flags |= MSG_TRUNC; | 1169 | m->msg_flags |= MSG_TRUNC; |
1164 | ret = flags & MSG_TRUNC ? ret : total_len; | 1170 | ret = flags & MSG_TRUNC ? ret : total_len; |