diff options
| -rw-r--r-- | sys/i386/linux/linux.h | 8 | ||||
| -rw-r--r-- | sys/i386/linux/linux_machdep.c | 49 |
2 files changed, 47 insertions, 10 deletions
diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h index 8887ec36f67e..f399f054441f 100644 --- a/sys/i386/linux/linux.h +++ b/sys/i386/linux/linux.h @@ -159,6 +159,14 @@ struct linux_new_utsname { /* sigaltstack */ #define LINUX_MINSIGSTKSZ 2048 +#define LINUX_SS_ONSTACK_BC 0 /* backwards compat SS_ONSTACK */ +#define LINUX_SS_ONSTACK 1 +#define LINUX_SS_DISABLE 2 + + +int linux_to_bsd_sigaltstack(int lsa); +int bsd_to_linux_sigaltstack(int bsa); + typedef void (*linux_handler_t)(int); typedef u_long linux_osigset_t; diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c index afcfd4c734fc..d5ea70fc4b41 100644 --- a/sys/i386/linux/linux_machdep.c +++ b/sys/i386/linux/linux_machdep.c @@ -67,6 +67,32 @@ struct linux_select_argv { }; int +linux_to_bsd_sigaltstack(int lsa) +{ + int bsa = 0; + + if (lsa & LINUX_SS_DISABLE) + bsa |= SS_DISABLE; + if (lsa & LINUX_SS_ONSTACK) + bsa |= SS_ONSTACK; + if (lsa == LINUX_SS_ONSTACK_BC) + bsa = SS_ONSTACK; + return (bsa); +} + +int +bsd_to_linux_sigaltstack(int bsa) +{ + int lsa = 0; + + if (bsa & SS_DISABLE) + lsa |= LINUX_SS_DISABLE; + if (bsa & SS_ONSTACK) + lsa |= LINUX_SS_ONSTACK; + return (lsa); +} + +int linux_execve(struct proc *p, struct linux_execve_args *args) { struct execve_args bsd; @@ -606,16 +632,19 @@ linux_sigaltstack(p, uap) (long)p->p_pid, uap->uss, uap->uoss); #endif - error = copyin(uap->uss, &lss, sizeof(linux_stack_t)); - if (error) - return (error); - - ss = stackgap_alloc(&sg, sizeof(stack_t)); - ss->ss_sp = lss.ss_sp; - ss->ss_size = (lss.ss_size >= LINUX_MINSIGSTKSZ && - lss.ss_size < MINSIGSTKSZ) ? MINSIGSTKSZ : lss.ss_size; - ss->ss_flags = lss.ss_flags; + if (uap->uss == NULL) { + ss = NULL; + } else { + error = copyin(uap->uss, &lss, sizeof(linux_stack_t)); + if (error) + return (error); + ss = stackgap_alloc(&sg, sizeof(stack_t)); + ss->ss_sp = lss.ss_sp; + ss->ss_size = (lss.ss_size >= LINUX_MINSIGSTKSZ && + lss.ss_size < MINSIGSTKSZ) ? MINSIGSTKSZ : lss.ss_size; + ss->ss_flags = linux_to_bsd_sigaltstack(lss.ss_flags); + } oss = (uap->uoss != NULL) ? stackgap_alloc(&sg, sizeof(stack_t)) : NULL; @@ -627,7 +656,7 @@ linux_sigaltstack(p, uap) if (!error && oss != NULL) { lss.ss_sp = oss->ss_sp; lss.ss_size = oss->ss_size; - lss.ss_flags = oss->ss_flags; + lss.ss_flags = bsd_to_linux_sigaltstack(oss->ss_flags); error = copyout(&lss, uap->uoss, sizeof(linux_stack_t)); } |
