]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Oct 2021 09:56:31 +0000 (11:56 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 4 Oct 2021 09:56:31 +0000 (11:56 +0200)
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

queue-4.4/ext4-fix-potential-infinite-loop-in-ext4_dx_readdir.patch [new file with mode: 0644]
queue-4.4/ipack-ipoctal-fix-missing-allocation-failure-check.patch [new file with mode: 0644]
queue-4.4/ipack-ipoctal-fix-module-reference-leak.patch [new file with mode: 0644]
queue-4.4/ipack-ipoctal-fix-stack-information-leak.patch [new file with mode: 0644]
queue-4.4/ipack-ipoctal-fix-tty-registration-error-handling.patch [new file with mode: 0644]
queue-4.4/ipack-ipoctal-fix-tty-registration-race.patch [new file with mode: 0644]
queue-4.4/series

diff --git a/queue-4.4/ext4-fix-potential-infinite-loop-in-ext4_dx_readdir.patch b/queue-4.4/ext4-fix-potential-infinite-loop-in-ext4_dx_readdir.patch
new file mode 100644 (file)
index 0000000..61fcc31
--- /dev/null
@@ -0,0 +1,68 @@
+From 42cb447410d024e9d54139ae9c21ea132a8c384c Mon Sep 17 00:00:00 2001
+From: yangerkun <yangerkun@huawei.com>
+Date: Tue, 14 Sep 2021 19:14:15 +0800
+Subject: ext4: fix potential infinite loop in ext4_dx_readdir()
+
+From: yangerkun <yangerkun@huawei.com>
+
+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 <yangerkun@huawei.com>
+Reviewed-by: Jan Kara <jack@suse.cz>
+Signed-off-by: Theodore Ts'o <tytso@mit.edu>
+Link: https://lore.kernel.org/r/20210914111415.3921954-1-yangerkun@huawei.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ext4/dir.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/fs/ext4/dir.c
++++ b/fs/ext4/dir.c
+@@ -521,7 +521,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);
+@@ -569,7 +569,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;
+@@ -600,7 +600,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.4/ipack-ipoctal-fix-missing-allocation-failure-check.patch b/queue-4.4/ipack-ipoctal-fix-missing-allocation-failure-check.patch
new file mode 100644 (file)
index 0000000..ddeb399
--- /dev/null
@@ -0,0 +1,36 @@
+From 445c8132727728dc297492a7d9fc074af3e94ba3 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 17 Sep 2021 13:46:20 +0200
+Subject: ipack: ipoctal: fix missing allocation-failure check
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <siglesias@igalia.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20210917114622.5412-5-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.4/ipack-ipoctal-fix-module-reference-leak.patch b/queue-4.4/ipack-ipoctal-fix-module-reference-leak.patch
new file mode 100644 (file)
index 0000000..13b2921
--- /dev/null
@@ -0,0 +1,79 @@
+From bb8a4fcb2136508224c596a7e665bdba1d7c3c27 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 17 Sep 2021 13:46:21 +0200
+Subject: ipack: ipoctal: fix module reference leak
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <federico.vaga@cern.ch>
+Acked-by: Samuel Iglesias Gonsalvez <siglesias@igalia.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20210917114622.5412-6-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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)
+@@ -669,6 +681,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.4/ipack-ipoctal-fix-stack-information-leak.patch b/queue-4.4/ipack-ipoctal-fix-stack-information-leak.patch
new file mode 100644 (file)
index 0000000..3176fe2
--- /dev/null
@@ -0,0 +1,86 @@
+From a89936cce87d60766a75732a9e7e25c51164f47c Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 17 Sep 2021 13:46:17 +0200
+Subject: ipack: ipoctal: fix stack information leak
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <siglesias@igalia.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20210917114622.5412-2-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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,
+@@ -704,6 +712,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.4/ipack-ipoctal-fix-tty-registration-error-handling.patch b/queue-4.4/ipack-ipoctal-fix-tty-registration-error-handling.patch
new file mode 100644 (file)
index 0000000..9a86aad
--- /dev/null
@@ -0,0 +1,56 @@
+From cd20d59291d1790dc74248476e928f57fc455189 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 17 Sep 2021 13:46:19 +0200
+Subject: ipack: ipoctal: fix tty-registration error handling
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <siglesias@igalia.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20210917114622.5412-4-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+       }
+       /*
+@@ -706,6 +709,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.4/ipack-ipoctal-fix-tty-registration-race.patch b/queue-4.4/ipack-ipoctal-fix-tty-registration-race.patch
new file mode 100644 (file)
index 0000000..ad25f00
--- /dev/null
@@ -0,0 +1,40 @@
+From 65c001df517a7bf9be8621b53d43c89f426ce8d6 Mon Sep 17 00:00:00 2001
+From: Johan Hovold <johan@kernel.org>
+Date: Fri, 17 Sep 2021 13:46:18 +0200
+Subject: ipack: ipoctal: fix tty registration race
+
+From: Johan Hovold <johan@kernel.org>
+
+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 <siglesias@igalia.com>
+Signed-off-by: Johan Hovold <johan@kernel.org>
+Link: https://lore.kernel.org/r/20210917114622.5412-3-johan@kernel.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+       }
+       /*
index 304e4a7887ba1c288fb0390fb03e3aafacc1f2ae..85f24b17ad2ecb9d397e1d77b4cc07849c110f93 100644 (file)
@@ -27,3 +27,9 @@ mac80211-fix-use-after-free-in-ccmp-gcmp-rx.patch
 ipvs-check-that-ip_vs_conn_tab_bits-is-between-8-and.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