From e06ce725da02a436965fd3a72c115ec7dee8d28e Mon Sep 17 00:00:00 2001 From: deischen Date: Sun, 26 Sep 2004 06:50:15 +0000 Subject: Add a wrapper for execve(). The exec'd process must be started with the signal mask and pending signals of the calling thread. These are stored in userland in libpthread. There is a small race condition in this patch which could cause problems if a signal arrives after setting the (kernel) signal mask and before exec'ing. The thread's set of pending signals also are not yet installed in the exec'd process. Both of these will be corrected with the addition of a special syscall. Reported & Tested by: Joost Bekkers Reviewed by: julian, davidxu --- lib/libkse/thread/Makefile.inc | 1 + lib/libkse/thread/thr_execve.c | 68 ++++++++++++++++++++++++++++++++++++++ lib/libpthread/pthread.map | 2 ++ lib/libpthread/thread/Makefile.inc | 1 + lib/libpthread/thread/thr_execve.c | 68 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 140 insertions(+) create mode 100644 lib/libkse/thread/thr_execve.c create mode 100644 lib/libpthread/thread/thr_execve.c (limited to 'lib') diff --git a/lib/libkse/thread/Makefile.inc b/lib/libkse/thread/Makefile.inc index 59fa21c..3ba361e 100644 --- a/lib/libkse/thread/Makefile.inc +++ b/lib/libkse/thread/Makefile.inc @@ -44,6 +44,7 @@ SRCS+= \ thr_create.c \ thr_detach.c \ thr_equal.c \ + thr_execve.c \ thr_exit.c \ thr_fcntl.c \ thr_find_thread.c \ diff --git a/lib/libkse/thread/thr_execve.c b/lib/libkse/thread/thr_execve.c new file mode 100644 index 0000000..db5b858 --- /dev/null +++ b/lib/libkse/thread/thr_execve.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2004 Daniel Eischen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include "thr_private.h" + +__weak_reference(_execve, execve); + +int +_execve(const char *name, char *const *argv, char *const *envp) +{ + sigset_t omask; + struct pthread *curthread; + kse_critical_t crit; + int saved_errno; + int ret; + + /* + * When exec'ing, set the kernel signal mask to the thread's + * signal mask to satisfy POSIX requirements. We have to enter + * a critical region so that the kernel thread doesn't get + * changed out from under us after setting the signal mask. + */ + curthread = _get_curthread(); + crit = _kse_critical_enter(); + __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, &omask); + ret = __sys_execve(name, argv, envp); + + /* + * If something went wrong, set the signal mask back but don't + * destroy errno. + */ + saved_errno = errno; + __sys_sigprocmask(SIG_SETMASK, &omask, NULL); + errno = saved_errno; + _kse_critical_leave(crit); + return (ret); +} diff --git a/lib/libpthread/pthread.map b/lib/libpthread/pthread.map index bb04272..4d9110e 100644 --- a/lib/libpthread/pthread.map +++ b/lib/libpthread/pthread.map @@ -25,6 +25,7 @@ global: __write; __writev; _aio_suspend; + _execve; _fork; _nanosleep; _pause; @@ -176,6 +177,7 @@ global: close; connect; creat; + execve; fcntl; fork; fsync; diff --git a/lib/libpthread/thread/Makefile.inc b/lib/libpthread/thread/Makefile.inc index 59fa21c..3ba361e 100644 --- a/lib/libpthread/thread/Makefile.inc +++ b/lib/libpthread/thread/Makefile.inc @@ -44,6 +44,7 @@ SRCS+= \ thr_create.c \ thr_detach.c \ thr_equal.c \ + thr_execve.c \ thr_exit.c \ thr_fcntl.c \ thr_find_thread.c \ diff --git a/lib/libpthread/thread/thr_execve.c b/lib/libpthread/thread/thr_execve.c new file mode 100644 index 0000000..db5b858 --- /dev/null +++ b/lib/libpthread/thread/thr_execve.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2004 Daniel Eischen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice(s), this list of conditions and the following disclaimer as + * the first lines of this file unmodified other than the possible + * addition of one or more copyright notices. + * 2. Redistributions in binary form must reproduce the above copyright + * notice(s), this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include "thr_private.h" + +__weak_reference(_execve, execve); + +int +_execve(const char *name, char *const *argv, char *const *envp) +{ + sigset_t omask; + struct pthread *curthread; + kse_critical_t crit; + int saved_errno; + int ret; + + /* + * When exec'ing, set the kernel signal mask to the thread's + * signal mask to satisfy POSIX requirements. We have to enter + * a critical region so that the kernel thread doesn't get + * changed out from under us after setting the signal mask. + */ + curthread = _get_curthread(); + crit = _kse_critical_enter(); + __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, &omask); + ret = __sys_execve(name, argv, envp); + + /* + * If something went wrong, set the signal mask back but don't + * destroy errno. + */ + saved_errno = errno; + __sys_sigprocmask(SIG_SETMASK, &omask, NULL); + errno = saved_errno; + _kse_critical_leave(crit); + return (ret); +} -- cgit v1.1