]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.19.46/net-test-nouarg-before-dereferencing-zerocopy-pointers.patch
Linux 4.19.46
[thirdparty/kernel/stable-queue.git] / releases / 4.19.46 / net-test-nouarg-before-dereferencing-zerocopy-pointers.patch
CommitLineData
91562c7b
GKH
1From foo@baz Wed 22 May 2019 08:37:51 AM CEST
2From: Willem de Bruijn <willemb@google.com>
3Date: Wed, 15 May 2019 13:29:16 -0400
4Subject: net: test nouarg before dereferencing zerocopy pointers
5
6From: Willem de Bruijn <willemb@google.com>
7
8[ Upstream commit 185ce5c38ea76f29b6bd9c7c8c7a5e5408834920 ]
9
10Zerocopy skbs without completion notification were added for packet
11sockets with PACKET_TX_RING user buffers. Those signal completion
12through the TP_STATUS_USER bit in the ring. Zerocopy annotation was
13added only to avoid premature notification after clone or orphan, by
14triggering a copy on these paths for these packets.
15
16The mechanism had to define a special "no-uarg" mode because packet
17sockets already use skb_uarg(skb) == skb_shinfo(skb)->destructor_arg
18for a different pointer.
19
20Before deferencing skb_uarg(skb), verify that it is a real pointer.
21
22Fixes: 5cd8d46ea1562 ("packet: copy user buffers before orphan or clone")
23Signed-off-by: Willem de Bruijn <willemb@google.com>
24Signed-off-by: David S. Miller <davem@davemloft.net>
25Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
26---
27 include/linux/skbuff.h | 9 ++++++---
28 1 file changed, 6 insertions(+), 3 deletions(-)
29
30--- a/include/linux/skbuff.h
31+++ b/include/linux/skbuff.h
32@@ -1333,10 +1333,12 @@ static inline void skb_zcopy_clear(struc
33 struct ubuf_info *uarg = skb_zcopy(skb);
34
35 if (uarg) {
36- if (uarg->callback == sock_zerocopy_callback) {
37+ if (skb_zcopy_is_nouarg(skb)) {
38+ /* no notification callback */
39+ } else if (uarg->callback == sock_zerocopy_callback) {
40 uarg->zerocopy = uarg->zerocopy && zerocopy;
41 sock_zerocopy_put(uarg);
42- } else if (!skb_zcopy_is_nouarg(skb)) {
43+ } else {
44 uarg->callback(uarg, zerocopy);
45 }
46
47@@ -2587,7 +2589,8 @@ static inline int skb_orphan_frags(struc
48 {
49 if (likely(!skb_zcopy(skb)))
50 return 0;
51- if (skb_uarg(skb)->callback == sock_zerocopy_callback)
52+ if (!skb_zcopy_is_nouarg(skb) &&
53+ skb_uarg(skb)->callback == sock_zerocopy_callback)
54 return 0;
55 return skb_copy_ubufs(skb, gfp_mask);
56 }