]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/5.0.10/net-strparser-partially-revert-strparser-call-skb_unclone-conditionally.patch
Fixes for 4.19
[thirdparty/kernel/stable-queue.git] / releases / 5.0.10 / net-strparser-partially-revert-strparser-call-skb_unclone-conditionally.patch
CommitLineData
0ee3da53
GKH
1From foo@baz Sat Apr 20 16:43:09 CEST 2019
2From: Jakub Kicinski <jakub.kicinski@netronome.com>
3Date: Wed, 10 Apr 2019 11:04:32 -0700
4Subject: net: strparser: partially revert "strparser: Call skb_unclone conditionally"
5
6From: Jakub Kicinski <jakub.kicinski@netronome.com>
7
8[ Upstream commit 4a9c2e3746e6151fd5d077259d79ce9ca86d47d7 ]
9
10This reverts the first part of commit 4e485d06bb8c ("strparser: Call
11skb_unclone conditionally"). To build a message with multiple
12fragments we need our own root of frag_list. We can't simply
13use the frag_list of orig_skb, because it will lead to linking
14all orig_skbs together creating very long frag chains, and causing
15stack overflow on kfree_skb() (which is called recursively on
16the frag_lists).
17
18BUG: stack guard page was hit at 00000000d40fad41 (stack is 0000000029dde9f4..000000008cce03d5)
19kernel stack overflow (double-fault): 0000 [#1] PREEMPT SMP
20RIP: 0010:free_one_page+0x2b/0x490
21
22Call Trace:
23 __free_pages_ok+0x143/0x2c0
24 skb_release_data+0x8e/0x140
25 ? skb_release_data+0xad/0x140
26 kfree_skb+0x32/0xb0
27
28 [...]
29
30 skb_release_data+0xad/0x140
31 ? skb_release_data+0xad/0x140
32 kfree_skb+0x32/0xb0
33 skb_release_data+0xad/0x140
34 ? skb_release_data+0xad/0x140
35 kfree_skb+0x32/0xb0
36 skb_release_data+0xad/0x140
37 ? skb_release_data+0xad/0x140
38 kfree_skb+0x32/0xb0
39 skb_release_data+0xad/0x140
40 ? skb_release_data+0xad/0x140
41 kfree_skb+0x32/0xb0
42 skb_release_data+0xad/0x140
43 __kfree_skb+0xe/0x20
44 tcp_disconnect+0xd6/0x4d0
45 tcp_close+0xf4/0x430
46 ? tcp_check_oom+0xf0/0xf0
47 tls_sk_proto_close+0xe4/0x1e0 [tls]
48 inet_release+0x36/0x60
49 __sock_release+0x37/0xa0
50 sock_close+0x11/0x20
51 __fput+0xa2/0x1d0
52 task_work_run+0x89/0xb0
53 exit_to_usermode_loop+0x9a/0xa0
54 do_syscall_64+0xc0/0xf0
55 entry_SYSCALL_64_after_hwframe+0x44/0xa9
56
57Let's leave the second unclone conditional, as I'm not entirely
58sure what is its purpose :)
59
60Fixes: 4e485d06bb8c ("strparser: Call skb_unclone conditionally")
61Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
62Reviewed-by: Dirk van der Merwe <dirk.vandermerwe@netronome.com>
63Reviewed-by: Eric Dumazet <edumazet@google.com>
64Signed-off-by: David S. Miller <davem@davemloft.net>
65Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
66---
67 net/strparser/strparser.c | 12 +++++-------
68 1 file changed, 5 insertions(+), 7 deletions(-)
69
70--- a/net/strparser/strparser.c
71+++ b/net/strparser/strparser.c
72@@ -140,13 +140,11 @@ static int __strp_recv(read_descriptor_t
73 /* We are going to append to the frags_list of head.
74 * Need to unshare the frag_list.
75 */
76- if (skb_has_frag_list(head)) {
77- err = skb_unclone(head, GFP_ATOMIC);
78- if (err) {
79- STRP_STATS_INCR(strp->stats.mem_fail);
80- desc->error = err;
81- return 0;
82- }
83+ err = skb_unclone(head, GFP_ATOMIC);
84+ if (err) {
85+ STRP_STATS_INCR(strp->stats.mem_fail);
86+ desc->error = err;
87+ return 0;
88 }
89
90 if (unlikely(skb_shinfo(head)->frag_list)) {