lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Tue, 3 May 2016 00:50:30 -0700 From: tip-bot for Stas Sergeev <tipbot@...or.com> To: linux-tip-commits@...r.kernel.org Cc: amanieu@...il.com, oleg@...hat.com, torvalds@...ux-foundation.org, luto@...capital.net, xypron.glpk@....de, akpm@...ux-foundation.org, jason.low2@...com, cyphar@...har.com, aarcange@...hat.com, ebiederm@...ssion.com, viro@...iv.linux.org.uk, josh@...htriplett.org, tj@...nel.org, hpa@...or.com, linux-kernel@...r.kernel.org, vdavydov@...allels.com, stsp@...t.ru, mingo@...nel.org, tglx@...utronix.de, peterz@...radead.org, bp@...en8.de, pmoore@...hat.com, fweisbec@...il.com, khlebnikov@...dex-team.ru, sasha.levin@...cle.com, shuahkh@....samsung.com, palmer@...belt.com, brgerst@...il.com, richard@....at, xemul@...allels.com, dvlasenk@...hat.com Subject: [tip:core/signals] signals/sigaltstack: Implement SS_AUTODISARM flag Commit-ID: 2a74213838104a41588d86fd5e8d344972891ace Gitweb: http://git.kernel.org/tip/2a74213838104a41588d86fd5e8d344972891ace Author: Stas Sergeev <stsp@...t.ru> AuthorDate: Thu, 14 Apr 2016 23:20:04 +0300 Committer: Ingo Molnar <mingo@...nel.org> CommitDate: Tue, 3 May 2016 08:37:59 +0200 signals/sigaltstack: Implement SS_AUTODISARM flag This patch implements the SS_AUTODISARM flag that can be OR-ed with SS_ONSTACK when forming ss_flags. When this flag is set, sigaltstack will be disabled when entering the signal handler; more precisely, after saving sas to uc_stack. When leaving the signal handler, the sigaltstack is restored by uc_stack. When this flag is used, it is safe to switch from sighandler with swapcontext(). Without this flag, the subsequent signal will corrupt the state of the switched-away sighandler. To detect the support of this functionality, one can do: err = sigaltstack(SS_DISABLE | SS_AUTODISARM); if (err && errno == EINVAL) unsupported(); Signed-off-by: Stas Sergeev <stsp@...t.ru> Cc: Al Viro <viro@...iv.linux.org.uk> Cc: Aleksa Sarai <cyphar@...har.com> Cc: Amanieu d'Antras <amanieu@...il.com> Cc: Andrea Arcangeli <aarcange@...hat.com> Cc: Andrew Morton <akpm@...ux-foundation.org> Cc: Andy Lutomirski <luto@...capital.net> Cc: Borislav Petkov <bp@...en8.de> Cc: Brian Gerst <brgerst@...il.com> Cc: Denys Vlasenko <dvlasenk@...hat.com> Cc: Eric W. Biederman <ebiederm@...ssion.com> Cc: Frederic Weisbecker <fweisbec@...il.com> Cc: H. Peter Anvin <hpa@...or.com> Cc: Heinrich Schuchardt <xypron.glpk@....de> Cc: Jason Low <jason.low2@...com> Cc: Josh Triplett <josh@...htriplett.org> Cc: Konstantin Khlebnikov <khlebnikov@...dex-team.ru> Cc: Linus Torvalds <torvalds@...ux-foundation.org> Cc: Oleg Nesterov <oleg@...hat.com> Cc: Palmer Dabbelt <palmer@...belt.com> Cc: Paul Moore <pmoore@...hat.com> Cc: Pavel Emelyanov <xemul@...allels.com> Cc: Peter Zijlstra <peterz@...radead.org> Cc: Richard Weinberger <richard@....at> Cc: Sasha Levin <sasha.levin@...cle.com> Cc: Shuah Khan <shuahkh@....samsung.com> Cc: Tejun Heo <tj@...nel.org> Cc: Thomas Gleixner <tglx@...utronix.de> Cc: Vladimir Davydov <vdavydov@...allels.com> Cc: linux-api@...r.kernel.org Cc: linux-kernel@...r.kernel.org Link: http://lkml.kernel.org/r/1460665206-13646-4-git-send-email-stsp@list.ru Signed-off-by: Ingo Molnar <mingo@...nel.org> --- include/linux/sched.h | 8 ++++++++ include/linux/signal.h | 4 +++- include/uapi/linux/signal.h | 4 +++- kernel/fork.c | 2 +- kernel/signal.c | 10 ++++++++-- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/include/linux/sched.h b/include/linux/sched.h index 52c4847..2950c5c 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1596,6 +1596,7 @@ struct task_struct { unsigned long sas_ss_sp; size_t sas_ss_size; + unsigned sas_ss_flags; struct callback_head *task_works; @@ -2592,6 +2593,13 @@ static inline int sas_ss_flags(unsigned long sp) return on_sig_stack(sp) ? SS_ONSTACK : 0; } +static inline void sas_ss_reset(struct task_struct *p) +{ + p->sas_ss_sp = 0; + p->sas_ss_size = 0; + p->sas_ss_flags = SS_DISABLE; +} + static inline unsigned long sigsp(unsigned long sp, struct ksignal *ksig) { if (unlikely((ksig->ka.sa.sa_flags & SA_ONSTACK)) && ! sas_ss_flags(sp)) diff --git a/include/linux/signal.h b/include/linux/signal.h index 92557bb..3fbe814 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -432,8 +432,10 @@ int __save_altstack(stack_t __user *, unsigned long); stack_t __user *__uss = uss; \ struct task_struct *t = current; \ put_user_ex((void __user *)t->sas_ss_sp, &__uss->ss_sp); \ - put_user_ex(sas_ss_flags(sp), &__uss->ss_flags); \ + put_user_ex(t->sas_ss_flags, &__uss->ss_flags); \ put_user_ex(t->sas_ss_size, &__uss->ss_size); \ + if (t->sas_ss_flags & SS_AUTODISARM) \ + sas_ss_reset(t); \ } while (0); #ifdef CONFIG_PROC_FS diff --git a/include/uapi/linux/signal.h b/include/uapi/linux/signal.h index 7c73165..7388260 100644 --- a/include/uapi/linux/signal.h +++ b/include/uapi/linux/signal.h @@ -7,7 +7,9 @@ #define SS_ONSTACK 1 #define SS_DISABLE 2 +/* bit-flags */ +#define SS_AUTODISARM (1 << 4) /* disable sas during sighandling */ /* mask for all SS_xxx flags */ -#define SS_FLAG_BITS 0 +#define SS_FLAG_BITS SS_AUTODISARM #endif /* _UAPI_LINUX_SIGNAL_H */ diff --git a/kernel/fork.c b/kernel/fork.c index d277e83..3e84515 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1494,7 +1494,7 @@ static struct task_struct *copy_process(unsigned long clone_flags, * sigaltstack should be cleared when sharing the same VM */ if ((clone_flags & (CLONE_VM|CLONE_VFORK)) == CLONE_VM) - p->sas_ss_sp = p->sas_ss_size = 0; + sas_ss_reset(p); /* * Syscall tracing and stepping should be turned off in the diff --git a/kernel/signal.c b/kernel/signal.c index b1c6eb4..bf97ea5 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -3137,6 +3137,7 @@ do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long s current->sas_ss_sp = (unsigned long) ss_sp; current->sas_ss_size = ss_size; + current->sas_ss_flags = ss_flags; } error = 0; @@ -3167,9 +3168,14 @@ int restore_altstack(const stack_t __user *uss) int __save_altstack(stack_t __user *uss, unsigned long sp) { struct task_struct *t = current; - return __put_user((void __user *)t->sas_ss_sp, &uss->ss_sp) | - __put_user(sas_ss_flags(sp), &uss->ss_flags) | + int err = __put_user((void __user *)t->sas_ss_sp, &uss->ss_sp) | + __put_user(t->sas_ss_flags, &uss->ss_flags) | __put_user(t->sas_ss_size, &uss->ss_size); + if (err) + return err; + if (t->sas_ss_flags & SS_AUTODISARM) + sas_ss_reset(t); + return 0; } #ifdef CONFIG_COMPAT
Powered by blists - more mailing lists