The following patches make it possible to use swapcontext()
in a sighandler that works on sigaltstack.
The approach is inspired by Andy Lutomirski's suggestion that
sigaltstack should disarm itself after saving into uc_stack:
https://lkml.org/lkml/2016/2/1/594
I add the SS_AUTODISARM flag that does exactly that.
On sighandler exit, the sigaltstack is restored from uc_stack.
Another possible name could be SS_ONESHOT, but, since it gets
always re-enabled, I choose SS_AUTODISARM.
[PATCH 1/2] sigaltstack: implement SS_AUTODISARM flag
This patch implements SS_AUTODISARM flag
[PATCH 2/2] selftests: Add test for sigaltstack(SS_AUTODISARM)
This patch adds the selftest code for new functionality
CC: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: Andy Lutomirski <redacted>
CC: Oleg Nesterov <redacted>
CC: Shuah Khan <redacted>
Diffstat:
include/linux/sched.h | 8 +
include/linux/signal.h | 4
include/uapi/linux/signal.h | 3
kernel/fork.c | 2
kernel/signal.c | 23 ++--
tools/testing/selftests/Makefile | 1
tools/testing/selftests/sigaltstack/Makefile | 8 +
tools/testing/selftests/sigaltstack/sas.c | 151 +++++++++++++++++++++++++++
8 files changed, 187 insertions(+), 13 deletions(-)
This patch implements the SS_AUTODISARM flag that can be ORed 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.
CC: Ingo Molnar <mingo@redhat.com>
CC: Peter Zijlstra <peterz@infradead.org>
CC: Richard Weinberger <richard@nod.at>
CC: Andrew Morton <akpm@linux-foundation.org>
CC: Oleg Nesterov <oleg@redhat.com>
CC: Tejun Heo <tj@kernel.org>
CC: Heinrich Schuchardt <redacted>
CC: Jason Low <redacted>
CC: Andrea Arcangeli <redacted>
CC: Frederic Weisbecker <redacted>
CC: Konstantin Khlebnikov <redacted>
CC: Josh Triplett <josh@joshtriplett.org>
CC: "Eric W. Biederman" <redacted>
CC: Aleksa Sarai <redacted>
CC: "Amanieu d'Antras" <redacted>
CC: Paul Moore <redacted>
CC: Sasha Levin <redacted>
CC: Palmer Dabbelt <palmer@dabbelt.com>
CC: Vladimir Davydov <redacted>
CC: linux-kernel@vger.kernel.org
CC: linux-api@vger.kernel.org
CC: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Stas Sergeev <redacted>
---
include/linux/sched.h | 8 ++++++++
include/linux/signal.h | 4 +++-
include/uapi/linux/signal.h | 3 +++
kernel/fork.c | 2 +-
kernel/signal.c | 23 ++++++++++++-----------
5 files changed, 27 insertions(+), 13 deletions(-)
@@ -2573,6 +2574,13 @@ static inline int sas_ss_flags(unsigned long sp)returnon_sig_stack(sp)?SS_ONSTACK:0;}+staticinlinevoidsas_ss_reset(structtask_struct*p)+{+p->sas_ss_sp=0;+p->sas_ss_size=0;+p->sas_ss_flags=SS_DISABLE;+}+staticinlineunsignedlongsigsp(unsignedlongsp,structksignal*ksig){if(unlikely((ksig->ka.sa.sa_flags&SA_ONSTACK))&&!sas_ss_flags(sp))
From: Stas Sergeev <redacted>
sigaltstack needs to be disabled before the signal handler can
safely use swapcontext().
This patch adds the SS_AUTODISARM flag.
This flag disables the sigaltstack when entering the signal handler.
When returning from signal handler, the sigaltstack is restored by
uc_stack.
CC: Shuah Khan <redacted>
CC: linux-kernel@vger.kernel.org
CC: linux-api@vger.kernel.org
CC: Andy Lutomirski <luto@amacapital.net>
Signed-off-by: Stas Sergeev <redacted>
---
tools/testing/selftests/Makefile | 1 +
tools/testing/selftests/sigaltstack/Makefile | 8 ++
tools/testing/selftests/sigaltstack/sas.c | 151 +++++++++++++++++++++++++++
3 files changed, 160 insertions(+)
create mode 100644 tools/testing/selftests/sigaltstack/Makefile
create mode 100644 tools/testing/selftests/sigaltstack/sas.c
@@ -0,0 +1,151 @@+/*+*StasSergeev<stsp@users.sourceforge.net>+*+*testsigaltstack(SS_AUTODISARM)+*Ifthatsucceeds,thenswapcontext()canbeusedinsidesighandlersafely.+*+*/++#define _GNU_SOURCE+#include<signal.h>+#include<stdio.h>+#include<stdlib.h>+#include<sys/mman.h>+#include<ucontext.h>+#include<alloca.h>+#include<string.h>+#include<assert.h>++#ifndef SS_AUTODISARM+#define SS_AUTODISARM (1 << 4)+#endif++staticvoid*sstack,*ustack;+staticucontext_tuc,sc;+staticconstchar*msg="[OK]\tStack preserved";+staticconstchar*msg2="[FAIL]\tStack corrupted";+structstk_data{+charmsg[128];+intflag;+};++voidmy_usr1(intsig,siginfo_t*si,void*u)+{+char*aa;+interr;+stack_tstk;+structstk_data*p;++registerunsignedlongspasm("sp");++if(sp<(unsignedlong)sstack||+sp>=(unsignedlong)sstack+SIGSTKSZ){+printf("[FAIL]\tSP is not on sigaltstack\n");+exit(EXIT_FAILURE);+}+/* put some data on stack. other sighandler will try to overwrite it */+aa=alloca(1024);+assert(aa);+p=(structstk_data*)(aa+512);+strcpy(p->msg,msg);+p->flag=1;+printf("[RUN]\tsignal USR1\n");+err=sigaltstack(NULL,&stk);+if(err){+perror("[FAIL]\tsigaltstack()");+exit(EXIT_FAILURE);+}+if(stk.ss_flags!=SS_DISABLE)+printf("[FAIL]\tss_flags=%i, should be SS_DISABLE\n",+stk.ss_flags);+else+printf("[OK]\tsigaltstack is disabled in sighandler\n");+swapcontext(&sc,&uc);+printf("%s\n",p->msg);+if(!p->flag){+printf("[RUN]\tAborting\n");+exit(EXIT_FAILURE);+}+}++voidmy_usr2(intsig,siginfo_t*si,void*u)+{+char*aa;+structstk_data*p;++printf("[RUN]\tsignal USR2\n");+aa=alloca(1024);+/* dont run valgrind on this */+/* try to find the data stored by previous sighandler */+p=memmem(aa,1024,msg,strlen(msg));+if(p){+printf("[FAIL]\tsigaltstack re-used\n");+/* corrupt the data */+strcpy(p->msg,msg2);+/* tell other sighandler that his data is corrupted */+p->flag=0;+}+}++staticvoidswitch_fn(void)+{+printf("[RUN]\tswitched to user ctx\n");+raise(SIGUSR2);+setcontext(&sc);+}++intmain(void)+{+structsigactionact;+stack_tstk;+interr;++sigemptyset(&act.sa_mask);+act.sa_flags=SA_ONSTACK|SA_SIGINFO;+act.sa_sigaction=my_usr1;+sigaction(SIGUSR1,&act,NULL);+act.sa_sigaction=my_usr2;+sigaction(SIGUSR2,&act,NULL);+sstack=mmap(NULL,SIGSTKSZ,PROT_READ|PROT_WRITE,+MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK,-1,0);+if(sstack==MAP_FAILED){+perror("mmap()");+returnEXIT_FAILURE;+}+stk.ss_sp=sstack;+stk.ss_size=SIGSTKSZ;+stk.ss_flags=SS_ONSTACK|SS_AUTODISARM;+err=sigaltstack(&stk,NULL);+if(err){+perror("sigaltstack()");+returnEXIT_FAILURE;+}++ustack=mmap(NULL,SIGSTKSZ,PROT_READ|PROT_WRITE,+MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK,-1,0);+if(ustack==MAP_FAILED){+perror("mmap()");+returnEXIT_FAILURE;+}+getcontext(&uc);+uc.uc_link=NULL;+uc.uc_stack.ss_sp=ustack;+uc.uc_stack.ss_size=SIGSTKSZ;+makecontext(&uc,switch_fn,0);+raise(SIGUSR1);++err=sigaltstack(NULL,&stk);+if(err){+perror("[FAIL]\tsigaltstack()");+exit(EXIT_FAILURE);+}+if(stk.ss_flags!=0){+printf("[FAIL]\tss_flags=%i, should be 0\n",+stk.ss_flags);+exit(EXIT_FAILURE);+}+printf("[OK]\tsigaltstack is enabled after signal\n");++printf("[OK]\tTest passed\n");+return0;+}
From: Andy Lutomirski <luto@amacapital.net> Date: 2016-03-04 22:22:47
On Mon, Feb 29, 2016 at 1:29 PM, Stas Sergeev [off-list ref] wrote:
This patch implements the SS_AUTODISARM flag that can be ORed 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.
This looks reasonable to me with one exception: how does a user
program detect the presence of this feature? Anyone else have any
thoughts?
On Mon, Feb 29, 2016 at 1:29 PM, Stas Sergeev [off-list ref] wrote:
quoted
This patch implements the SS_AUTODISARM flag that can be ORed 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.
This looks reasonable to me with one exception: how does a user
program detect the presence of this feature?
Compile-time detection:
#ifdef SS_AUTODISARM
# I have this feature
...
#endif
Run-time detection:
int err = sigaltstack(SS_ONSTACK | SS_AUTODISARM);
if (err == EINVAL) {
i_dont_have_this_feature = 1;
err = sigaltstack(SS_ONSTACK);
}
Note: if you want to keep such detection for the future
additions, the mask can be enlarged to, say, ((1 << 24) - 1),
and whenever someone adds a new flag, he can lower the
mask by one bit.
But I think this would be an overkill in that particular case.
On Mon, Feb 29, 2016 at 1:29 PM, Stas Sergeev [off-list ref] wrote:
quoted
This patch implements the SS_AUTODISARM flag that can be ORed 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.
This looks reasonable to me with one exception: how does a user
program detect the presence of this feature?
Compile-time detection:
#ifdef SS_AUTODISARM
# I have this feature
...
#endif
Run-time detection:
int err = sigaltstack(SS_ONSTACK | SS_AUTODISARM);
if (err == EINVAL) {
From: Andy Lutomirski <luto@amacapital.net> Date: 2016-03-06 20:07:34
On Mon, Feb 29, 2016 at 1:29 PM, Stas Sergeev [off-list ref] wrote:
quoted hunk
This patch implements the SS_AUTODISARM flag that can be ORed 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.
CC: Ingo Molnar <redacted>
CC: Peter Zijlstra <redacted>
CC: Richard Weinberger <richard-/L3Ra7n9ekc@public.gmane.org>
CC: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
CC: Oleg Nesterov <redacted>
CC: Tejun Heo <redacted>
CC: Heinrich Schuchardt <redacted>
CC: Jason Low <redacted>
CC: Andrea Arcangeli <redacted>
CC: Frederic Weisbecker <redacted>
CC: Konstantin Khlebnikov <redacted>
CC: Josh Triplett <redacted>
CC: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
CC: Aleksa Sarai <cyphar-gVpy/LI/lHzQT0dZR+AlfA@public.gmane.org>
CC: "Amanieu d'Antras" <redacted>
CC: Paul Moore <redacted>
CC: Sasha Levin <redacted>
CC: Palmer Dabbelt <redacted>
CC: Vladimir Davydov <redacted>
CC: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: Andy Lutomirski <redacted>
Signed-off-by: Stas Sergeev <redacted>
---
include/linux/sched.h | 8 ++++++++
include/linux/signal.h | 4 +++-
include/uapi/linux/signal.h | 3 +++
kernel/fork.c | 2 +-
kernel/signal.c | 23 ++++++++++++-----------
5 files changed, 27 insertions(+), 13 deletions(-)
@@ -2573,6 +2574,13 @@ static inline int sas_ss_flags(unsigned long sp)returnon_sig_stack(sp)?SS_ONSTACK:0;}+staticinlinevoidsas_ss_reset(structtask_struct*p)+{+p->sas_ss_sp=0;+p->sas_ss_size=0;+p->sas_ss_flags=SS_DISABLE;+}+staticinlineunsignedlongsigsp(unsignedlongsp,structksignal*ksig){if(unlikely((ksig->ka.sa.sa_flags&SA_ONSTACK))&&!sas_ss_flags(sp))
The following patches make it possible to use swapcontext()
in a sighandler that works on sigaltstack.
i don't think that's possible, the (obsolete) userspace
*context functions cannot operate on kernel provided
ucontext_t structs, so they are not usable in signal
handlers.
at least not on most target archs.
so i don't understand how the tests can work portably.
The approach is inspired by Andy Lutomirski's suggestion that
sigaltstack should disarm itself after saving into uc_stack:
https://lkml.org/lkml/2016/2/1/594
I add the SS_AUTODISARM flag that does exactly that.
On sighandler exit, the sigaltstack is restored from uc_stack.
Another possible name could be SS_ONESHOT, but, since it gets
always re-enabled, I choose SS_AUTODISARM.
[PATCH 1/2] sigaltstack: implement SS_AUTODISARM flag
This patch implements SS_AUTODISARM flag
[PATCH 2/2] selftests: Add test for sigaltstack(SS_AUTODISARM)
This patch adds the selftest code for new functionality
CC: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: Andy Lutomirski <redacted>
CC: Oleg Nesterov <redacted>
CC: Shuah Khan <redacted>
Diffstat:
include/linux/sched.h | 8 +
include/linux/signal.h | 4
include/uapi/linux/signal.h | 3
kernel/fork.c | 2
kernel/signal.c | 23 ++--
tools/testing/selftests/Makefile | 1
tools/testing/selftests/sigaltstack/Makefile | 8 +
tools/testing/selftests/sigaltstack/sas.c | 151 +++++++++++++++++++++++++++
8 files changed, 187 insertions(+), 13 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe linux-api" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
From: Andy Lutomirski <luto@amacapital.net> Date: 2016-03-06 20:10:50
On Sun, Mar 6, 2016 at 12:07 PM, Andy Lutomirski [off-list ref] wrote:
On Mon, Feb 29, 2016 at 1:29 PM, Stas Sergeev [off-list ref] wrote:
quoted
This patch implements the SS_AUTODISARM flag that can be ORed 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.
CC: Ingo Molnar <redacted>
CC: Peter Zijlstra <redacted>
CC: Richard Weinberger <richard-/L3Ra7n9ekc@public.gmane.org>
CC: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
CC: Oleg Nesterov <redacted>
CC: Tejun Heo <redacted>
CC: Heinrich Schuchardt <redacted>
CC: Jason Low <redacted>
CC: Andrea Arcangeli <redacted>
CC: Frederic Weisbecker <redacted>
CC: Konstantin Khlebnikov <redacted>
CC: Josh Triplett <redacted>
CC: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
CC: Aleksa Sarai <cyphar-gVpy/LI/lHzQT0dZR+AlfA@public.gmane.org>
CC: "Amanieu d'Antras" <redacted>
CC: Paul Moore <redacted>
CC: Sasha Levin <redacted>
CC: Palmer Dabbelt <redacted>
CC: Vladimir Davydov <redacted>
CC: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: Andy Lutomirski <redacted>
Signed-off-by: Stas Sergeev <redacted>
---
include/linux/sched.h | 8 ++++++++
include/linux/signal.h | 4 +++-
include/uapi/linux/signal.h | 3 +++
kernel/fork.c | 2 +-
kernel/signal.c | 23 ++++++++++++-----------
5 files changed, 27 insertions(+), 13 deletions(-)
@@ -2573,6 +2574,13 @@ static inline int sas_ss_flags(unsigned long sp)returnon_sig_stack(sp)?SS_ONSTACK:0;}+staticinlinevoidsas_ss_reset(structtask_struct*p)+{+p->sas_ss_sp=0;+p->sas_ss_size=0;+p->sas_ss_flags=SS_DISABLE;+}+staticinlineunsignedlongsigsp(unsignedlongsp,structksignal*ksig){if(unlikely((ksig->ka.sa.sa_flags&SA_ONSTACK))&&!sas_ss_flags(sp))
Actually, let's invert that.
#define SS_AUTODISARM (1U << 31)
#define SS_FLAG_BITS SS_AUTODISARM
ss_mode = ss_flags & ~SS_FLAG_BITS;
this way flag bits that are currently undefined will continue to trigger EINVAL.
--Andy
On Sun, Mar 6, 2016 at 12:07 PM, Andy Lutomirski [off-list ref] wrote:
quoted
On Mon, Feb 29, 2016 at 1:29 PM, Stas Sergeev [off-list ref] wrote:
quoted
This patch implements the SS_AUTODISARM flag that can be ORed 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.
CC: Ingo Molnar <redacted>
CC: Peter Zijlstra <redacted>
CC: Richard Weinberger <richard-/L3Ra7n9ekc@public.gmane.org>
CC: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
CC: Oleg Nesterov <redacted>
CC: Tejun Heo <redacted>
CC: Heinrich Schuchardt <redacted>
CC: Jason Low <redacted>
CC: Andrea Arcangeli <redacted>
CC: Frederic Weisbecker <redacted>
CC: Konstantin Khlebnikov <redacted>
CC: Josh Triplett <redacted>
CC: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
CC: Aleksa Sarai <cyphar-gVpy/LI/lHzQT0dZR+AlfA@public.gmane.org>
CC: "Amanieu d'Antras" <redacted>
CC: Paul Moore <redacted>
CC: Sasha Levin <redacted>
CC: Palmer Dabbelt <redacted>
CC: Vladimir Davydov <redacted>
CC: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: Andy Lutomirski <redacted>
Signed-off-by: Stas Sergeev <redacted>
---
include/linux/sched.h | 8 ++++++++
include/linux/signal.h | 4 +++-
include/uapi/linux/signal.h | 3 +++
kernel/fork.c | 2 +-
kernel/signal.c | 23 ++++++++++++-----------
5 files changed, 27 insertions(+), 13 deletions(-)
@@ -2573,6 +2574,13 @@ static inline int sas_ss_flags(unsigned long sp)returnon_sig_stack(sp)?SS_ONSTACK:0;}+staticinlinevoidsas_ss_reset(structtask_struct*p)+{+p->sas_ss_sp=0;+p->sas_ss_size=0;+p->sas_ss_flags=SS_DISABLE;+}+staticinlineunsignedlongsigsp(unsignedlongsp,structksignal*ksig){if(unlikely((ksig->ka.sa.sa_flags&SA_ONSTACK))&&!sas_ss_flags(sp))
Actually, let's invert that.
#define SS_AUTODISARM (1U << 31)
#define SS_FLAG_BITS SS_AUTODISARM
ss_mode = ss_flags & ~SS_FLAG_BITS;
this way flag bits that are currently undefined will continue to trigger EINVAL.
OK, will do.
Though I am still going to keep SS_AUTODISARM =(1 << 4) -
it doesn't matter from what side we add new flags, does it?
The following patches make it possible to use swapcontext()
in a sighandler that works on sigaltstack.
i don't think that's possible, the (obsolete) userspace
*context functions cannot operate on kernel provided
ucontext_t structs,
It doesn't have to.
It does the normal getcontext()/swapcontext() sequences,
as if it would be switching from any casual code place.
Kernel-provided context structs are completely irrelevant.
For more details please see the test-case I posted in that patch series.
It shows what can be done and how.
so they are not usable in signal
handlers.
Please note the fact that swapcontext() also replaces the
signal mask as part of the context switching. This is a very
strong hint that it was intended to work with signal handlers.
And in fact it perfectly does.
What I want is only to make it friendly to sigaltstack.
I am not making it friendly to signal handlers in general,
because it already is.
at least not on most target archs.
so i don't understand how the tests can work portably.
If you apply my patch series, you can immediately test
it on any arch you want, thanks to the test-case my patch
adds to the kernel. Please let me know on what arch it fails.
The following patches make it possible to use swapcontext()
in a sighandler that works on sigaltstack.
i don't think that's possible, the (obsolete) userspace
*context functions cannot operate on kernel provided
ucontext_t structs, so they are not usable in signal
handlers.
at least not on most target archs.
so i don't understand how the tests can work portably.
i see the test does not use the kernel ucontext_t
and only synchronous context switch is done
sorry for the noise.
From: Andy Lutomirski <luto@amacapital.net> Date: 2016-03-06 20:55:48
On Sun, Mar 6, 2016 at 12:17 PM, Stas Sergeev [off-list ref] wrote:
06.03.2016 23:10, Andy Lutomirski пишет:
quoted
On Sun, Mar 6, 2016 at 12:07 PM, Andy Lutomirski [off-list ref]
wrote:
quoted
On Mon, Feb 29, 2016 at 1:29 PM, Stas Sergeev [off-list ref] wrote:
quoted
This patch implements the SS_AUTODISARM flag that can be ORed 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.
CC: Ingo Molnar <redacted>
CC: Peter Zijlstra <redacted>
CC: Richard Weinberger <richard-/L3Ra7n9ekc@public.gmane.org>
CC: Andrew Morton <akpm-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
CC: Oleg Nesterov <redacted>
CC: Tejun Heo <redacted>
CC: Heinrich Schuchardt <redacted>
CC: Jason Low <redacted>
CC: Andrea Arcangeli <redacted>
CC: Frederic Weisbecker <redacted>
CC: Konstantin Khlebnikov <redacted>
CC: Josh Triplett <redacted>
CC: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
CC: Aleksa Sarai <cyphar-gVpy/LI/lHzQT0dZR+AlfA@public.gmane.org>
CC: "Amanieu d'Antras" <redacted>
CC: Paul Moore <redacted>
CC: Sasha Levin <redacted>
CC: Palmer Dabbelt <redacted>
CC: Vladimir Davydov <redacted>
CC: linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: linux-api-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
CC: Andy Lutomirski <redacted>
Signed-off-by: Stas Sergeev <redacted>
---
include/linux/sched.h | 8 ++++++++
include/linux/signal.h | 4 +++-
include/uapi/linux/signal.h | 3 +++
kernel/fork.c | 2 +-
kernel/signal.c | 23 ++++++++++++-----------
5 files changed, 27 insertions(+), 13 deletions(-)
@@ -2573,6 +2574,13 @@ static inline int sas_ss_flags(unsigned long sp)returnon_sig_stack(sp)?SS_ONSTACK:0;}+staticinlinevoidsas_ss_reset(structtask_struct*p)+{+p->sas_ss_sp=0;+p->sas_ss_size=0;+p->sas_ss_flags=SS_DISABLE;+}+staticinlineunsignedlongsigsp(unsignedlongsp,structksignal
*ksig)
{
if (unlikely((ksig->ka.sa.sa_flags & SA_ONSTACK)) && !
sas_ss_flags(sp))
Actually, let's invert that.
#define SS_AUTODISARM (1U << 31)
#define SS_FLAG_BITS SS_AUTODISARM
ss_mode = ss_flags & ~SS_FLAG_BITS;
this way flag bits that are currently undefined will continue to trigger
EINVAL.
OK, will do.
Though I am still going to keep SS_AUTODISARM =(1 << 4) -
it doesn't matter from what side we add new flags, does it?
Adding them starting with a high bit means that more low bits are
available for use as mode numbers. Admittedly, this barely matters.
--Andy
--
Andy Lutomirski
AMA Capital Management, LLC