From f270a5e1e41ed2883b76bc386c6489544f00dc5f Mon Sep 17 00:00:00 2001 From: Josh Boyer Date: Wed, 20 Jan 2016 08:32:28 -0500 Subject: [PATCH] CVE-2016-0723 memory disclosure and crash in tty layer (rhbz 1296253 1300224) --- kernel.spec | 4 ++ ...e-ldisc-reference-via-ioctl-TIOCGETD.patch | 68 +++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 tty-Fix-unsafe-ldisc-reference-via-ioctl-TIOCGETD.patch diff --git a/kernel.spec b/kernel.spec index 5d0ad68c9..07be31ea5 100644 --- a/kernel.spec +++ b/kernel.spec @@ -609,6 +609,9 @@ Patch634: KEYS-Fix-keyring-ref-leak-in-join_session_keyring.patch #CVE-2013-4312 rhbz 1297813 1300216 Patch636: unix-properly-account-for-FDs-passed-over-unix-socke.patch +#CVE-2016-0723 rhbz 1296253 1300224 +Patch637: tty-Fix-unsafe-ldisc-reference-via-ioctl-TIOCGETD.patch + # END OF PATCH DEFINITIONS %endif @@ -2053,6 +2056,7 @@ fi # %changelog * Wed Jan 20 2016 Josh Boyer +- CVE-2016-0723 memory disclosure and crash in tty layer (rhbz 1296253 1300224) - CVE-2013-4312 file descr passed over unix sockects not properly accounted (rhbz 1297813 1300216) * Tue Jan 19 2016 Josh Boyer diff --git a/tty-Fix-unsafe-ldisc-reference-via-ioctl-TIOCGETD.patch b/tty-Fix-unsafe-ldisc-reference-via-ioctl-TIOCGETD.patch new file mode 100644 index 000000000..d169105db --- /dev/null +++ b/tty-Fix-unsafe-ldisc-reference-via-ioctl-TIOCGETD.patch @@ -0,0 +1,68 @@ +From 938f50fc744cb49892bd42c8f56bdfa63e82a27d Mon Sep 17 00:00:00 2001 +From: Peter Hurley +Date: Sun, 10 Jan 2016 22:40:55 -0800 +Subject: [PATCH] tty: Fix unsafe ldisc reference via ioctl(TIOCGETD) + +ioctl(TIOCGETD) retrieves the line discipline id directly from the +ldisc because the line discipline id (c_line) in termios is untrustworthy; +userspace may have set termios via ioctl(TCSETS*) without actually +changing the line discipline via ioctl(TIOCSETD). + +However, directly accessing the current ldisc via tty->ldisc is +unsafe; the ldisc ptr dereferenced may be stale if the line discipline +is changing via ioctl(TIOCSETD) or hangup. + +Wait for the line discipline reference (just like read() or write()) +to retrieve the "current" line discipline id. + +Cc: +Signed-off-by: Peter Hurley +--- + drivers/tty/tty_io.c | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) + +diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c +index f435977de740..bd4027e36910 100644 +--- a/drivers/tty/tty_io.c ++++ b/drivers/tty/tty_io.c +@@ -2654,6 +2654,28 @@ static int tiocsetd(struct tty_struct *tty, int __user *p) + } + + /** ++ * tiocgetd - get line discipline ++ * @tty: tty device ++ * @p: pointer to user data ++ * ++ * Retrieves the line discipline id directly from the ldisc. ++ * ++ * Locking: waits for ldisc reference (in case the line discipline ++ * is changing or the tty is being hungup) ++ */ ++ ++static int tiocgetd(struct tty_struct *tty, int __user *p) ++{ ++ struct tty_ldisc *ld; ++ int ret; ++ ++ ld = tty_ldisc_ref_wait(tty); ++ ret = put_user(ld->ops->num, p); ++ tty_ldisc_deref(ld); ++ return ret; ++} ++ ++/** + * send_break - performed time break + * @tty: device to break on + * @duration: timeout in mS +@@ -2879,7 +2901,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg) + case TIOCGSID: + return tiocgsid(tty, real_tty, p); + case TIOCGETD: +- return put_user(tty->ldisc->ops->num, (int __user *)p); ++ return tiocgetd(tty, p); + case TIOCSETD: + return tiocsetd(tty, p); + case TIOCVHANGUP: +-- +2.5.0 +