From: Greg Kroah-Hartman Date: Sat, 24 Apr 2021 14:52:03 +0000 (+0200) Subject: 4.9-stable patches X-Git-Tag: v4.4.268~33 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=049f138027b60ff448eb77433bca6f2f86bbe4bb;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: ext4-correct-error-label-in-ext4_rename.patch net-hso-fix-null-ptr-deref-during-tty-device-unregistration.patch --- diff --git a/queue-4.9/ext4-correct-error-label-in-ext4_rename.patch b/queue-4.9/ext4-correct-error-label-in-ext4_rename.patch new file mode 100644 index 00000000000..ae0ce55c4fc --- /dev/null +++ b/queue-4.9/ext4-correct-error-label-in-ext4_rename.patch @@ -0,0 +1,47 @@ +From yi.zhang@huawei.com Sat Apr 24 16:48:28 2021 +From: Zhang Yi +Date: Fri, 23 Apr 2021 20:37:50 +0800 +Subject: ext4: correct error label in ext4_rename() +To: +Cc: , , , +Message-ID: <20210423123750.1946580-1-yi.zhang@huawei.com> + +From: Zhang Yi + +The backport of upstream patch 5dccdc5a1916 ("ext4: do not iput inode +under running transaction in ext4_rename()") introduced a regression on +the stable kernels 4.14 and older. One of the end_rename error label was +forgetting to change to release_bh, which may trigger below bug. + + ------------[ cut here ]------------ + kernel BUG at /home/zhangyi/hulk-4.4/fs/ext4/ext4_jbd2.c:30! + ... + Call Trace: + [] ext4_rename+0x9e2/0x10c0 + [] ? unlazy_walk+0x124/0x2a0 + [] ext4_rename2+0x25/0x60 + [] vfs_rename+0x3a4/0xed0 + [] SYSC_renameat2+0x57d/0x7f0 + [] SyS_renameat+0x19/0x30 + [] entry_SYSCALL_64_fastpath+0x18/0x78 + ... + ---[ end trace 75346ce7c76b9f06 ]--- + +Fixes: f5337ec530a6 ("ext4: do not iput inode under running transaction in ext4_rename()") +Signed-off-by: Zhang Yi +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/namei.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/ext4/namei.c ++++ b/fs/ext4/namei.c +@@ -3621,7 +3621,7 @@ static int ext4_rename(struct inode *old + ext4_encrypted_inode(new.dir) && + !fscrypt_has_permitted_context(new.dir, old.inode)) { + retval = -EXDEV; +- goto end_rename; ++ goto release_bh; + } + + new.bh = ext4_find_entry(new.dir, &new.dentry->d_name, diff --git a/queue-4.9/net-hso-fix-null-ptr-deref-during-tty-device-unregistration.patch b/queue-4.9/net-hso-fix-null-ptr-deref-during-tty-device-unregistration.patch new file mode 100644 index 00000000000..f0e9c84d1bf --- /dev/null +++ b/queue-4.9/net-hso-fix-null-ptr-deref-during-tty-device-unregistration.patch @@ -0,0 +1,146 @@ +From foo@baz Sat Apr 24 04:46:08 PM CEST 2021 +From: Anirudh Rayabharam +Date: Wed, 7 Apr 2021 22:57:22 +0530 +Subject: net: hso: fix null-ptr-deref during tty device unregistration + +From: Anirudh Rayabharam + +commit 8a12f8836145ffe37e9c8733dce18c22fb668b66 upstream + +Multiple ttys try to claim the same the minor number causing a double +unregistration of the same device. The first unregistration succeeds +but the next one results in a null-ptr-deref. + +The get_free_serial_index() function returns an available minor number +but doesn't assign it immediately. The assignment is done by the caller +later. But before this assignment, calls to get_free_serial_index() +would return the same minor number. + +Fix this by modifying get_free_serial_index to assign the minor number +immediately after one is found to be and rename it to obtain_minor() +to better reflect what it does. Similary, rename set_serial_by_index() +to release_minor() and modify it to free up the minor number of the +given hso_serial. Every obtain_minor() should have corresponding +release_minor() call. + +Fixes: 72dc1c096c705 ("HSO: add option hso driver") +Reported-by: syzbot+c49fe6089f295a05e6f8@syzkaller.appspotmail.com +Tested-by: syzbot+c49fe6089f295a05e6f8@syzkaller.appspotmail.com +Reviewed-by: Greg Kroah-Hartman +Signed-off-by: Anirudh Rayabharam +Signed-off-by: David S. Miller +[sudip: adjust context] +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/hso.c | 33 ++++++++++++--------------------- + 1 file changed, 12 insertions(+), 21 deletions(-) + +--- a/drivers/net/usb/hso.c ++++ b/drivers/net/usb/hso.c +@@ -626,7 +626,7 @@ static struct hso_serial *get_serial_by_ + return serial; + } + +-static int get_free_serial_index(void) ++static int obtain_minor(struct hso_serial *serial) + { + int index; + unsigned long flags; +@@ -634,8 +634,10 @@ static int get_free_serial_index(void) + spin_lock_irqsave(&serial_table_lock, flags); + for (index = 0; index < HSO_SERIAL_TTY_MINORS; index++) { + if (serial_table[index] == NULL) { ++ serial_table[index] = serial->parent; ++ serial->minor = index; + spin_unlock_irqrestore(&serial_table_lock, flags); +- return index; ++ return 0; + } + } + spin_unlock_irqrestore(&serial_table_lock, flags); +@@ -644,15 +646,12 @@ static int get_free_serial_index(void) + return -1; + } + +-static void set_serial_by_index(unsigned index, struct hso_serial *serial) ++static void release_minor(struct hso_serial *serial) + { + unsigned long flags; + + spin_lock_irqsave(&serial_table_lock, flags); +- if (serial) +- serial_table[index] = serial->parent; +- else +- serial_table[index] = NULL; ++ serial_table[serial->minor] = NULL; + spin_unlock_irqrestore(&serial_table_lock, flags); + } + +@@ -2243,6 +2242,7 @@ static int hso_stop_serial_device(struct + static void hso_serial_tty_unregister(struct hso_serial *serial) + { + tty_unregister_device(tty_drv, serial->minor); ++ release_minor(serial); + } + + static void hso_serial_common_free(struct hso_serial *serial) +@@ -2267,25 +2267,23 @@ static int hso_serial_common_create(stru + int rx_size, int tx_size) + { + struct device *dev; +- int minor; + int i; + + tty_port_init(&serial->port); + +- minor = get_free_serial_index(); +- if (minor < 0) ++ if (obtain_minor(serial)) + goto exit2; + + /* register our minor number */ + serial->parent->dev = tty_port_register_device_attr(&serial->port, +- tty_drv, minor, &serial->parent->interface->dev, ++ tty_drv, serial->minor, &serial->parent->interface->dev, + serial->parent, hso_serial_dev_groups); +- if (IS_ERR(serial->parent->dev)) ++ if (IS_ERR(serial->parent->dev)) { ++ release_minor(serial); + goto exit2; ++ } + dev = serial->parent->dev; + +- /* fill in specific data for later use */ +- serial->minor = minor; + serial->magic = HSO_SERIAL_MAGIC; + spin_lock_init(&serial->serial_lock); + serial->num_rx_urbs = num_urbs; +@@ -2678,9 +2676,6 @@ static struct hso_device *hso_create_bul + + serial->write_data = hso_std_serial_write_data; + +- /* and record this serial */ +- set_serial_by_index(serial->minor, serial); +- + /* setup the proc dirs and files if needed */ + hso_log_port(hso_dev); + +@@ -2737,9 +2732,6 @@ struct hso_device *hso_create_mux_serial + serial->shared_int->ref_count++; + mutex_unlock(&serial->shared_int->shared_int_lock); + +- /* and record this serial */ +- set_serial_by_index(serial->minor, serial); +- + /* setup the proc dirs and files if needed */ + hso_log_port(hso_dev); + +@@ -3124,7 +3116,6 @@ static void hso_free_interface(struct us + cancel_work_sync(&serial_table[i]->async_get_intf); + hso_serial_tty_unregister(serial); + kref_put(&serial_table[i]->ref, hso_serial_ref_free); +- set_serial_by_index(i, NULL); + } + } + diff --git a/queue-4.9/series b/queue-4.9/series index 666e9fc827a..50a1b091682 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -25,3 +25,5 @@ usbip-add-sysfs_lock-to-synchronize-sysfs-code-paths.patch usbip-stub-dev-synchronize-sysfs-code-paths.patch usbip-vudc-synchronize-sysfs-code-paths.patch usbip-synchronize-event-handler-with-sysfs-code-paths.patch +net-hso-fix-null-ptr-deref-during-tty-device-unregistration.patch +ext4-correct-error-label-in-ext4_rename.patch