From: Jeff Trawick Date: Thu, 16 Aug 2001 13:59:14 +0000 (+0000) Subject: The Unix MPMs other than perchild now allow child server X-Git-Tag: 2.0.24~62 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aee4f61414ab2c88cd51e00dc05974539080836f;p=apache The Unix MPMs other than perchild now allow child server processes to use the accept mutex when starting as root and using SysV sems for the accept mutex. Previously, this combination would lead to fatal errors in the child server processes. perchild can't use SysV sems because of security issues. translation: steal apache 1.3 code to call semop(IPC_SET) on the semaphore to set permissions and uid/gid git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@90213 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index a80c236b77..29c52ac811 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,12 @@ Changes with Apache 2.0.24-dev + *) The Unix MPMs other than perchild now allow child server + processes to use the accept mutex when starting as root and + using SysV sems for the accept mutex. Previously, this + combination would lead to fatal errors in the child server + processes. perchild can't use SysV sems because of security + issues. [Jeff Trawick, Greg Ames] + *) Added Win32 revision stamp resources to all http binaries (including modules/ and support/ tools.) PR7322 [William Rowe] diff --git a/configure.in b/configure.in index 9ba565f5b5..0a435b00d6 100644 --- a/configure.in +++ b/configure.in @@ -186,7 +186,8 @@ sys/socket.h \ pwd.h \ grp.h \ strings.h \ -sys/processor.h +sys/processor.h \ +sys/sem.h ) AC_HEADER_SYS_WAIT diff --git a/os/unix/unixd.c b/os/unix/unixd.c index ab1a12dbde..4ffde23218 100644 --- a/os/unix/unixd.c +++ b/os/unix/unixd.c @@ -69,6 +69,7 @@ #include "ap_mpm.h" #include "apr_thread_proc.h" #include "apr_strings.h" +#include "apr_portable.h" #ifdef HAVE_PWD_H #include #endif @@ -86,6 +87,9 @@ #ifdef HAVE_STRINGS_H #include #endif +#ifdef HAVE_SYS_SEM_H +#include +#endif unixd_config_rec unixd_config; @@ -373,3 +377,35 @@ AP_DECLARE(apr_status_t) ap_os_create_privileged_process( attr, ugid, p); } +AP_DECLARE(apr_status_t) unixd_set_lock_perms(apr_lock_t *lock) +{ +/* MPM shouldn't call us unless we're actually using a SysV sem; + * this is just to avoid compile issues on systems without that + * feature + */ +#if APR_HAS_SYSVSEM_SERIALIZE + apr_os_lock_t oslock; +#if !APR_HAVE_UNION_SEMUN + union semun { + long val; + struct semid_ds *buf; + ushort *array; +}; +#endif + union semun ick; + struct semid_ds buf; + + if (!geteuid()) { + apr_os_lock_get(&oslock, lock); + buf.sem_perm.uid = unixd_config.user_id; + buf.sem_perm.gid = unixd_config.group_id; + buf.sem_perm.mode = 0600; + ick.buf = &buf; + if (semctl(oslock.crossproc, 0, IPC_SET, ick) < 0) { + return errno; + } + } +#endif + return APR_SUCCESS; +} + diff --git a/os/unix/unixd.h b/os/unix/unixd.h index d1b5abdeec..b37e5b53c1 100644 --- a/os/unix/unixd.h +++ b/os/unix/unixd.h @@ -69,6 +69,7 @@ #endif #include "apr_hooks.h" #include "apr_thread_proc.h" +#include "apr_lock.h" #include #include @@ -111,7 +112,7 @@ AP_DECLARE(const char *) unixd_set_group(cmd_parms *cmd, void *dummy, AP_DECLARE(void) unixd_set_rlimit(cmd_parms *cmd, struct rlimit **plimit, const char *arg, const char * arg2, int type); #endif - +AP_DECLARE(apr_status_t) unixd_set_lock_perms(apr_lock_t *lock); #ifdef HAVE_KILLPG #define unixd_killpg(x, y) (killpg ((x), (y))) diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c index 3133fc5b85..0fe46a3a85 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -276,6 +276,20 @@ static void accept_mutex_init(apr_pool_t *p) ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, "couldn't create accept mutex"); exit(APEXIT_INIT); } + +#if APR_USE_SYSVSEM_SERIALIZE + if (ap_accept_lock_mech == APR_LOCK_DEFAULT || + ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#else + if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#endif + rv = unixd_set_lock_perms(accept_lock); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, NULL, + "Couldn't set permissions on cross-process lock"); + exit(APEXIT_INIT); + } + } } static void accept_mutex_on(void) diff --git a/server/mpm/threaded/threaded.c b/server/mpm/threaded/threaded.c index 8ea3700ed9..73008a7399 100644 --- a/server/mpm/threaded/threaded.c +++ b/server/mpm/threaded/threaded.c @@ -1229,6 +1229,20 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) return 1; } +#if APR_USE_SYSVSEM_SERIALIZE + if (ap_accept_lock_mech == APR_LOCK_DEFAULT || + ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#else + if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#endif + rv = unixd_set_lock_perms(accept_mutex); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't set permissions on cross-process lock"); + return 1; + } + } + if (!is_graceful) { ap_run_pre_mpm(pconf, SB_SHARED); } diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index d14771a5ef..76465963d4 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -1272,6 +1272,20 @@ int ap_mpm_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) return 1; } +#if APR_USE_SYSVSEM_SERIALIZE + if (ap_accept_lock_mech == APR_LOCK_DEFAULT || + ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#else + if (ap_accept_lock_mech == APR_LOCK_SYSVSEM) { +#endif + rv = unixd_set_lock_perms(accept_mutex); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, + "Couldn't set permissions on cross-process lock"); + return 1; + } + } + if (!is_graceful) { ap_run_pre_mpm(pconf, SB_SHARED); } diff --git a/server/mpm_common.c b/server/mpm_common.c index e850c3a95a..4fb8614178 100644 --- a/server/mpm_common.c +++ b/server/mpm_common.c @@ -593,7 +593,12 @@ AP_DECLARE(const char *) ap_mpm_set_accept_lock_mech(cmd_parms *cmd, ap_accept_lock_mech = APR_LOCK_FCNTL; } #endif -#if APR_HAS_SYSVSEM_SERIALIZE + /* perchild can't use SysV sems because the permissions on the accept + * mutex can't be set to allow all processes to use the mutex and + * at the same time keep all users from being able to dink with the + * mutex + */ +#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM) else if (!strcasecmp(arg, "sysvsem")) { ap_accept_lock_mech = APR_LOCK_SYSVSEM; } @@ -605,14 +610,14 @@ AP_DECLARE(const char *) ap_mpm_set_accept_lock_mech(cmd_parms *cmd, #endif else { return apr_pstrcat(cmd->pool, arg, " is an invalid mutex mechanism; valid " - "ones for this platform are: default" + "ones for this platform and MPM are: default" #if APR_HAS_FLOCK_SERIALIZE ", flock" #endif #if APR_HAS_FCNTL_SERIALIZE ", fcntl" #endif -#if APR_HAS_SYSVSEM_SERIALIZE +#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM) ", sysvsem" #endif #if APR_HAS_PROC_PTHREAD_SERIALIZE