From: Greg Kroah-Hartman Date: Fri, 20 Jul 2018 10:05:43 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v3.18.116~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7908ea4a618eb32fba0152b128c087bf644999a7;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches 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 netfilter-ipv6-nf_defrag-drop-skb-dst-before-queueing.patch rds-avoid-unenecessary-cong_update-in-loop-transport.patch reiserfs-fix-buffer-overflow-with-long-warning-messages.patch --- diff --git a/queue-4.9/keys-dns-fix-parsing-multiple-options.patch b/queue-4.9/keys-dns-fix-parsing-multiple-options.patch new file mode 100644 index 00000000000..b3fd1f4f660 --- /dev/null +++ b/queue-4.9/keys-dns-fix-parsing-multiple-options.patch @@ -0,0 +1,107 @@ +From c604cb767049b78b3075497b80ebb8fd530ea2cc Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Wed, 11 Jul 2018 10:46:29 -0700 +Subject: KEYS: DNS: fix parsing multiple options + +From: Eric Biggers + +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 +Fixes: 4a2d789267e0 ("DNS: If the DNS server returns an error, allow that to be cached [ver #2]") +Signed-off-by: Eric Biggers +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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.9/net-nfc-avoid-stalls-when-nfc_alloc_send_skb-returned-null.patch b/queue-4.9/net-nfc-avoid-stalls-when-nfc_alloc_send_skb-returned-null.patch new file mode 100644 index 00000000000..27b911ce8d6 --- /dev/null +++ b/queue-4.9/net-nfc-avoid-stalls-when-nfc_alloc_send_skb-returned-null.patch @@ -0,0 +1,49 @@ +From 3bc53be9db21040b5d2de4d455f023c8c494aa68 Mon Sep 17 00:00:00 2001 +From: Tetsuo Handa +Date: Wed, 18 Jul 2018 18:57:27 +0900 +Subject: net/nfc: Avoid stalls when nfc_alloc_send_skb() returned NULL. + +From: Tetsuo Handa + +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 +Reported-by: syzbot +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -753,11 +753,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.9/netfilter-ebtables-reject-non-bridge-targets.patch b/queue-4.9/netfilter-ebtables-reject-non-bridge-targets.patch new file mode 100644 index 00000000000..8de47536cc8 --- /dev/null +++ b/queue-4.9/netfilter-ebtables-reject-non-bridge-targets.patch @@ -0,0 +1,64 @@ +From 11ff7288beb2b7da889a014aff0a7b80bf8efcf3 Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Wed, 6 Jun 2018 12:14:56 +0200 +Subject: netfilter: ebtables: reject non-bridge targets + +From: Florian Westphal + +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 +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/bridge/netfilter/ebtables.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/net/bridge/netfilter/ebtables.c ++++ b/net/bridge/netfilter/ebtables.c +@@ -406,6 +406,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; +@@ -727,6 +733,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.9/netfilter-ipv6-nf_defrag-drop-skb-dst-before-queueing.patch b/queue-4.9/netfilter-ipv6-nf_defrag-drop-skb-dst-before-queueing.patch new file mode 100644 index 00000000000..1827d393f8b --- /dev/null +++ b/queue-4.9/netfilter-ipv6-nf_defrag-drop-skb-dst-before-queueing.patch @@ -0,0 +1,52 @@ +From 84379c9afe011020e797e3f50a662b08a6355dcf Mon Sep 17 00:00:00 2001 +From: Florian Westphal +Date: Mon, 9 Jul 2018 13:43:38 +0200 +Subject: netfilter: ipv6: nf_defrag: drop skb dst before queueing + +From: Florian Westphal + +commit 84379c9afe011020e797e3f50a662b08a6355dcf upstream. + +Eric Dumazet reports: + Here is a reproducer of an annoying bug detected by syzkaller on our production kernel + [..] + ./b78305423 enable_conntrack + Then : + sleep 60 + dmesg | tail -10 + [ 171.599093] unregister_netdevice: waiting for lo to become free. Usage count = 2 + [ 181.631024] unregister_netdevice: waiting for lo to become free. Usage count = 2 + [ 191.687076] unregister_netdevice: waiting for lo to become free. Usage count = 2 + [ 201.703037] unregister_netdevice: waiting for lo to become free. Usage count = 2 + [ 211.711072] unregister_netdevice: waiting for lo to become free. Usage count = 2 + [ 221.959070] unregister_netdevice: waiting for lo to become free. Usage count = 2 + +Reproducer sends ipv6 fragment that hits nfct defrag via LOCAL_OUT hook. +skb gets queued until frag timer expiry -- 1 minute. + +Normally nf_conntrack_reasm gets called during prerouting, so skb has +no dst yet which might explain why this wasn't spotted earlier. + +Reported-by: Eric Dumazet +Reported-by: John Sperbeck +Signed-off-by: Florian Westphal +Tested-by: Eric Dumazet +Reported-by: syzbot +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Greg Kroah-Hartman + +--- + net/ipv6/netfilter/nf_conntrack_reasm.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/ipv6/netfilter/nf_conntrack_reasm.c ++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c +@@ -618,6 +618,8 @@ int nf_ct_frag6_gather(struct net *net, + fq->q.meat == fq->q.len && + nf_ct_frag6_reasm(fq, skb, dev)) + ret = 0; ++ else ++ skb_dst_drop(skb); + + out_unlock: + spin_unlock_bh(&fq->q.lock); diff --git a/queue-4.9/rds-avoid-unenecessary-cong_update-in-loop-transport.patch b/queue-4.9/rds-avoid-unenecessary-cong_update-in-loop-transport.patch new file mode 100644 index 00000000000..b0ec6efcf14 --- /dev/null +++ b/queue-4.9/rds-avoid-unenecessary-cong_update-in-loop-transport.patch @@ -0,0 +1,61 @@ +From f1693c63ab133d16994cc50f773982b5905af264 Mon Sep 17 00:00:00 2001 +From: Santosh Shilimkar +Date: Thu, 14 Jun 2018 11:52:34 -0700 +Subject: rds: avoid unenecessary cong_update in loop transport + +From: Santosh Shilimkar + +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 +Signed-off-by: Santosh Shilimkar +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman + +--- + 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 +@@ -193,4 +193,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 +@@ -440,6 +440,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 +@@ -94,6 +94,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 " diff --git a/queue-4.9/reiserfs-fix-buffer-overflow-with-long-warning-messages.patch b/queue-4.9/reiserfs-fix-buffer-overflow-with-long-warning-messages.patch new file mode 100644 index 00000000000..e2cd1952784 --- /dev/null +++ b/queue-4.9/reiserfs-fix-buffer-overflow-with-long-warning-messages.patch @@ -0,0 +1,252 @@ +From fe10e398e860955bac4d28ec031b701d358465e4 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Fri, 13 Jul 2018 16:59:27 -0700 +Subject: reiserfs: fix buffer overflow with long warning messages + +From: Eric Biggers + +commit fe10e398e860955bac4d28ec031b701d358465e4 upstream. + +ReiserFS prepares log messages into a 1024-byte buffer with no bounds +checks. Long messages, such as the "unknown mount option" warning when +userspace passes a crafted mount options string, overflow this buffer. +This causes KASAN to report a global-out-of-bounds write. + +Fix it by truncating messages to the buffer size. + +Link: http://lkml.kernel.org/r/20180707203621.30922-1-ebiggers3@gmail.com +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot+b890b3335a4d8c608963@syzkaller.appspotmail.com +Signed-off-by: Eric Biggers +Reviewed-by: Andrew Morton +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/reiserfs/prints.c | 141 +++++++++++++++++++++++++++++---------------------- + 1 file changed, 81 insertions(+), 60 deletions(-) + +--- a/fs/reiserfs/prints.c ++++ b/fs/reiserfs/prints.c +@@ -76,83 +76,99 @@ static char *le_type(struct reiserfs_key + } + + /* %k */ +-static void sprintf_le_key(char *buf, struct reiserfs_key *key) ++static int scnprintf_le_key(char *buf, size_t size, struct reiserfs_key *key) + { + if (key) +- sprintf(buf, "[%d %d %s %s]", le32_to_cpu(key->k_dir_id), +- le32_to_cpu(key->k_objectid), le_offset(key), +- le_type(key)); ++ return scnprintf(buf, size, "[%d %d %s %s]", ++ le32_to_cpu(key->k_dir_id), ++ le32_to_cpu(key->k_objectid), le_offset(key), ++ le_type(key)); + else +- sprintf(buf, "[NULL]"); ++ return scnprintf(buf, size, "[NULL]"); + } + + /* %K */ +-static void sprintf_cpu_key(char *buf, struct cpu_key *key) ++static int scnprintf_cpu_key(char *buf, size_t size, struct cpu_key *key) + { + if (key) +- sprintf(buf, "[%d %d %s %s]", key->on_disk_key.k_dir_id, +- key->on_disk_key.k_objectid, reiserfs_cpu_offset(key), +- cpu_type(key)); ++ return scnprintf(buf, size, "[%d %d %s %s]", ++ key->on_disk_key.k_dir_id, ++ key->on_disk_key.k_objectid, ++ reiserfs_cpu_offset(key), cpu_type(key)); + else +- sprintf(buf, "[NULL]"); ++ return scnprintf(buf, size, "[NULL]"); + } + +-static void sprintf_de_head(char *buf, struct reiserfs_de_head *deh) ++static int scnprintf_de_head(char *buf, size_t size, ++ struct reiserfs_de_head *deh) + { + if (deh) +- sprintf(buf, +- "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]", +- deh_offset(deh), deh_dir_id(deh), deh_objectid(deh), +- deh_location(deh), deh_state(deh)); ++ return scnprintf(buf, size, ++ "[offset=%d dir_id=%d objectid=%d location=%d state=%04x]", ++ deh_offset(deh), deh_dir_id(deh), ++ deh_objectid(deh), deh_location(deh), ++ deh_state(deh)); + else +- sprintf(buf, "[NULL]"); ++ return scnprintf(buf, size, "[NULL]"); + + } + +-static void sprintf_item_head(char *buf, struct item_head *ih) ++static int scnprintf_item_head(char *buf, size_t size, struct item_head *ih) + { + if (ih) { +- strcpy(buf, +- (ih_version(ih) == KEY_FORMAT_3_6) ? "*3.6* " : "*3.5*"); +- sprintf_le_key(buf + strlen(buf), &(ih->ih_key)); +- sprintf(buf + strlen(buf), ", item_len %d, item_location %d, " +- "free_space(entry_count) %d", +- ih_item_len(ih), ih_location(ih), ih_free_space(ih)); ++ char *p = buf; ++ char * const end = buf + size; ++ ++ p += scnprintf(p, end - p, "%s", ++ (ih_version(ih) == KEY_FORMAT_3_6) ? ++ "*3.6* " : "*3.5*"); ++ ++ p += scnprintf_le_key(p, end - p, &ih->ih_key); ++ ++ p += scnprintf(p, end - p, ++ ", item_len %d, item_location %d, free_space(entry_count) %d", ++ ih_item_len(ih), ih_location(ih), ++ ih_free_space(ih)); ++ return p - buf; + } else +- sprintf(buf, "[NULL]"); ++ return scnprintf(buf, size, "[NULL]"); + } + +-static void sprintf_direntry(char *buf, struct reiserfs_dir_entry *de) ++static int scnprintf_direntry(char *buf, size_t size, ++ struct reiserfs_dir_entry *de) + { + char name[20]; + + memcpy(name, de->de_name, de->de_namelen > 19 ? 19 : de->de_namelen); + name[de->de_namelen > 19 ? 19 : de->de_namelen] = 0; +- sprintf(buf, "\"%s\"==>[%d %d]", name, de->de_dir_id, de->de_objectid); ++ return scnprintf(buf, size, "\"%s\"==>[%d %d]", ++ name, de->de_dir_id, de->de_objectid); + } + +-static void sprintf_block_head(char *buf, struct buffer_head *bh) ++static int scnprintf_block_head(char *buf, size_t size, struct buffer_head *bh) + { +- sprintf(buf, "level=%d, nr_items=%d, free_space=%d rdkey ", +- B_LEVEL(bh), B_NR_ITEMS(bh), B_FREE_SPACE(bh)); ++ return scnprintf(buf, size, ++ "level=%d, nr_items=%d, free_space=%d rdkey ", ++ B_LEVEL(bh), B_NR_ITEMS(bh), B_FREE_SPACE(bh)); + } + +-static void sprintf_buffer_head(char *buf, struct buffer_head *bh) ++static int scnprintf_buffer_head(char *buf, size_t size, struct buffer_head *bh) + { +- sprintf(buf, +- "dev %pg, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)", +- bh->b_bdev, bh->b_size, +- (unsigned long long)bh->b_blocknr, atomic_read(&(bh->b_count)), +- bh->b_state, bh->b_page, +- buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE", +- buffer_dirty(bh) ? "DIRTY" : "CLEAN", +- buffer_locked(bh) ? "LOCKED" : "UNLOCKED"); ++ return scnprintf(buf, size, ++ "dev %pg, size %zd, blocknr %llu, count %d, state 0x%lx, page %p, (%s, %s, %s)", ++ bh->b_bdev, bh->b_size, ++ (unsigned long long)bh->b_blocknr, ++ atomic_read(&(bh->b_count)), ++ bh->b_state, bh->b_page, ++ buffer_uptodate(bh) ? "UPTODATE" : "!UPTODATE", ++ buffer_dirty(bh) ? "DIRTY" : "CLEAN", ++ buffer_locked(bh) ? "LOCKED" : "UNLOCKED"); + } + +-static void sprintf_disk_child(char *buf, struct disk_child *dc) ++static int scnprintf_disk_child(char *buf, size_t size, struct disk_child *dc) + { +- sprintf(buf, "[dc_number=%d, dc_size=%u]", dc_block_number(dc), +- dc_size(dc)); ++ return scnprintf(buf, size, "[dc_number=%d, dc_size=%u]", ++ dc_block_number(dc), dc_size(dc)); + } + + static char *is_there_reiserfs_struct(char *fmt, int *what) +@@ -189,55 +205,60 @@ static void prepare_error_buf(const char + char *fmt1 = fmt_buf; + char *k; + char *p = error_buf; ++ char * const end = &error_buf[sizeof(error_buf)]; + int what; + + spin_lock(&error_lock); + +- strcpy(fmt1, fmt); ++ if (WARN_ON(strscpy(fmt_buf, fmt, sizeof(fmt_buf)) < 0)) { ++ strscpy(error_buf, "format string too long", end - error_buf); ++ goto out_unlock; ++ } + + while ((k = is_there_reiserfs_struct(fmt1, &what)) != NULL) { + *k = 0; + +- p += vsprintf(p, fmt1, args); ++ p += vscnprintf(p, end - p, fmt1, args); + + switch (what) { + case 'k': +- sprintf_le_key(p, va_arg(args, struct reiserfs_key *)); ++ p += scnprintf_le_key(p, end - p, ++ va_arg(args, struct reiserfs_key *)); + break; + case 'K': +- sprintf_cpu_key(p, va_arg(args, struct cpu_key *)); ++ p += scnprintf_cpu_key(p, end - p, ++ va_arg(args, struct cpu_key *)); + break; + case 'h': +- sprintf_item_head(p, va_arg(args, struct item_head *)); ++ p += scnprintf_item_head(p, end - p, ++ va_arg(args, struct item_head *)); + break; + case 't': +- sprintf_direntry(p, +- va_arg(args, +- struct reiserfs_dir_entry *)); ++ p += scnprintf_direntry(p, end - p, ++ va_arg(args, struct reiserfs_dir_entry *)); + break; + case 'y': +- sprintf_disk_child(p, +- va_arg(args, struct disk_child *)); ++ p += scnprintf_disk_child(p, end - p, ++ va_arg(args, struct disk_child *)); + break; + case 'z': +- sprintf_block_head(p, +- va_arg(args, struct buffer_head *)); ++ p += scnprintf_block_head(p, end - p, ++ va_arg(args, struct buffer_head *)); + break; + case 'b': +- sprintf_buffer_head(p, +- va_arg(args, struct buffer_head *)); ++ p += scnprintf_buffer_head(p, end - p, ++ va_arg(args, struct buffer_head *)); + break; + case 'a': +- sprintf_de_head(p, +- va_arg(args, +- struct reiserfs_de_head *)); ++ p += scnprintf_de_head(p, end - p, ++ va_arg(args, struct reiserfs_de_head *)); + break; + } + +- p += strlen(p); + fmt1 = k + 2; + } +- vsprintf(p, fmt1, args); ++ p += vscnprintf(p, end - p, fmt1, args); ++out_unlock: + spin_unlock(&error_lock); + + } diff --git a/queue-4.9/series b/queue-4.9/series index 1aa6c08e3b5..c6a8584deff 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -34,3 +34,9 @@ net-mlx5-fix-command-interface-race-in-polling-mode.patch net-cxgb3_main-fix-potential-spectre-v1.patch rtlwifi-rtl8821ae-fix-firmware-is-not-ready-to-run.patch net-lan78xx-fix-race-in-tx-pending-skb-size-calculation.patch +netfilter-ebtables-reject-non-bridge-targets.patch +reiserfs-fix-buffer-overflow-with-long-warning-messages.patch +keys-dns-fix-parsing-multiple-options.patch +netfilter-ipv6-nf_defrag-drop-skb-dst-before-queueing.patch +rds-avoid-unenecessary-cong_update-in-loop-transport.patch +net-nfc-avoid-stalls-when-nfc_alloc_send_skb-returned-null.patch