diff options
author | kan <kan@FreeBSD.org> | 2007-05-11 01:25:51 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2007-05-11 01:25:51 +0000 |
commit | ea141892dce27c40435a682310e8d5beb8140681 (patch) | |
tree | 420a47771d1176128aaba0843e0eb57fec7f204c | |
parent | f6d9987afef1db420c46ccb06008b627cac5e971 (diff) | |
download | FreeBSD-src-ea141892dce27c40435a682310e8d5beb8140681.zip FreeBSD-src-ea141892dce27c40435a682310e8d5beb8140681.tar.gz |
Do not dereference linux_to_bsd_signal[-1] if userland has
passed zero as exit signal.
GCC 4.2 changes the kernel data segment layout not to have 0
in that memory location. This code ran by luck before and now
the luck has run out.
-rw-r--r-- | sys/amd64/linux32/linux32_machdep.c | 9 | ||||
-rw-r--r-- | sys/i386/linux/linux_machdep.c | 9 |
2 files changed, 10 insertions, 8 deletions
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c index cedd9b5..86a53ae 100644 --- a/sys/amd64/linux32/linux32_machdep.c +++ b/sys/amd64/linux32/linux32_machdep.c @@ -561,12 +561,13 @@ linux_clone(struct thread *td, struct linux_clone_args *args) #endif exit_signal = args->flags & 0x000000ff; - if (!LINUX_SIG_VALID(exit_signal) && exit_signal != 0) + if (LINUX_SIG_VALID(exit_signal)) { + if (exit_signal <= LINUX_SIGTBLSZ) + exit_signal = + linux_to_bsd_signal[_SIG_IDX(exit_signal)]; + } else if (exit_signal != 0) return (EINVAL); - if (exit_signal <= LINUX_SIGTBLSZ) - exit_signal = linux_to_bsd_signal[_SIG_IDX(exit_signal)]; - if (args->flags & LINUX_CLONE_VM) ff |= RFMEM; if (args->flags & LINUX_CLONE_SIGHAND) diff --git a/sys/i386/linux/linux_machdep.c b/sys/i386/linux/linux_machdep.c index c58abb5..5f916ed 100644 --- a/sys/i386/linux/linux_machdep.c +++ b/sys/i386/linux/linux_machdep.c @@ -400,12 +400,13 @@ linux_clone(struct thread *td, struct linux_clone_args *args) #endif exit_signal = args->flags & 0x000000ff; - if (!LINUX_SIG_VALID(exit_signal) && exit_signal != 0) + if (LINUX_SIG_VALID(exit_signal)) { + if (exit_signal <= LINUX_SIGTBLSZ) + exit_signal = + linux_to_bsd_signal[_SIG_IDX(exit_signal)]; + } else if (exit_signal != 0) return (EINVAL); - if (exit_signal <= LINUX_SIGTBLSZ) - exit_signal = linux_to_bsd_signal[_SIG_IDX(exit_signal)]; - if (args->flags & LINUX_CLONE_VM) ff |= RFMEM; if (args->flags & LINUX_CLONE_SIGHAND) |