From: Greg Kroah-Hartman Date: Mon, 4 Oct 2021 09:59:40 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.4.286~40 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bef9c01a7ccda96ab8eb100e4fe06e1e93f68227;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: ext4-fix-potential-infinite-loop-in-ext4_dx_readdir.patch ipack-ipoctal-fix-missing-allocation-failure-check.patch ipack-ipoctal-fix-module-reference-leak.patch ipack-ipoctal-fix-stack-information-leak.patch ipack-ipoctal-fix-tty-registration-error-handling.patch ipack-ipoctal-fix-tty-registration-race.patch net-udp-annotate-data-race-around-udp_sk-sk-corkflag.patch --- diff --git a/queue-4.9/ext4-fix-potential-infinite-loop-in-ext4_dx_readdir.patch b/queue-4.9/ext4-fix-potential-infinite-loop-in-ext4_dx_readdir.patch new file mode 100644 index 00000000000..da2f809f728 --- /dev/null +++ b/queue-4.9/ext4-fix-potential-infinite-loop-in-ext4_dx_readdir.patch @@ -0,0 +1,68 @@ +From 42cb447410d024e9d54139ae9c21ea132a8c384c Mon Sep 17 00:00:00 2001 +From: yangerkun +Date: Tue, 14 Sep 2021 19:14:15 +0800 +Subject: ext4: fix potential infinite loop in ext4_dx_readdir() + +From: yangerkun + +commit 42cb447410d024e9d54139ae9c21ea132a8c384c upstream. + +When ext4_htree_fill_tree() fails, ext4_dx_readdir() can run into an +infinite loop since if info->last_pos != ctx->pos this will reset the +directory scan and reread the failing entry. For example: + +1. a dx_dir which has 3 block, block 0 as dx_root block, block 1/2 as + leaf block which own the ext4_dir_entry_2 +2. block 1 read ok and call_filldir which will fill the dirent and update + the ctx->pos +3. block 2 read fail, but we has already fill some dirent, so we will + return back to userspace will a positive return val(see ksys_getdents64) +4. the second ext4_dx_readdir will reset the world since info->last_pos + != ctx->pos, and will also init the curr_hash which pos to block 1 +5. So we will read block1 too, and once block2 still read fail, we can + only fill one dirent because the hash of the entry in block1(besides + the last one) won't greater than curr_hash +6. this time, we forget update last_pos too since the read for block2 + will fail, and since we has got the one entry, ksys_getdents64 can + return success +7. Latter we will trapped in a loop with step 4~6 + +Cc: stable@kernel.org +Signed-off-by: yangerkun +Reviewed-by: Jan Kara +Signed-off-by: Theodore Ts'o +Link: https://lore.kernel.org/r/20210914111415.3921954-1-yangerkun@huawei.com +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/dir.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/fs/ext4/dir.c ++++ b/fs/ext4/dir.c +@@ -531,7 +531,7 @@ static int ext4_dx_readdir(struct file * + struct dir_private_info *info = file->private_data; + struct inode *inode = file_inode(file); + struct fname *fname; +- int ret; ++ int ret = 0; + + if (!info) { + info = ext4_htree_create_dir_info(file, ctx->pos); +@@ -579,7 +579,7 @@ static int ext4_dx_readdir(struct file * + info->curr_minor_hash, + &info->next_hash); + if (ret < 0) +- return ret; ++ goto finished; + if (ret == 0) { + ctx->pos = ext4_get_htree_eof(file); + break; +@@ -610,7 +610,7 @@ static int ext4_dx_readdir(struct file * + } + finished: + info->last_pos = ctx->pos; +- return 0; ++ return ret < 0 ? ret : 0; + } + + static int ext4_dir_open(struct inode * inode, struct file * filp) diff --git a/queue-4.9/ipack-ipoctal-fix-missing-allocation-failure-check.patch b/queue-4.9/ipack-ipoctal-fix-missing-allocation-failure-check.patch new file mode 100644 index 00000000000..ddeb3997634 --- /dev/null +++ b/queue-4.9/ipack-ipoctal-fix-missing-allocation-failure-check.patch @@ -0,0 +1,36 @@ +From 445c8132727728dc297492a7d9fc074af3e94ba3 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 17 Sep 2021 13:46:20 +0200 +Subject: ipack: ipoctal: fix missing allocation-failure check + +From: Johan Hovold + +commit 445c8132727728dc297492a7d9fc074af3e94ba3 upstream. + +Add the missing error handling when allocating the transmit buffer to +avoid dereferencing a NULL pointer in write() should the allocation +ever fail. + +Fixes: ba4dc61fe8c5 ("Staging: ipack: add support for IP-OCTAL mezzanine board") +Cc: stable@vger.kernel.org # 3.5 +Acked-by: Samuel Iglesias Gonsalvez +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20210917114622.5412-5-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ipack/devices/ipoctal.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/ipack/devices/ipoctal.c ++++ b/drivers/ipack/devices/ipoctal.c +@@ -391,7 +391,9 @@ static int ipoctal_inst_slot(struct ipoc + + channel = &ipoctal->channel[i]; + tty_port_init(&channel->tty_port); +- tty_port_alloc_xmit_buf(&channel->tty_port); ++ res = tty_port_alloc_xmit_buf(&channel->tty_port); ++ if (res) ++ continue; + channel->tty_port.ops = &ipoctal_tty_port_ops; + + ipoctal_reset_stats(&channel->stats); diff --git a/queue-4.9/ipack-ipoctal-fix-module-reference-leak.patch b/queue-4.9/ipack-ipoctal-fix-module-reference-leak.patch new file mode 100644 index 00000000000..e2bd4e957fc --- /dev/null +++ b/queue-4.9/ipack-ipoctal-fix-module-reference-leak.patch @@ -0,0 +1,79 @@ +From bb8a4fcb2136508224c596a7e665bdba1d7c3c27 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 17 Sep 2021 13:46:21 +0200 +Subject: ipack: ipoctal: fix module reference leak + +From: Johan Hovold + +commit bb8a4fcb2136508224c596a7e665bdba1d7c3c27 upstream. + +A reference to the carrier module was taken on every open but was only +released once when the final reference to the tty struct was dropped. + +Fix this by taking the module reference and initialising the tty driver +data when installing the tty. + +Fixes: 82a82340bab6 ("ipoctal: get carrier driver to avoid rmmod") +Cc: stable@vger.kernel.org # 3.18 +Cc: Federico Vaga +Acked-by: Samuel Iglesias Gonsalvez +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20210917114622.5412-6-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ipack/devices/ipoctal.c | 29 +++++++++++++++++++++-------- + 1 file changed, 21 insertions(+), 8 deletions(-) + +--- a/drivers/ipack/devices/ipoctal.c ++++ b/drivers/ipack/devices/ipoctal.c +@@ -87,22 +87,34 @@ static int ipoctal_port_activate(struct + return 0; + } + +-static int ipoctal_open(struct tty_struct *tty, struct file *file) ++static int ipoctal_install(struct tty_driver *driver, struct tty_struct *tty) + { + struct ipoctal_channel *channel = dev_get_drvdata(tty->dev); + struct ipoctal *ipoctal = chan_to_ipoctal(channel, tty->index); +- int err; +- +- tty->driver_data = channel; ++ int res; + + if (!ipack_get_carrier(ipoctal->dev)) + return -EBUSY; + +- err = tty_port_open(&channel->tty_port, tty, file); +- if (err) +- ipack_put_carrier(ipoctal->dev); ++ res = tty_standard_install(driver, tty); ++ if (res) ++ goto err_put_carrier; ++ ++ tty->driver_data = channel; ++ ++ return 0; ++ ++err_put_carrier: ++ ipack_put_carrier(ipoctal->dev); ++ ++ return res; ++} ++ ++static int ipoctal_open(struct tty_struct *tty, struct file *file) ++{ ++ struct ipoctal_channel *channel = tty->driver_data; + +- return err; ++ return tty_port_open(&channel->tty_port, tty, file); + } + + static void ipoctal_reset_stats(struct ipoctal_stats *stats) +@@ -668,6 +680,7 @@ static void ipoctal_cleanup(struct tty_s + + static const struct tty_operations ipoctal_fops = { + .ioctl = NULL, ++ .install = ipoctal_install, + .open = ipoctal_open, + .close = ipoctal_close, + .write = ipoctal_write_tty, diff --git a/queue-4.9/ipack-ipoctal-fix-stack-information-leak.patch b/queue-4.9/ipack-ipoctal-fix-stack-information-leak.patch new file mode 100644 index 00000000000..23a69a76729 --- /dev/null +++ b/queue-4.9/ipack-ipoctal-fix-stack-information-leak.patch @@ -0,0 +1,86 @@ +From a89936cce87d60766a75732a9e7e25c51164f47c Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 17 Sep 2021 13:46:17 +0200 +Subject: ipack: ipoctal: fix stack information leak + +From: Johan Hovold + +commit a89936cce87d60766a75732a9e7e25c51164f47c upstream. + +The tty driver name is used also after registering the driver and must +specifically not be allocated on the stack to avoid leaking information +to user space (or triggering an oops). + +Drivers should not try to encode topology information in the tty device +name but this one snuck in through staging without anyone noticing and +another driver has since copied this malpractice. + +Fixing the ABI is a separate issue, but this at least plugs the security +hole. + +Fixes: ba4dc61fe8c5 ("Staging: ipack: add support for IP-OCTAL mezzanine board") +Cc: stable@vger.kernel.org # 3.5 +Acked-by: Samuel Iglesias Gonsalvez +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20210917114622.5412-2-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ipack/devices/ipoctal.c | 19 ++++++++++++++----- + 1 file changed, 14 insertions(+), 5 deletions(-) + +--- a/drivers/ipack/devices/ipoctal.c ++++ b/drivers/ipack/devices/ipoctal.c +@@ -269,7 +269,6 @@ static int ipoctal_inst_slot(struct ipoc + int res; + int i; + struct tty_driver *tty; +- char name[20]; + struct ipoctal_channel *channel; + struct ipack_region *region; + void __iomem *addr; +@@ -360,8 +359,11 @@ static int ipoctal_inst_slot(struct ipoc + /* Fill struct tty_driver with ipoctal data */ + tty->owner = THIS_MODULE; + tty->driver_name = KBUILD_MODNAME; +- sprintf(name, KBUILD_MODNAME ".%d.%d.", bus_nr, slot); +- tty->name = name; ++ tty->name = kasprintf(GFP_KERNEL, KBUILD_MODNAME ".%d.%d.", bus_nr, slot); ++ if (!tty->name) { ++ res = -ENOMEM; ++ goto err_put_driver; ++ } + tty->major = 0; + + tty->minor_start = 0; +@@ -377,8 +379,7 @@ static int ipoctal_inst_slot(struct ipoc + res = tty_register_driver(tty); + if (res) { + dev_err(&ipoctal->dev->dev, "Can't register tty driver.\n"); +- put_tty_driver(tty); +- return res; ++ goto err_free_name; + } + + /* Save struct tty_driver for use it when uninstalling the device */ +@@ -415,6 +416,13 @@ static int ipoctal_inst_slot(struct ipoc + ipoctal_irq_handler, ipoctal); + + return 0; ++ ++err_free_name: ++ kfree(tty->name); ++err_put_driver: ++ put_tty_driver(tty); ++ ++ return res; + } + + static inline int ipoctal_copy_write_buffer(struct ipoctal_channel *channel, +@@ -703,6 +711,7 @@ static void __ipoctal_remove(struct ipoc + } + + tty_unregister_driver(ipoctal->tty_drv); ++ kfree(ipoctal->tty_drv->name); + put_tty_driver(ipoctal->tty_drv); + kfree(ipoctal); + } diff --git a/queue-4.9/ipack-ipoctal-fix-tty-registration-error-handling.patch b/queue-4.9/ipack-ipoctal-fix-tty-registration-error-handling.patch new file mode 100644 index 00000000000..afda523f903 --- /dev/null +++ b/queue-4.9/ipack-ipoctal-fix-tty-registration-error-handling.patch @@ -0,0 +1,56 @@ +From cd20d59291d1790dc74248476e928f57fc455189 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 17 Sep 2021 13:46:19 +0200 +Subject: ipack: ipoctal: fix tty-registration error handling + +From: Johan Hovold + +commit cd20d59291d1790dc74248476e928f57fc455189 upstream. + +Registration of the ipoctal tty devices is unlikely to fail, but if it +ever does, make sure not to deregister a never registered tty device +(and dereference a NULL pointer) when the driver is later unbound. + +Fixes: 2afb41d9d30d ("Staging: ipack/devices/ipoctal: Check tty_register_device return value.") +Cc: stable@vger.kernel.org # 3.7 +Acked-by: Samuel Iglesias Gonsalvez +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20210917114622.5412-4-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ipack/devices/ipoctal.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/ipack/devices/ipoctal.c ++++ b/drivers/ipack/devices/ipoctal.c +@@ -38,6 +38,7 @@ struct ipoctal_channel { + unsigned int pointer_read; + unsigned int pointer_write; + struct tty_port tty_port; ++ bool tty_registered; + union scc2698_channel __iomem *regs; + union scc2698_block __iomem *block_regs; + unsigned int board_id; +@@ -402,9 +403,11 @@ static int ipoctal_inst_slot(struct ipoc + i, NULL, channel, NULL); + if (IS_ERR(tty_dev)) { + dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); ++ tty_port_free_xmit_buf(&channel->tty_port); + tty_port_destroy(&channel->tty_port); + continue; + } ++ channel->tty_registered = true; + } + + /* +@@ -705,6 +708,10 @@ static void __ipoctal_remove(struct ipoc + + for (i = 0; i < NR_CHANNELS; i++) { + struct ipoctal_channel *channel = &ipoctal->channel[i]; ++ ++ if (!channel->tty_registered) ++ continue; ++ + tty_unregister_device(ipoctal->tty_drv, i); + tty_port_free_xmit_buf(&channel->tty_port); + tty_port_destroy(&channel->tty_port); diff --git a/queue-4.9/ipack-ipoctal-fix-tty-registration-race.patch b/queue-4.9/ipack-ipoctal-fix-tty-registration-race.patch new file mode 100644 index 00000000000..ad25f00a5c4 --- /dev/null +++ b/queue-4.9/ipack-ipoctal-fix-tty-registration-race.patch @@ -0,0 +1,40 @@ +From 65c001df517a7bf9be8621b53d43c89f426ce8d6 Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 17 Sep 2021 13:46:18 +0200 +Subject: ipack: ipoctal: fix tty registration race + +From: Johan Hovold + +commit 65c001df517a7bf9be8621b53d43c89f426ce8d6 upstream. + +Make sure to set the tty class-device driver data before registering the +tty to avoid having a racing open() dereference a NULL pointer. + +Fixes: 9c1d784afc6f ("Staging: ipack/devices/ipoctal: Get rid of ipoctal_list.") +Cc: stable@vger.kernel.org # 3.7 +Acked-by: Samuel Iglesias Gonsalvez +Signed-off-by: Johan Hovold +Link: https://lore.kernel.org/r/20210917114622.5412-3-johan@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ipack/devices/ipoctal.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/ipack/devices/ipoctal.c ++++ b/drivers/ipack/devices/ipoctal.c +@@ -398,13 +398,13 @@ static int ipoctal_inst_slot(struct ipoc + spin_lock_init(&channel->lock); + channel->pointer_read = 0; + channel->pointer_write = 0; +- tty_dev = tty_port_register_device(&channel->tty_port, tty, i, NULL); ++ tty_dev = tty_port_register_device_attr(&channel->tty_port, tty, ++ i, NULL, channel, NULL); + if (IS_ERR(tty_dev)) { + dev_err(&ipoctal->dev->dev, "Failed to register tty device.\n"); + tty_port_destroy(&channel->tty_port); + continue; + } +- dev_set_drvdata(tty_dev, channel); + } + + /* diff --git a/queue-4.9/net-udp-annotate-data-race-around-udp_sk-sk-corkflag.patch b/queue-4.9/net-udp-annotate-data-race-around-udp_sk-sk-corkflag.patch new file mode 100644 index 00000000000..11b9c4ddf50 --- /dev/null +++ b/queue-4.9/net-udp-annotate-data-race-around-udp_sk-sk-corkflag.patch @@ -0,0 +1,73 @@ +From a9f5970767d11eadc805d5283f202612c7ba1f59 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Mon, 27 Sep 2021 17:29:24 -0700 +Subject: net: udp: annotate data race around udp_sk(sk)->corkflag + +From: Eric Dumazet + +commit a9f5970767d11eadc805d5283f202612c7ba1f59 upstream. + +up->corkflag field can be read or written without any lock. +Annotate accesses to avoid possible syzbot/KCSAN reports. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/udp.c | 10 +++++----- + net/ipv6/udp.c | 2 +- + 2 files changed, 6 insertions(+), 6 deletions(-) + +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -886,7 +886,7 @@ int udp_sendmsg(struct sock *sk, struct + __be16 dport; + u8 tos; + int err, is_udplite = IS_UDPLITE(sk); +- int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; ++ int corkreq = READ_ONCE(up->corkflag) || msg->msg_flags&MSG_MORE; + int (*getfrag)(void *, char *, int, int, int, struct sk_buff *); + struct sk_buff *skb; + struct ip_options_data opt_copy; +@@ -1167,7 +1167,7 @@ int udp_sendpage(struct sock *sk, struct + } + + up->len += size; +- if (!(up->corkflag || (flags&MSG_MORE))) ++ if (!(READ_ONCE(up->corkflag) || (flags&MSG_MORE))) + ret = udp_push_pending_frames(sk); + if (!ret) + ret = size; +@@ -2034,9 +2034,9 @@ int udp_lib_setsockopt(struct sock *sk, + switch (optname) { + case UDP_CORK: + if (val != 0) { +- up->corkflag = 1; ++ WRITE_ONCE(up->corkflag, 1); + } else { +- up->corkflag = 0; ++ WRITE_ONCE(up->corkflag, 0); + lock_sock(sk); + push_pending_frames(sk); + release_sock(sk); +@@ -2143,7 +2143,7 @@ int udp_lib_getsockopt(struct sock *sk, + + switch (optname) { + case UDP_CORK: +- val = up->corkflag; ++ val = READ_ONCE(up->corkflag); + break; + + case UDP_ENCAP: +--- a/net/ipv6/udp.c ++++ b/net/ipv6/udp.c +@@ -1028,7 +1028,7 @@ int udpv6_sendmsg(struct sock *sk, struc + struct ipcm6_cookie ipc6; + int addr_len = msg->msg_namelen; + int ulen = len; +- int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; ++ int corkreq = READ_ONCE(up->corkflag) || msg->msg_flags&MSG_MORE; + int err; + int connected = 0; + int is_udplite = IS_UDPLITE(sk); diff --git a/queue-4.9/series b/queue-4.9/series index fddc2caf81e..04a1a3b4e19 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -38,3 +38,10 @@ mac80211-limit-injected-vht-mcs-nss-in-ieee80211_par.patch hwmon-tmp421-fix-rounding-for-negative-values.patch e100-fix-length-calculation-in-e100_get_regs_len.patch e100-fix-buffer-overrun-in-e100_get_regs.patch +ipack-ipoctal-fix-stack-information-leak.patch +ipack-ipoctal-fix-tty-registration-race.patch +ipack-ipoctal-fix-tty-registration-error-handling.patch +ipack-ipoctal-fix-missing-allocation-failure-check.patch +ipack-ipoctal-fix-module-reference-leak.patch +ext4-fix-potential-infinite-loop-in-ext4_dx_readdir.patch +net-udp-annotate-data-race-around-udp_sk-sk-corkflag.patch