]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Jan 2020 09:41:54 +0000 (10:41 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 14 Jan 2020 09:41:54 +0000 (10:41 +0100)
added patches:
netfilter-arp_tables-init-netns-pointer-in-xt_tgchk_param-struct.patch
netfilter-ipset-avoid-null-deref-when-ipset_attr_lineno-is-present.patch
usb-fix-don-t-skip-endpoint-descriptors-with-maxpacket-0.patch

queue-4.4/netfilter-arp_tables-init-netns-pointer-in-xt_tgchk_param-struct.patch [new file with mode: 0644]
queue-4.4/netfilter-ipset-avoid-null-deref-when-ipset_attr_lineno-is-present.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/usb-fix-don-t-skip-endpoint-descriptors-with-maxpacket-0.patch [new file with mode: 0644]

diff --git a/queue-4.4/netfilter-arp_tables-init-netns-pointer-in-xt_tgchk_param-struct.patch b/queue-4.4/netfilter-arp_tables-init-netns-pointer-in-xt_tgchk_param-struct.patch
new file mode 100644 (file)
index 0000000..037d03b
--- /dev/null
@@ -0,0 +1,149 @@
+From 1b789577f655060d98d20ed0c6f9fbd469d6ba63 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Fri, 27 Dec 2019 01:33:10 +0100
+Subject: netfilter: arp_tables: init netns pointer in xt_tgchk_param struct
+
+From: Florian Westphal <fw@strlen.de>
+
+commit 1b789577f655060d98d20ed0c6f9fbd469d6ba63 upstream.
+
+We get crash when the targets checkentry function tries to make
+use of the network namespace pointer for arptables.
+
+When the net pointer got added back in 2010, only ip/ip6/ebtables were
+changed to initialize it, so arptables has this set to NULL.
+
+This isn't a problem for normal arptables because no existing
+arptables target has a checkentry function that makes use of par->net.
+
+However, direct users of the setsockopt interface can provide any
+target they want as long as its registered for ARP or UNPSEC protocols.
+
+syzkaller managed to send a semi-valid arptables rule for RATEEST target
+which is enough to trigger NULL deref:
+
+kasan: GPF could be caused by NULL-ptr deref or user memory access
+general protection fault: 0000 [#1] PREEMPT SMP KASAN
+RIP: xt_rateest_tg_checkentry+0x11d/0xb40 net/netfilter/xt_RATEEST.c:109
+[..]
+ xt_check_target+0x283/0x690 net/netfilter/x_tables.c:1019
+ check_target net/ipv4/netfilter/arp_tables.c:399 [inline]
+ find_check_entry net/ipv4/netfilter/arp_tables.c:422 [inline]
+ translate_table+0x1005/0x1d70 net/ipv4/netfilter/arp_tables.c:572
+ do_replace net/ipv4/netfilter/arp_tables.c:977 [inline]
+ do_arpt_set_ctl+0x310/0x640 net/ipv4/netfilter/arp_tables.c:1456
+
+Fixes: add67461240c1d ("netfilter: add struct net * to target parameters")
+Reported-by: syzbot+d7358a458d8a81aee898@syzkaller.appspotmail.com
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv4/netfilter/arp_tables.c |   27 ++++++++++++++++-----------
+ 1 file changed, 16 insertions(+), 11 deletions(-)
+
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -488,11 +488,12 @@ next:
+       return 1;
+ }
+-static inline int check_target(struct arpt_entry *e, const char *name)
++static int check_target(struct arpt_entry *e, struct net *net, const char *name)
+ {
+       struct xt_entry_target *t = arpt_get_target(e);
+       int ret;
+       struct xt_tgchk_param par = {
++              .net       = net,
+               .table     = name,
+               .entryinfo = e,
+               .target    = t->u.kernel.target,
+@@ -510,8 +511,9 @@ static inline int check_target(struct ar
+       return 0;
+ }
+-static inline int
+-find_check_entry(struct arpt_entry *e, const char *name, unsigned int size,
++static int
++find_check_entry(struct arpt_entry *e, struct net *net, const char *name,
++               unsigned int size,
+                struct xt_percpu_counter_alloc_state *alloc_state)
+ {
+       struct xt_entry_target *t;
+@@ -531,7 +533,7 @@ find_check_entry(struct arpt_entry *e, c
+       }
+       t->u.kernel.target = target;
+-      ret = check_target(e, name);
++      ret = check_target(e, net, name);
+       if (ret)
+               goto err;
+       return 0;
+@@ -632,7 +634,9 @@ static inline void cleanup_entry(struct
+ /* Checks and translates the user-supplied table segment (held in
+  * newinfo).
+  */
+-static int translate_table(struct xt_table_info *newinfo, void *entry0,
++static int translate_table(struct net *net,
++                         struct xt_table_info *newinfo,
++                         void *entry0,
+                          const struct arpt_replace *repl)
+ {
+       struct xt_percpu_counter_alloc_state alloc_state = { 0 };
+@@ -709,7 +713,7 @@ static int translate_table(struct xt_tab
+       /* Finally, each sanity check must pass */
+       i = 0;
+       xt_entry_foreach(iter, entry0, newinfo->size) {
+-              ret = find_check_entry(iter, repl->name, repl->size,
++              ret = find_check_entry(iter, net, repl->name, repl->size,
+                                      &alloc_state);
+               if (ret != 0)
+                       break;
+@@ -1114,7 +1118,7 @@ static int do_replace(struct net *net, c
+               goto free_newinfo;
+       }
+-      ret = translate_table(newinfo, loc_cpu_entry, &tmp);
++      ret = translate_table(net, newinfo, loc_cpu_entry, &tmp);
+       if (ret != 0)
+               goto free_newinfo;
+@@ -1301,7 +1305,8 @@ compat_copy_entry_from_user(struct compa
+       }
+ }
+-static int translate_compat_table(struct xt_table_info **pinfo,
++static int translate_compat_table(struct net *net,
++                                struct xt_table_info **pinfo,
+                                 void **pentry0,
+                                 const struct compat_arpt_replace *compatr)
+ {
+@@ -1371,7 +1376,7 @@ static int translate_compat_table(struct
+       repl.num_counters = 0;
+       repl.counters = NULL;
+       repl.size = newinfo->size;
+-      ret = translate_table(newinfo, entry1, &repl);
++      ret = translate_table(net, newinfo, entry1, &repl);
+       if (ret)
+               goto free_newinfo;
+@@ -1426,7 +1431,7 @@ static int compat_do_replace(struct net
+               goto free_newinfo;
+       }
+-      ret = translate_compat_table(&newinfo, &loc_cpu_entry, &tmp);
++      ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp);
+       if (ret != 0)
+               goto free_newinfo;
+@@ -1696,7 +1701,7 @@ struct xt_table *arpt_register_table(str
+       loc_cpu_entry = newinfo->entries;
+       memcpy(loc_cpu_entry, repl->entries, repl->size);
+-      ret = translate_table(newinfo, loc_cpu_entry, repl);
++      ret = translate_table(net, newinfo, loc_cpu_entry, repl);
+       duprintf("arpt_register_table: translate table gives %d\n", ret);
+       if (ret != 0)
+               goto out_free;
diff --git a/queue-4.4/netfilter-ipset-avoid-null-deref-when-ipset_attr_lineno-is-present.patch b/queue-4.4/netfilter-ipset-avoid-null-deref-when-ipset_attr_lineno-is-present.patch
new file mode 100644 (file)
index 0000000..7b9b62d
--- /dev/null
@@ -0,0 +1,59 @@
+From 22dad713b8a5ff488e07b821195270672f486eb2 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Wed, 8 Jan 2020 10:59:38 +0100
+Subject: netfilter: ipset: avoid null deref when IPSET_ATTR_LINENO is present
+
+From: Florian Westphal <fw@strlen.de>
+
+commit 22dad713b8a5ff488e07b821195270672f486eb2 upstream.
+
+The set uadt functions assume lineno is never NULL, but it is in
+case of ip_set_utest().
+
+syzkaller managed to generate a netlink message that calls this with
+LINENO attr present:
+
+general protection fault: 0000 [#1] PREEMPT SMP KASAN
+RIP: 0010:hash_mac4_uadt+0x1bc/0x470 net/netfilter/ipset/ip_set_hash_mac.c:104
+Call Trace:
+ ip_set_utest+0x55b/0x890 net/netfilter/ipset/ip_set_core.c:1867
+ nfnetlink_rcv_msg+0xcf2/0xfb0 net/netfilter/nfnetlink.c:229
+ netlink_rcv_skb+0x177/0x450 net/netlink/af_netlink.c:2477
+ nfnetlink_rcv+0x1ba/0x460 net/netfilter/nfnetlink.c:563
+
+pass a dummy lineno storage, its easier than patching all set
+implementations.
+
+This seems to be a day-0 bug.
+
+Cc: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
+Reported-by: syzbot+34bd2369d38707f3f4a7@syzkaller.appspotmail.com
+Fixes: a7b4f989a6294 ("netfilter: ipset: IP set core support")
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Acked-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/netfilter/ipset/ip_set_core.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/netfilter/ipset/ip_set_core.c
++++ b/net/netfilter/ipset/ip_set_core.c
+@@ -1619,6 +1619,7 @@ ip_set_utest(struct sock *ctnl, struct s
+       struct ip_set *set;
+       struct nlattr *tb[IPSET_ATTR_ADT_MAX + 1] = {};
+       int ret = 0;
++      u32 lineno;
+       if (unlikely(protocol_failed(attr) ||
+                    !attr[IPSET_ATTR_SETNAME] ||
+@@ -1635,7 +1636,7 @@ ip_set_utest(struct sock *ctnl, struct s
+               return -IPSET_ERR_PROTOCOL;
+       rcu_read_lock_bh();
+-      ret = set->variant->uadt(set, tb, IPSET_TEST, NULL, 0, 0);
++      ret = set->variant->uadt(set, tb, IPSET_TEST, &lineno, 0, 0);
+       rcu_read_unlock_bh();
+       /* Userspace can't trigger element to be re-added */
+       if (ret == -EAGAIN)
index d9e9acf10df7d5b794cce0c4bd5973963dd5bf44..f68b5bc5327a423d28401f7b316e44ebdd7438b7 100644 (file)
@@ -23,3 +23,6 @@ mwifiex-fix-possible-heap-overflow-in-mwifiex_process_country_ie.patch
 mwifiex-pcie-fix-memory-leak-in-mwifiex_pcie_alloc_cmdrsp_buf.patch
 scsi-bfa-release-allocated-memory-in-case-of-error.patch
 rtl8xxxu-prevent-leaking-urb.patch
+usb-fix-don-t-skip-endpoint-descriptors-with-maxpacket-0.patch
+netfilter-arp_tables-init-netns-pointer-in-xt_tgchk_param-struct.patch
+netfilter-ipset-avoid-null-deref-when-ipset_attr_lineno-is-present.patch
diff --git a/queue-4.4/usb-fix-don-t-skip-endpoint-descriptors-with-maxpacket-0.patch b/queue-4.4/usb-fix-don-t-skip-endpoint-descriptors-with-maxpacket-0.patch
new file mode 100644 (file)
index 0000000..8bd93c9
--- /dev/null
@@ -0,0 +1,63 @@
+From 2548288b4fb059b2da9ceada172ef763077e8a59 Mon Sep 17 00:00:00 2001
+From: Alan Stern <stern@rowland.harvard.edu>
+Date: Mon, 6 Jan 2020 10:43:42 -0500
+Subject: USB: Fix: Don't skip endpoint descriptors with maxpacket=0
+
+From: Alan Stern <stern@rowland.harvard.edu>
+
+commit 2548288b4fb059b2da9ceada172ef763077e8a59 upstream.
+
+It turns out that even though endpoints with a maxpacket length of 0
+aren't useful for data transfer, the descriptors do serve other
+purposes.  In particular, skipping them will also skip over other
+class-specific descriptors for classes such as UVC.  This unexpected
+side effect has caused some UVC cameras to stop working.
+
+In addition, the USB spec requires that when isochronous endpoint
+descriptors are present in an interface's altsetting 0 (which is true
+on some devices), the maxpacket size _must_ be set to 0.  Warning
+about such things seems like a bad idea.
+
+This patch updates an earlier commit which would log a warning and
+skip these endpoint descriptors.  Now we only log a warning, and we
+don't even do that for isochronous endpoints in altsetting 0.
+
+We don't need to worry about preventing endpoints with maxpacket = 0
+from ever being used for data transfers; usb_submit_urb() already
+checks for this.
+
+Reported-and-tested-by: Roger Whittaker <Roger.Whittaker@suse.com>
+Fixes: d482c7bb0541 ("USB: Skip endpoints with 0 maxpacket length")
+Signed-off-by: Alan Stern <stern@rowland.harvard.edu>
+CC: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
+Link: https://marc.info/?l=linux-usb&m=157790377329882&w=2
+Link: https://lore.kernel.org/r/Pine.LNX.4.44L0.2001061040270.1514-100000@iolanthe.rowland.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/core/config.c |   12 ++++++++----
+ 1 file changed, 8 insertions(+), 4 deletions(-)
+
+--- a/drivers/usb/core/config.c
++++ b/drivers/usb/core/config.c
+@@ -358,12 +358,16 @@ static int usb_parse_endpoint(struct dev
+                       endpoint->desc.wMaxPacketSize = cpu_to_le16(8);
+       }
+-      /* Validate the wMaxPacketSize field */
++      /*
++       * Validate the wMaxPacketSize field.
++       * Some devices have isochronous endpoints in altsetting 0;
++       * the USB-2 spec requires such endpoints to have wMaxPacketSize = 0
++       * (see the end of section 5.6.3), so don't warn about them.
++       */
+       maxp = usb_endpoint_maxp(&endpoint->desc);
+-      if (maxp == 0) {
+-              dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has wMaxPacketSize 0, skipping\n",
++      if (maxp == 0 && !(usb_endpoint_xfer_isoc(d) && asnum == 0)) {
++              dev_warn(ddev, "config %d interface %d altsetting %d endpoint 0x%X has invalid wMaxPacketSize 0\n",
+                   cfgno, inum, asnum, d->bEndpointAddress);
+-              goto skip_to_next_endpoint_or_interface_descriptor;
+       }
+       /* Find the highest legal maxpacket size for this endpoint */