]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 20 Jul 2018 10:05:26 +0000 (12:05 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 20 Jul 2018 10:05:26 +0000 (12:05 +0200)
added patches:
keys-dns-fix-parsing-multiple-options.patch
net-nfc-avoid-stalls-when-nfc_alloc_send_skb-returned-null.patch
netfilter-ebtables-reject-non-bridge-targets.patch
rds-avoid-unenecessary-cong_update-in-loop-transport.patch

queue-4.4/keys-dns-fix-parsing-multiple-options.patch [new file with mode: 0644]
queue-4.4/net-nfc-avoid-stalls-when-nfc_alloc_send_skb-returned-null.patch [new file with mode: 0644]
queue-4.4/netfilter-ebtables-reject-non-bridge-targets.patch [new file with mode: 0644]
queue-4.4/rds-avoid-unenecessary-cong_update-in-loop-transport.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/keys-dns-fix-parsing-multiple-options.patch b/queue-4.4/keys-dns-fix-parsing-multiple-options.patch
new file mode 100644 (file)
index 0000000..b3fd1f4
--- /dev/null
@@ -0,0 +1,107 @@
+From c604cb767049b78b3075497b80ebb8fd530ea2cc Mon Sep 17 00:00:00 2001
+From: Eric Biggers <ebiggers@google.com>
+Date: Wed, 11 Jul 2018 10:46:29 -0700
+Subject: KEYS: DNS: fix parsing multiple options
+
+From: Eric Biggers <ebiggers@google.com>
+
+commit c604cb767049b78b3075497b80ebb8fd530ea2cc upstream.
+
+My recent fix for dns_resolver_preparse() printing very long strings was
+incomplete, as shown by syzbot which still managed to hit the
+WARN_ONCE() in set_precision() by adding a crafted "dns_resolver" key:
+
+    precision 50001 too large
+    WARNING: CPU: 7 PID: 864 at lib/vsprintf.c:2164 vsnprintf+0x48a/0x5a0
+
+The bug this time isn't just a printing bug, but also a logical error
+when multiple options ("#"-separated strings) are given in the key
+payload.  Specifically, when separating an option string into name and
+value, if there is no value then the name is incorrectly considered to
+end at the end of the key payload, rather than the end of the current
+option.  This bypasses validation of the option length, and also means
+that specifying multiple options is broken -- which presumably has gone
+unnoticed as there is currently only one valid option anyway.
+
+A similar problem also applied to option values, as the kstrtoul() when
+parsing the "dnserror" option will read past the end of the current
+option and into the next option.
+
+Fix these bugs by correctly computing the length of the option name and
+by copying the option value, null-terminated, into a temporary buffer.
+
+Reproducer for the WARN_ONCE() that syzbot hit:
+
+    perl -e 'print "#A#", "\0" x 50000' | keyctl padd dns_resolver desc @s
+
+Reproducer for "dnserror" option being parsed incorrectly (expected
+behavior is to fail when seeing the unknown option "foo", actual
+behavior was to read the dnserror value as "1#foo" and fail there):
+
+    perl -e 'print "#dnserror=1#foo\0"' | keyctl padd dns_resolver desc @s
+
+Reported-by: syzbot <syzkaller@googlegroups.com>
+Fixes: 4a2d789267e0 ("DNS: If the DNS server returns an error, allow that to be cached [ver #2]")
+Signed-off-by: Eric Biggers <ebiggers@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/dns_resolver/dns_key.c |   30 +++++++++++++++++-------------
+ 1 file changed, 17 insertions(+), 13 deletions(-)
+
+--- a/net/dns_resolver/dns_key.c
++++ b/net/dns_resolver/dns_key.c
+@@ -87,35 +87,39 @@ dns_resolver_preparse(struct key_prepars
+               opt++;
+               kdebug("options: '%s'", opt);
+               do {
++                      int opt_len, opt_nlen;
+                       const char *eq;
+-                      int opt_len, opt_nlen, opt_vlen, tmp;
++                      char optval[128];
+                       next_opt = memchr(opt, '#', end - opt) ?: end;
+                       opt_len = next_opt - opt;
+-                      if (opt_len <= 0 || opt_len > 128) {
++                      if (opt_len <= 0 || opt_len > sizeof(optval)) {
+                               pr_warn_ratelimited("Invalid option length (%d) for dns_resolver key\n",
+                                                   opt_len);
+                               return -EINVAL;
+                       }
+-                      eq = memchr(opt, '=', opt_len) ?: end;
+-                      opt_nlen = eq - opt;
+-                      eq++;
+-                      opt_vlen = next_opt - eq; /* will be -1 if no value */
+-
+-                      tmp = opt_vlen >= 0 ? opt_vlen : 0;
+-                      kdebug("option '%*.*s' val '%*.*s'",
+-                             opt_nlen, opt_nlen, opt, tmp, tmp, eq);
++                      eq = memchr(opt, '=', opt_len);
++                      if (eq) {
++                              opt_nlen = eq - opt;
++                              eq++;
++                              memcpy(optval, eq, next_opt - eq);
++                              optval[next_opt - eq] = '\0';
++                      } else {
++                              opt_nlen = opt_len;
++                              optval[0] = '\0';
++                      }
++
++                      kdebug("option '%*.*s' val '%s'",
++                             opt_nlen, opt_nlen, opt, optval);
+                       /* see if it's an error number representing a DNS error
+                        * that's to be recorded as the result in this key */
+                       if (opt_nlen == sizeof(DNS_ERRORNO_OPTION) - 1 &&
+                           memcmp(opt, DNS_ERRORNO_OPTION, opt_nlen) == 0) {
+                               kdebug("dns error number option");
+-                              if (opt_vlen <= 0)
+-                                      goto bad_option_value;
+-                              ret = kstrtoul(eq, 10, &derrno);
++                              ret = kstrtoul(optval, 10, &derrno);
+                               if (ret < 0)
+                                       goto bad_option_value;
diff --git a/queue-4.4/net-nfc-avoid-stalls-when-nfc_alloc_send_skb-returned-null.patch b/queue-4.4/net-nfc-avoid-stalls-when-nfc_alloc_send_skb-returned-null.patch
new file mode 100644 (file)
index 0000000..46c3536
--- /dev/null
@@ -0,0 +1,49 @@
+From 3bc53be9db21040b5d2de4d455f023c8c494aa68 Mon Sep 17 00:00:00 2001
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Date: Wed, 18 Jul 2018 18:57:27 +0900
+Subject: net/nfc: Avoid stalls when nfc_alloc_send_skb() returned NULL.
+
+From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+
+commit 3bc53be9db21040b5d2de4d455f023c8c494aa68 upstream.
+
+syzbot is reporting stalls at nfc_llcp_send_ui_frame() [1]. This is
+because nfc_llcp_send_ui_frame() is retrying the loop without any delay
+when nonblocking nfc_alloc_send_skb() returned NULL.
+
+Since there is no need to use MSG_DONTWAIT if we retry until
+sock_alloc_send_pskb() succeeds, let's use blocking call.
+Also, in case an unexpected error occurred, let's break the loop
+if blocking nfc_alloc_send_skb() failed.
+
+[1] https://syzkaller.appspot.com/bug?id=4a131cc571c3733e0eff6bc673f4e36ae48f19c6
+
+Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Reported-by: syzbot <syzbot+d29d18215e477cfbfbdd@syzkaller.appspotmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/nfc/llcp_commands.c |    9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/net/nfc/llcp_commands.c
++++ b/net/nfc/llcp_commands.c
+@@ -754,11 +754,14 @@ int nfc_llcp_send_ui_frame(struct nfc_ll
+               pr_debug("Fragment %zd bytes remaining %zd",
+                        frag_len, remaining_len);
+-              pdu = nfc_alloc_send_skb(sock->dev, &sock->sk, MSG_DONTWAIT,
++              pdu = nfc_alloc_send_skb(sock->dev, &sock->sk, 0,
+                                        frag_len + LLCP_HEADER_SIZE, &err);
+               if (pdu == NULL) {
+-                      pr_err("Could not allocate PDU\n");
+-                      continue;
++                      pr_err("Could not allocate PDU (error=%d)\n", err);
++                      len -= remaining_len;
++                      if (len == 0)
++                              len = err;
++                      break;
+               }
+               pdu = llcp_add_header(pdu, dsap, ssap, LLCP_PDU_UI);
diff --git a/queue-4.4/netfilter-ebtables-reject-non-bridge-targets.patch b/queue-4.4/netfilter-ebtables-reject-non-bridge-targets.patch
new file mode 100644 (file)
index 0000000..3de5691
--- /dev/null
@@ -0,0 +1,64 @@
+From 11ff7288beb2b7da889a014aff0a7b80bf8efcf3 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Wed, 6 Jun 2018 12:14:56 +0200
+Subject: netfilter: ebtables: reject non-bridge targets
+
+From: Florian Westphal <fw@strlen.de>
+
+commit 11ff7288beb2b7da889a014aff0a7b80bf8efcf3 upstream.
+
+the ebtables evaluation loop expects targets to return
+positive values (jumps), or negative values (absolute verdicts).
+
+This is completely different from what xtables does.
+In xtables, targets are expected to return the standard netfilter
+verdicts, i.e. NF_DROP, NF_ACCEPT, etc.
+
+ebtables will consider these as jumps.
+
+Therefore reject any target found due to unspec fallback.
+v2: also reject watchers.  ebtables ignores their return value, so
+a target that assumes skb ownership (and returns NF_STOLEN) causes
+use-after-free.
+
+The only watchers in the 'ebtables' front-end are log and nflog;
+both have AF_BRIDGE specific wrappers on kernel side.
+
+Reported-by: syzbot+2b43f681169a2a0d306a@syzkaller.appspotmail.com
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/bridge/netfilter/ebtables.c |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -404,6 +404,12 @@ ebt_check_watcher(struct ebt_entry_watch
+       watcher = xt_request_find_target(NFPROTO_BRIDGE, w->u.name, 0);
+       if (IS_ERR(watcher))
+               return PTR_ERR(watcher);
++
++      if (watcher->family != NFPROTO_BRIDGE) {
++              module_put(watcher->me);
++              return -ENOENT;
++      }
++
+       w->u.watcher = watcher;
+       par->target   = watcher;
+@@ -724,6 +730,13 @@ ebt_check_entry(struct ebt_entry *e, str
+               goto cleanup_watchers;
+       }
++      /* Reject UNSPEC, xtables verdicts/return values are incompatible */
++      if (target->family != NFPROTO_BRIDGE) {
++              module_put(target->me);
++              ret = -ENOENT;
++              goto cleanup_watchers;
++      }
++
+       t->u.target = target;
+       if (t->u.target == &ebt_standard_target) {
+               if (gap < sizeof(struct ebt_standard_target)) {
diff --git a/queue-4.4/rds-avoid-unenecessary-cong_update-in-loop-transport.patch b/queue-4.4/rds-avoid-unenecessary-cong_update-in-loop-transport.patch
new file mode 100644 (file)
index 0000000..bc507b9
--- /dev/null
@@ -0,0 +1,61 @@
+From f1693c63ab133d16994cc50f773982b5905af264 Mon Sep 17 00:00:00 2001
+From: Santosh Shilimkar <santosh.shilimkar@oracle.com>
+Date: Thu, 14 Jun 2018 11:52:34 -0700
+Subject: rds: avoid unenecessary cong_update in loop transport
+
+From: Santosh Shilimkar <santosh.shilimkar@oracle.com>
+
+commit f1693c63ab133d16994cc50f773982b5905af264 upstream.
+
+Loop transport which is self loopback, remote port congestion
+update isn't relevant. Infact the xmit path already ignores it.
+Receive path needs to do the same.
+
+Reported-by: syzbot+4c20b3866171ce8441d2@syzkaller.appspotmail.com
+Reviewed-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+Signed-off-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/rds/loop.c |    1 +
+ net/rds/rds.h  |    5 +++++
+ net/rds/recv.c |    5 +++++
+ 3 files changed, 11 insertions(+)
+
+--- a/net/rds/loop.c
++++ b/net/rds/loop.c
+@@ -191,4 +191,5 @@ struct rds_transport rds_loop_transport
+       .inc_copy_to_user       = rds_message_inc_copy_to_user,
+       .inc_free               = rds_loop_inc_free,
+       .t_name                 = "loopback",
++      .t_type                 = RDS_TRANS_LOOP,
+ };
+--- a/net/rds/rds.h
++++ b/net/rds/rds.h
+@@ -401,6 +401,11 @@ struct rds_notifier {
+       int                     n_status;
+ };
++/* Available as part of RDS core, so doesn't need to participate
++ * in get_preferred transport etc
++ */
++#define       RDS_TRANS_LOOP  3
++
+ /**
+  * struct rds_transport -  transport specific behavioural hooks
+  *
+--- a/net/rds/recv.c
++++ b/net/rds/recv.c
+@@ -76,6 +76,11 @@ static void rds_recv_rcvbuf_delta(struct
+               return;
+       rs->rs_rcv_bytes += delta;
++
++      /* loop transport doesn't send/recv congestion updates */
++      if (rs->rs_transport->t_type == RDS_TRANS_LOOP)
++              return;
++
+       now_congested = rs->rs_rcv_bytes > rds_sk_rcvbuf(rs);
+       rdsdebug("rs %p (%pI4:%u) recv bytes %d buf %d "
index 102f7444593a1d06003cf52751e4ff6c6020573e..342559fe3b295d6a3accd1a919109ae0717367d1 100644 (file)
@@ -25,3 +25,7 @@ net-cxgb3_main-fix-potential-spectre-v1.patch
 rtlwifi-rtl8821ae-fix-firmware-is-not-ready-to-run.patch
 mips-call-dump_stack-from-show_regs.patch
 mips-use-async-ipis-for-arch_trigger_cpumask_backtrace.patch
+netfilter-ebtables-reject-non-bridge-targets.patch
+keys-dns-fix-parsing-multiple-options.patch
+rds-avoid-unenecessary-cong_update-in-loop-transport.patch
+net-nfc-avoid-stalls-when-nfc_alloc_send_skb-returned-null.patch