From: Greg Kroah-Hartman Date: Fri, 14 Aug 2015 16:47:04 +0000 (-0700) Subject: 4.1-stable patches X-Git-Tag: v3.10.87~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=46cc3f02a9541e9b77bb69f004dbea9037d39747;p=thirdparty%2Fkernel%2Fstable-queue.git 4.1-stable patches added patches: signal-fix-information-leak-in-copy_siginfo_from_user32.patch signal-fix-information-leak-in-copy_siginfo_to_user.patch signalfd-fix-information-leak-in-signalfd_copyinfo.patch --- diff --git a/queue-4.1/series b/queue-4.1/series index d6d7f78831b..ece08e70bb9 100644 --- a/queue-4.1/series +++ b/queue-4.1/series @@ -77,3 +77,6 @@ mtd-nand-fix-nand_use_bounce_buffer-flag-conflict.patch input-alps-only-dell-laptops-have-separate-button-bits-for-v2-dualpoint-sticks.patch thermal-exynos-disable-the-regulator-on-probe-failure.patch mm-vmscan-do-not-wait-for-page-writeback-for-gfp_nofs-allocations.patch +signalfd-fix-information-leak-in-signalfd_copyinfo.patch +signal-fix-information-leak-in-copy_siginfo_to_user.patch +signal-fix-information-leak-in-copy_siginfo_from_user32.patch diff --git a/queue-4.1/signal-fix-information-leak-in-copy_siginfo_from_user32.patch b/queue-4.1/signal-fix-information-leak-in-copy_siginfo_from_user32.patch new file mode 100644 index 00000000000..504f3557c77 --- /dev/null +++ b/queue-4.1/signal-fix-information-leak-in-copy_siginfo_from_user32.patch @@ -0,0 +1,117 @@ +From 3c00cb5e68dc719f2fc73a33b1b230aadfcb1309 Mon Sep 17 00:00:00 2001 +From: Amanieu d'Antras +Date: Thu, 6 Aug 2015 15:46:26 -0700 +Subject: signal: fix information leak in copy_siginfo_from_user32 + +From: Amanieu d'Antras + +commit 3c00cb5e68dc719f2fc73a33b1b230aadfcb1309 upstream. + +This function can leak kernel stack data when the user siginfo_t has a +positive si_code value. The top 16 bits of si_code descibe which fields +in the siginfo_t union are active, but they are treated inconsistently +between copy_siginfo_from_user32, copy_siginfo_to_user32 and +copy_siginfo_to_user. + +copy_siginfo_from_user32 is called from rt_sigqueueinfo and +rt_tgsigqueueinfo in which the user has full control overthe top 16 bits +of si_code. + +This fixes the following information leaks: +x86: 8 bytes leaked when sending a signal from a 32-bit process to + itself. This leak grows to 16 bytes if the process uses x32. + (si_code = __SI_CHLD) +x86: 100 bytes leaked when sending a signal from a 32-bit process to + a 64-bit process. (si_code = -1) +sparc: 4 bytes leaked when sending a signal from a 32-bit process to a + 64-bit process. (si_code = any) + +parsic and s390 have similar bugs, but they are not vulnerable because +rt_[tg]sigqueueinfo have checks that prevent sending a positive si_code +to a different process. These bugs are also fixed for consistency. + +Signed-off-by: Amanieu d'Antras +Cc: Oleg Nesterov +Cc: Ingo Molnar +Cc: Russell King +Cc: Ralf Baechle +Cc: Benjamin Herrenschmidt +Cc: Chris Metcalf +Cc: Paul Mackerras +Cc: Michael Ellerman +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/kernel/signal32.c | 2 -- + arch/mips/kernel/signal32.c | 2 -- + arch/powerpc/kernel/signal_32.c | 2 -- + arch/tile/kernel/compat_signal.c | 2 -- + kernel/signal.c | 4 ++-- + 5 files changed, 2 insertions(+), 10 deletions(-) + +--- a/arch/arm64/kernel/signal32.c ++++ b/arch/arm64/kernel/signal32.c +@@ -202,8 +202,6 @@ int copy_siginfo_to_user32(compat_siginf + + int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) + { +- memset(to, 0, sizeof *to); +- + if (copy_from_user(to, from, __ARCH_SI_PREAMBLE_SIZE) || + copy_from_user(to->_sifields._pad, + from->_sifields._pad, SI_PAD_SIZE)) +--- a/arch/mips/kernel/signal32.c ++++ b/arch/mips/kernel/signal32.c +@@ -409,8 +409,6 @@ int copy_siginfo_to_user32(compat_siginf + + int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) + { +- memset(to, 0, sizeof *to); +- + if (copy_from_user(to, from, 3*sizeof(int)) || + copy_from_user(to->_sifields._pad, + from->_sifields._pad, SI_PAD_SIZE32)) +--- a/arch/powerpc/kernel/signal_32.c ++++ b/arch/powerpc/kernel/signal_32.c +@@ -966,8 +966,6 @@ int copy_siginfo_to_user32(struct compat + + int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from) + { +- memset(to, 0, sizeof *to); +- + if (copy_from_user(to, from, 3*sizeof(int)) || + copy_from_user(to->_sifields._pad, + from->_sifields._pad, SI_PAD_SIZE32)) +--- a/arch/tile/kernel/compat_signal.c ++++ b/arch/tile/kernel/compat_signal.c +@@ -113,8 +113,6 @@ int copy_siginfo_from_user32(siginfo_t * + if (!access_ok(VERIFY_READ, from, sizeof(struct compat_siginfo))) + return -EFAULT; + +- memset(to, 0, sizeof(*to)); +- + err = __get_user(to->si_signo, &from->si_signo); + err |= __get_user(to->si_errno, &from->si_errno); + err |= __get_user(to->si_code, &from->si_code); +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -3025,7 +3025,7 @@ COMPAT_SYSCALL_DEFINE3(rt_sigqueueinfo, + int, sig, + struct compat_siginfo __user *, uinfo) + { +- siginfo_t info; ++ siginfo_t info = {}; + int ret = copy_siginfo_from_user32(&info, uinfo); + if (unlikely(ret)) + return ret; +@@ -3069,7 +3069,7 @@ COMPAT_SYSCALL_DEFINE4(rt_tgsigqueueinfo + int, sig, + struct compat_siginfo __user *, uinfo) + { +- siginfo_t info; ++ siginfo_t info = {}; + + if (copy_siginfo_from_user32(&info, uinfo)) + return -EFAULT; diff --git a/queue-4.1/signal-fix-information-leak-in-copy_siginfo_to_user.patch b/queue-4.1/signal-fix-information-leak-in-copy_siginfo_to_user.patch new file mode 100644 index 00000000000..97e1a73e995 --- /dev/null +++ b/queue-4.1/signal-fix-information-leak-in-copy_siginfo_to_user.patch @@ -0,0 +1,63 @@ +From 26135022f85105ad725cda103fa069e29e83bd16 Mon Sep 17 00:00:00 2001 +From: Amanieu d'Antras +Date: Thu, 6 Aug 2015 15:46:29 -0700 +Subject: signal: fix information leak in copy_siginfo_to_user + +From: Amanieu d'Antras + +commit 26135022f85105ad725cda103fa069e29e83bd16 upstream. + +This function may copy the si_addr_lsb, si_lower and si_upper fields to +user mode when they haven't been initialized, which can leak kernel +stack data to user mode. + +Just checking the value of si_code is insufficient because the same +si_code value is shared between multiple signals. This is solved by +checking the value of si_signo in addition to si_code. + +Signed-off-by: Amanieu d'Antras +Cc: Oleg Nesterov +Cc: Ingo Molnar +Cc: Russell King +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm64/kernel/signal32.c | 3 ++- + kernel/signal.c | 9 ++++++--- + 2 files changed, 8 insertions(+), 4 deletions(-) + +--- a/arch/arm64/kernel/signal32.c ++++ b/arch/arm64/kernel/signal32.c +@@ -168,7 +168,8 @@ int copy_siginfo_to_user32(compat_siginf + * Other callers might not initialize the si_lsb field, + * so check explicitely for the right codes here. + */ +- if (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO) ++ if (from->si_signo == SIGBUS && ++ (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO)) + err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb); + #endif + break; +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -2753,12 +2753,15 @@ int copy_siginfo_to_user(siginfo_t __use + * Other callers might not initialize the si_lsb field, + * so check explicitly for the right codes here. + */ +- if (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO) ++ if (from->si_signo == SIGBUS && ++ (from->si_code == BUS_MCEERR_AR || from->si_code == BUS_MCEERR_AO)) + err |= __put_user(from->si_addr_lsb, &to->si_addr_lsb); + #endif + #ifdef SEGV_BNDERR +- err |= __put_user(from->si_lower, &to->si_lower); +- err |= __put_user(from->si_upper, &to->si_upper); ++ if (from->si_signo == SIGSEGV && from->si_code == SEGV_BNDERR) { ++ err |= __put_user(from->si_lower, &to->si_lower); ++ err |= __put_user(from->si_upper, &to->si_upper); ++ } + #endif + break; + case __SI_CHLD: diff --git a/queue-4.1/signalfd-fix-information-leak-in-signalfd_copyinfo.patch b/queue-4.1/signalfd-fix-information-leak-in-signalfd_copyinfo.patch new file mode 100644 index 00000000000..c7fbba1bff2 --- /dev/null +++ b/queue-4.1/signalfd-fix-information-leak-in-signalfd_copyinfo.patch @@ -0,0 +1,41 @@ +From 3ead7c52bdb0ab44f4bb1feed505a8323cc12ba7 Mon Sep 17 00:00:00 2001 +From: Amanieu d'Antras +Date: Thu, 6 Aug 2015 15:46:33 -0700 +Subject: signalfd: fix information leak in signalfd_copyinfo + +From: Amanieu d'Antras + +commit 3ead7c52bdb0ab44f4bb1feed505a8323cc12ba7 upstream. + +This function may copy the si_addr_lsb field to user mode when it hasn't +been initialized, which can leak kernel stack data to user mode. + +Just checking the value of si_code is insufficient because the same +si_code value is shared between multiple signals. This is solved by +checking the value of si_signo in addition to si_code. + +Signed-off-by: Amanieu d'Antras +Cc: Oleg Nesterov +Cc: Ingo Molnar +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + fs/signalfd.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/signalfd.c ++++ b/fs/signalfd.c +@@ -121,8 +121,9 @@ static int signalfd_copyinfo(struct sign + * Other callers might not initialize the si_lsb field, + * so check explicitly for the right codes here. + */ +- if (kinfo->si_code == BUS_MCEERR_AR || +- kinfo->si_code == BUS_MCEERR_AO) ++ if (kinfo->si_signo == SIGBUS && ++ (kinfo->si_code == BUS_MCEERR_AR || ++ kinfo->si_code == BUS_MCEERR_AO)) + err |= __put_user((short) kinfo->si_addr_lsb, + &uinfo->ssi_addr_lsb); + #endif