Patch "sparc: Harden signal return frame checks." has been added to the 4.4-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
sparc: Harden signal return frame checks.
to the 4.4-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
sparc-harden-signal-return-frame-checks.patch
and it can be found in the queue-4.4 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Mon Jun 20 10:48:29 PDT 2016
From: "David S. Miller" <[email protected]>
Date: Sat, 28 May 2016 21:21:31 -0700
Subject: sparc: Harden signal return frame checks.
From: "David S. Miller" <[email protected]>
[ Upstream commit d11c2a0de2824395656cf8ed15811580c9dd38aa ]
All signal frames must be at least 16-byte aligned, because that is the alignment we explicitly create when we build signal return stack frames.
All stack pointers must be at least 8-byte aligned.
--- arch/sparc/kernel/signal32.c | 46 ++++++++++++++++++++++++++--------------- arch/sparc/kernel/signal_32.c | 41 +++++++++++++++++++++++------------- arch/sparc/kernel/signal_64.c | 31 +++++++++++++++++---------- arch/sparc/kernel/sigutil_32.c | 9 +++++++- arch/sparc/kernel/sigutil_64.c | 10 +++++++- 5 files changed, 92 insertions(+), 45 deletions(-)
arch/sparc/kernel/signal32.c +30 -16
@@ -138,12 +138,24 @@ int copy_siginfo_from_user32(siginfo_t *return 0 ; } +/* Checks if the fp is valid. We always build signal frames which are +* 16-byte aligned, therefore we can always enforce that the restore +* frame has that property as well. +*/ +static bool invalid_frame_pointer (void __user *fp,int fplen) +{ +if ((((unsigned long ) fp) &15 ) || + ((unsigned long )fp) >0x100000000ULL - fplen) +return true; +return false; +} +void do_sigreturn32 (struct pt_regs *regs) {struct signal_frame32 __user *sf;compat_uptr_t fpu_save;compat_uptr_t rwin_save; -unsigned int psr; +unsigned int psr, ufp;unsigned pc, npc;sigset_t set;compat_sigset_t seta;
@@ -158,11 +170,16 @@ void do_sigreturn32(struct pt_regs *regs sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP ];/* 1. Make sure we are not getting garbage from the user */ -if (!access_ok (VERIFY_READ , sf,sizeof (*sf)) || - (((unsigned long ) sf) &3 )) +if (invalid_frame_pointer (sf,sizeof (*sf))) + goto segv; + +if (get_user (ufp, &sf->info.si_regs.u_regs[UREG_FP ])) + goto segv; + +if (ufp &0x7 ) goto segv; -if (get_user (pc, &sf->info.si_regs.pc) || +if (__get_user (pc, &sf->info.si_regs.pc) ||__get_user (npc, &sf->info.si_regs.npc)) goto segv;
@@ -227,7 +244,7 @@ segv: asmlinkage void do_rt_sigreturn32(struct pt_regs *regs) {struct rt_signal_frame32 __user *sf; -unsigned int psr, pc, npc; +unsigned int psr, pc, npc, ufp;compat_uptr_t fpu_save;compat_uptr_t rwin_save;sigset_t set;
@@ -242,11 +259,16 @@ asmlinkage void do_rt_sigreturn32(struct sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP ];/* 1. Make sure we are not getting garbage from the user */ -if (!access_ok (VERIFY_READ , sf,sizeof (*sf)) || - (((unsigned long ) sf) &3 )) +if (invalid_frame_pointer (sf,sizeof (*sf))) goto segv; -if (get_user (pc, &sf->regs.pc) || +if (get_user (ufp, &sf->regs.u_regs[UREG_FP ])) + goto segv; + +if (ufp &0x7 ) + goto segv; + +if (__get_user (pc, &sf->regs.pc) ||__get_user (npc, &sf->regs.npc)) goto segv;
@@ -307,14 +329,6 @@ segv:force_sig (SIGSEGV , current); } -/* Checks if the fp is valid */ -static int invalid_frame_pointer (void __user *fp,int fplen) -{ -if ((((unsigned long ) fp) &7 ) || ((unsigned long )fp) >0x100000000ULL - fplen) -return 1 ; -return 0 ; -} -static void __user *get_sigframe (struct ksignal *ksig,struct pt_regs *regs,unsigned long framesize) {unsigned long sp;
arch/sparc/kernel/signal_32.c +26 -15
76 lines not on this page · raw message
arch/sparc/kernel/signal_64.c +20 -11
@@ -234,6 +234,17 @@ do_sigsegv: goto out; } +/* Checks if the fp is valid. We always build rt signal frames which +* are 16-byte aligned, therefore we can always enforce that the +* restore frame has that property as well. +*/ +static bool invalid_frame_pointer (void __user *fp) +{ +if (((unsigned long ) fp) &15 ) +return true; +return false; +} +struct rt_signal_frame {struct sparc_stackf ss;siginfo_t info;
@@ -246,8 +257,8 @@ struct rt_signal_frame {void do_rt_sigreturn (struct pt_regs *regs) { +unsigned long tpc, tnpc, tstate, ufp;struct rt_signal_frame __user *sf; -unsigned long tpc, tnpc, tstate;__siginfo_fpu_t __user *fpu_save;__siginfo_rwin_t __user *rwin_save;sigset_t set;
@@ -261,10 +272,16 @@ void do_rt_sigreturn(struct pt_regs *reg (regs->u_regs [UREG_FP ] +STACK_BIAS );/* 1. Make sure we are not getting garbage from the user */ -if (((unsigned long ) sf) &3 ) +if (invalid_frame_pointer (sf)) + goto segv; + +if (get_user (ufp, &sf->regs.u_regs[UREG_FP ])) goto segv; - err =get_user (tpc, &sf->regs.tpc); +if ((ufp +STACK_BIAS ) &0x7 ) + goto segv; + + err =__get_user (tpc, &sf->regs.tpc); err |=__get_user (tnpc, &sf->regs.tnpc);if (test_thread_flag (TIF_32BIT )) { tpc &=0xffffffff ;
@@ -308,14 +325,6 @@ segv:force_sig (SIGSEGV , current); } -/* Checks if the fp is valid */ -static int invalid_frame_pointer (void __user *fp) -{ -if (((unsigned long ) fp) &15 ) -return 1 ; -return 0 ; -} -static inline void __user *get_sigframe (struct ksignal *ksig,struct pt_regs *regs,unsigned long framesize) {unsigned long sp = regs->u_regs[UREG_FP ] +STACK_BIAS ;
arch/sparc/kernel/sigutil_32.c +8 -1
@@ -48,6 +48,10 @@ int save_fpu_state(struct pt_regs *regs,int restore_fpu_state (struct pt_regs *regs,__siginfo_fpu_t __user *fpu) {int err; + +if (((unsigned long ) fpu) &3 ) +return -EFAULT ; +#ifdef CONFIG_SMP if (test_tsk_thread_flag (current,TIF_USEDFPU )) regs->psr &= ~PSR_EF ;
@@ -97,7 +101,10 @@ int restore_rwin_state(__siginfo_rwin_tstruct thread_info *t =current_thread_info ();int i, wsaved, err; -__get_user (wsaved, &rp->wsaved); +if (((unsigned long ) rp) &3 ) +return -EFAULT ; + +get_user (wsaved, &rp->wsaved);if (wsaved >NSWINS )return -EFAULT ;
arch/sparc/kernel/sigutil_64.c +8 -2
@@ -37,7 +37,10 @@ int restore_fpu_state(struct pt_regs *reunsigned long fprs;int err; - err =__get_user (fprs, &fpu->si_fprs); +if (((unsigned long ) fpu) &7 ) +return -EFAULT ; + + err =get_user (fprs, &fpu->si_fprs);fprs_write (0 ); regs->tstate &= ~TSTATE_PEF ;if (fprs &FPRS_DL )
@@ -72,7 +75,10 @@ int restore_rwin_state(__siginfo_rwin_tstruct thread_info *t =current_thread_info ();int i, wsaved, err; -__get_user (wsaved, &rp->wsaved); +if (((unsigned long ) rp) &7 ) +return -EFAULT ; + +get_user (wsaved, &rp->wsaved);if (wsaved >NSWINS )return -EFAULT ;
Patches currently in stable-queue which might be from [email protected] are
queue-4.4/sparc64-fix-bootup-regressions-on-some-kconfig-combinations.patch queue-4.4/bpf-inode-disallow-userns-mounts.patch queue-4.4/vxlan-accept-user-specified-mtu-value-when-create-new-vxlan-link.patch queue-4.4/sfc-on-mc-reset-clear-pio-buffer-linkage-in-txqs.patch queue-4.4/ipv6-skip-xfrm-lookup-if-dst_entry-in-socket-cache-is-valid.patch queue-4.4/l2tp-fix-configuration-passed-to-setup_udp_tunnel_sock.patch queue-4.4/switchdev-pass-pointer-to-fib_info-instead-of-copy.patch queue-4.4/vxlan-relax-mtu-constraints.patch queue-4.4/sparc-fix-system-call-tracing-register-handling.patch queue-4.4/vxlan-gre-geneve-set-a-large-mtu-on-ovs-created-tunnel-devices.patch queue-4.4/tcp-record-tlp-and-er-timer-stats-in-v6-stats.patch queue-4.4/sparc64-fix-return-from-trap-window-fill-crashes.patch queue-4.4/bpf-use-mount_nodev-not-mount_ns-to-mount-the-bpf-filesystem.patch queue-4.4/netlink-fix-dump-skb-leak-double-free.patch queue-4.4/sparc-pci-fix-for-panic-while-enabling-sr-iov.patch queue-4.4/team-don-t-call-netdev_change_features-under-team-lock.patch queue-4.4/sparc64-reduce-tlb-flushes-during-hugepte-changes.patch queue-4.4/udp-prevent-skbs-lingering-in-tunnel-socket-queues.patch queue-4.4/bridge-don-t-insert-unnecessary-local-fdb-entry-on-changing-mac-address.patch queue-4.4/tipc-fix-nametable-publication-field-in-nl-compat.patch queue-4.4/sparc64-fix-sparc64_set_context-stack-handling.patch queue-4.4/sparc64-take-ctx_alloc_lock-properly-in-hugetlb_setup.patch queue-4.4/tipc-check-nl-sock-before-parsing-nested-attributes.patch queue-4.4/geneve-relax-mtu-constraints.patch queue-4.4/uapi-glibc-compat-fix-compilation-when-__use_misc-in-glibc.patch queue-4.4/sparc-harden-signal-return-frame-checks.patch queue-4.4/tuntap-correctly-wake-up-process-during-uninit.patch queue-4.4/sparc64-fix-numa-node-distance-initialization.patch