]> git.proxmox.com Git - pve-kernel.git/blob - patches/kernel/0009-tun-free-skb-in-early-errors.patch
add objtool build fix
[pve-kernel.git] / patches / kernel / 0009-tun-free-skb-in-early-errors.patch
1 From 442f5963a52060fcf86a73377c31a863738632dd Mon Sep 17 00:00:00 2001
2 From: Wei Xu <wexu@redhat.com>
3 Date: Fri, 1 Dec 2017 05:10:37 -0500
4 Subject: [PATCH 009/233] tun: free skb in early errors
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 tun_recvmsg() supports accepting skb by msg_control after
10 commit ac77cfd4258f ("tun: support receiving skb through msg_control"),
11 the skb if presented should be freed no matter how far it can go
12 along, otherwise it would be leaked.
13
14 This patch fixes several missed cases.
15
16 Signed-off-by: Wei Xu <wexu@redhat.com>
17 Reported-by: Matthew Rosato <mjrosato@linux.vnet.ibm.com>
18 Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
19 ---
20 drivers/net/tun.c | 24 ++++++++++++++++++------
21 1 file changed, 18 insertions(+), 6 deletions(-)
22
23 diff --git a/drivers/net/tun.c b/drivers/net/tun.c
24 index cb1f7747adad..5143e948d7d1 100644
25 --- a/drivers/net/tun.c
26 +++ b/drivers/net/tun.c
27 @@ -1519,8 +1519,11 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,
28
29 tun_debug(KERN_INFO, tun, "tun_do_read\n");
30
31 - if (!iov_iter_count(to))
32 + if (!iov_iter_count(to)) {
33 + if (skb)
34 + kfree_skb(skb);
35 return 0;
36 + }
37
38 if (!skb) {
39 /* Read frames from ring */
40 @@ -1636,22 +1639,24 @@ static int tun_recvmsg(struct socket *sock, struct msghdr *m, size_t total_len,
41 {
42 struct tun_file *tfile = container_of(sock, struct tun_file, socket);
43 struct tun_struct *tun = __tun_get(tfile);
44 + struct sk_buff *skb = m->msg_control;
45 int ret;
46
47 - if (!tun)
48 - return -EBADFD;
49 + if (!tun) {
50 + ret = -EBADFD;
51 + goto out_free_skb;
52 + }
53
54 if (flags & ~(MSG_DONTWAIT|MSG_TRUNC|MSG_ERRQUEUE)) {
55 ret = -EINVAL;
56 - goto out;
57 + goto out_put_tun;
58 }
59 if (flags & MSG_ERRQUEUE) {
60 ret = sock_recv_errqueue(sock->sk, m, total_len,
61 SOL_PACKET, TUN_TX_TIMESTAMP);
62 goto out;
63 }
64 - ret = tun_do_read(tun, tfile, &m->msg_iter, flags & MSG_DONTWAIT,
65 - m->msg_control);
66 + ret = tun_do_read(tun, tfile, &m->msg_iter, flags & MSG_DONTWAIT, skb);
67 if (ret > (ssize_t)total_len) {
68 m->msg_flags |= MSG_TRUNC;
69 ret = flags & MSG_TRUNC ? ret : total_len;
70 @@ -1659,6 +1664,13 @@ static int tun_recvmsg(struct socket *sock, struct msghdr *m, size_t total_len,
71 out:
72 tun_put(tun);
73 return ret;
74 +
75 +out_put_tun:
76 + tun_put(tun);
77 +out_free_skb:
78 + if (skb)
79 + kfree_skb(skb);
80 + return ret;
81 }
82
83 static int tun_peek_len(struct socket *sock)
84 --
85 2.14.2
86