[PATCH OLK-6.6 0/3] fix CVE-2026-98751
fix CVE-2026-98751 Gu Bowen (1): tty: Fix kabi breakage of tty_struct Johan Hovold (2): tty: abort break signalling on hangup tty: add break_wait kernel-doc drivers/tty/tty_io.c | 36 +++++++++++++++++++++++++++--------- include/linux/tty.h | 5 +++++ 2 files changed, 32 insertions(+), 9 deletions(-) -- 2.43.0
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://atomgit.com/openeuler/kernel/merge_requests/30614 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/2LX... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://atomgit.com/openeuler/kernel/merge_requests/30614 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/2LX...
From: Johan Hovold <johan@kernel.org> stable inclusion from stable-v6.6.160 commit 6c9c9367351a461d62e5c0a39bffdcfbb40f068b category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/20415 CVE: CVE-2026-98751 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- commit 845a2737e0f5ffe5ca8d38de556012b0c9472cdd upstream. The break ioctls can race with hangup and end up calling into a tty driver for a device that is already gone or powered down. Drivers must handle this race, but TCSBRK and TCSBRKP should still be aborted to avoid calling back into the driver after a user-controlled timeout (possibly even after the tty has been reopened). Note that drivers should disable any break state on shutdown so just return on hangup (calling break_ctl() again is racy and will most likely fail for drivers handling the race). Fixes: f34d7a5b7010 ("tty: The big operations rework") Cc: stable <stable@kernel.org> Signed-off-by: Johan Hovold <johan@kernel.org> Link: https://patch.msgid.link/20260903163736.1499280-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Gu Bowen <gubowen5@huawei.com> --- drivers/tty/tty_io.c | 36 +++++++++++++++++++++++++++--------- include/linux/tty.h | 1 + 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index c1cffb241407..817370cc4165 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -629,6 +629,8 @@ static void __tty_hangup(struct tty_struct *tty, int exit_session) tty_ldisc_hangup(tty, cons_filp != NULL); + wake_up_interruptible(&tty->break_wait); + spin_lock_irq(&tty->ctrl.lock); clear_bit(TTY_THROTTLED, &tty->flags); clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); @@ -2460,6 +2462,7 @@ static int tiocgetd(struct tty_struct *tty, int __user *p) * send_break - performed time break * @tty: device to break on * @duration: timeout in mS + * @file: file object * * Perform a timed break on hardware that lacks its own driver level timed * break functionality. @@ -2467,8 +2470,9 @@ static int tiocgetd(struct tty_struct *tty, int __user *p) * Locking: * @tty->atomic_write_lock serializes */ -static int send_break(struct tty_struct *tty, unsigned int duration) +static int send_break(struct file *file, struct tty_struct *tty, unsigned int duration) { + long timeout; int retval; if (tty->ops->break_ctl == NULL) @@ -2482,13 +2486,26 @@ static int send_break(struct tty_struct *tty, unsigned int duration) return -EINTR; retval = tty->ops->break_ctl(tty, -1); - if (!retval) { - msleep_interruptible(duration); - retval = tty->ops->break_ctl(tty, 0); - } else if (retval == -EOPNOTSUPP) { - /* some drivers can tell only dynamically */ - retval = 0; + if (retval) { + if (retval == -EOPNOTSUPP) { + /* some drivers can tell only dynamically */ + retval = 0; + } + goto out_unlock; + } + + timeout = msecs_to_jiffies(duration); + timeout = wait_event_interruptible_timeout(tty->break_wait, + tty_hung_up_p(file), + timeout); + /* return early on hangup only */ + if (timeout > 0) { + retval = -EIO; + goto out_unlock; } + + retval = tty->ops->break_ctl(tty, 0); +out_unlock: tty_write_unlock(tty); if (signal_pending(current)) @@ -2741,10 +2758,10 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) * This is used by the tcdrain() termios function. */ if (!arg) - return send_break(tty, 250); + return send_break(file, tty, 250); return 0; case TCSBRKP: /* support for POSIX tcsendbreak() */ - return send_break(tty, arg ? arg*100 : 250); + return send_break(file, tty, arg ? arg * 100 : 250); case TIOCMGET: return tty_tiocmget(tty, p); @@ -3107,6 +3124,7 @@ struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx) init_ldsem(&tty->ldisc_sem); init_waitqueue_head(&tty->write_wait); init_waitqueue_head(&tty->read_wait); + init_waitqueue_head(&tty->break_wait); INIT_WORK(&tty->hangup_work, do_tty_hangup); mutex_init(&tty->atomic_write_lock); spin_lock_init(&tty->ctrl.lock); diff --git a/include/linux/tty.h b/include/linux/tty.h index daddeca8737e..707e42df85fe 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -238,6 +238,7 @@ struct tty_struct { struct fasync_struct *fasync; wait_queue_head_t write_wait; wait_queue_head_t read_wait; + wait_queue_head_t break_wait; struct work_struct hangup_work; void *disc_data; void *driver_data; -- 2.43.0
From: Johan Hovold <johan@kernel.org> stable inclusion from stable-v6.6.160 commit 6c9c9367351a461d62e5c0a39bffdcfbb40f068b category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/20415 CVE: CVE-2026-98751 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- Add the missing kernel-doc description for the new break_wait field in struct tty_struct. Fixes: 845a2737e0f5 ("tty: abort break signalling on hangup") Reported-by: Randy Dunlap <rdunlap@infradead.org> Link: https://lore.kernel.org/20d75a7a-2e7a-484f-a267-c21db82dd922@infradead.org Signed-off-by: Johan Hovold <johan@kernel.org> Link: https://patch.msgid.link/20260925094222.18303-1-johan@kernel.org Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Gu Bowen <gubowen5@huawei.com> --- include/linux/tty.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/tty.h b/include/linux/tty.h index 707e42df85fe..803a63cad60e 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -174,6 +174,7 @@ struct tty_operations; * @write_wait: concurrent writers are waiting in this queue until they are * allowed to write * @read_wait: readers wait for data in this queue + * @break_wait: wait queue for timed breaks * @hangup_work: normally a work to perform a hangup (do_tty_hangup()); while * freeing the tty, (re)used to release_one_tty() * @disc_data: pointer to @ldisc's private data (e.g. to &struct n_tty_data) -- 2.43.0
hulk inclusion category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/20415 CVE: CVE-2026-98751 -------------------------------- Commit "tty: abort break signalling on hangup" adds a new variable, wait_queue_head_t break_wait, to the tty_struct structure, which causes a KABI change. This issue is resolved by using the reserved KABI. Fixes: 6c9c9367351a ("tty: abort break signalling on hangup") Signed-off-by: Gu Bowen <gubowen5@huawei.com> --- include/linux/tty.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/tty.h b/include/linux/tty.h index 803a63cad60e..807e02c47284 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -239,7 +239,6 @@ struct tty_struct { struct fasync_struct *fasync; wait_queue_head_t write_wait; wait_queue_head_t read_wait; - wait_queue_head_t break_wait; struct work_struct hangup_work; void *disc_data; void *driver_data; @@ -251,9 +250,13 @@ struct tty_struct { #define N_TTY_BUF_SIZE 4096 struct work_struct SAK_work; +#ifndef __GENKSYMS__ + wait_queue_head_t break_wait; +#else KABI_RESERVE(0) KABI_RESERVE(1) KABI_RESERVE(2) +#endif KABI_RESERVE(3) KABI_RESERVE(4) KABI_RESERVE(5) -- 2.43.0
participants (2)
-
Gu Bowen -
patchwork bot