From: Jim Jagielski Date: Thu, 18 Sep 2008 18:42:18 +0000 (+0000) Subject: Merge r611483, r639005, r639010 from trunk: X-Git-Tag: 2.2.10~21 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a19c7578e4eebbab57f7d9e318451dd9dd90284a;p=thirdparty%2Fapache%2Fhttpd.git Merge r611483, r639005, r639010 from trunk: Support chroot on unix-family platforms PR 43596 (Dimitar Pashev) Document new ChrootDir directive (r611483) mmn bump for chroot (r611483) Submitted by: niq Reviewed by: jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@696758 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 0d945deddf1..6674d05b5c6 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,9 @@ Changes with Apache 2.2.10 mod_proxy_ftp: Prevent XSS attacks when using wildcards in the path of the FTP URL. Discovered by Marc Bevand of Rapid7. [Ruediger Pluem] + *) Support chroot on Unix-family platforms + PR 43596 [Dimitar Pashev ] + *) mod_ssl: implement dynamic mutex callbacks for the benefit of OpenSSL. [Sander Temme] diff --git a/docs/manual/mod/mpm_common.xml b/docs/manual/mod/mpm_common.xml index 9323262988f..cfc7168114a 100644 --- a/docs/manual/mod/mpm_common.xml +++ b/docs/manual/mod/mpm_common.xml @@ -964,4 +964,25 @@ requests + +ChrootDir +Directory for apache to run chroot(8) after startup. +ChrootDir /path/to/directory +none +server config +event +preforkworker +Available in Apache 2.2.10 and later + + +

This directive tells the server to chroot(8) to the + specified directory after startup, but before accepting requests.

+ +

Note that running the server under chroot is not + simple, and requires additional setup, particularly if you are running + scripts such as CGI or PHP. Please make sure you are properly familiar + with the operation of chroot before attempting to use this feature.

+
+
+ diff --git a/include/ap_mmn.h b/include/ap_mmn.h index 85408f576ad..bb832f86ecb 100644 --- a/include/ap_mmn.h +++ b/include/ap_mmn.h @@ -132,6 +132,7 @@ * proxy_worker struct. * 20051115.17(2.2.10) Add scolonsep to proxy_balancer * + * 20051115.18(2.2.10) Add chroot support to unixd_config */ #define MODULE_MAGIC_COOKIE 0x41503232UL /* "AP22" */ @@ -139,7 +140,7 @@ #ifndef MODULE_MAGIC_NUMBER_MAJOR #define MODULE_MAGIC_NUMBER_MAJOR 20051115 #endif -#define MODULE_MAGIC_NUMBER_MINOR 17 /* 0...n */ +#define MODULE_MAGIC_NUMBER_MINOR 18 /* 0...n */ /** * Determine if the server's current MODULE_MAGIC_NUMBER is at least a diff --git a/os/unix/unixd.c b/os/unix/unixd.c index ae140093f4d..7a306be667b 100644 --- a/os/unix/unixd.c +++ b/os/unix/unixd.c @@ -117,6 +117,30 @@ AP_DECLARE(int) unixd_setup_child(void) if (set_group_privs()) { return -1; } + + if (NULL != unixd_config.chroot_dir) { + if (geteuid()) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "Cannot chroot when not started as root"); + return -1; + } + if (chdir(unixd_config.chroot_dir) != 0) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "Can't chdir to %s", unixd_config.chroot_dir); + return -1; + } + if (chroot(unixd_config.chroot_dir) != 0) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "Can't chroot to %s", unixd_config.chroot_dir); + return -1; + } + if (chdir("/") != 0) { + ap_log_error(APLOG_MARK, APLOG_ALERT, errno, NULL, + "Can't chdir to new root"); + return -1; + } + } + #ifdef MPE /* Only try to switch if we're running as MANAGER.SYS */ if (geteuid() == 1 && unixd_config.user_id > 1) { @@ -198,6 +222,20 @@ AP_DECLARE(const char *) unixd_set_group(cmd_parms *cmd, void *dummy, return NULL; } +AP_DECLARE(const char *) unixd_set_chroot_dir(cmd_parms *cmd, void *dummy, + const char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + if (!ap_is_directory(cmd->pool, arg)) { + return "ChrootDir must be a valid directory"; + } + + unixd_config.chroot_dir = arg; + return NULL; +} AP_DECLARE(void) unixd_pre_config(apr_pool_t *ptemp) { @@ -206,6 +244,8 @@ AP_DECLARE(void) unixd_pre_config(apr_pool_t *ptemp) unixd_config.user_name = DEFAULT_USER; unixd_config.user_id = ap_uname2id(DEFAULT_USER); unixd_config.group_id = ap_gname2id(DEFAULT_GROUP); + + unixd_config.chroot_dir = NULL; /* none */ /* Check for suexec */ unixd_config.suexec_enabled = 0; diff --git a/os/unix/unixd.h b/os/unix/unixd.h index 8f781dcc330..833cc8f0c40 100644 --- a/os/unix/unixd.h +++ b/os/unix/unixd.h @@ -72,6 +72,7 @@ typedef struct { uid_t user_id; gid_t group_id; int suexec_enabled; + const char *chroot_dir; } unixd_config_rec; AP_DECLARE_DATA extern unixd_config_rec unixd_config; @@ -81,6 +82,9 @@ AP_DECLARE(const char *) unixd_set_user(cmd_parms *cmd, void *dummy, const char *arg); AP_DECLARE(const char *) unixd_set_group(cmd_parms *cmd, void *dummy, const char *arg); +AP_DECLARE(const char *) unixd_set_chroot_dir(cmd_parms *cmd, void *dummy, + const char *arg); + #if defined(RLIMIT_CPU) || defined(RLIMIT_DATA) || defined(RLIMIT_VMEM) || defined(RLIMIT_NPROC) || defined(RLIMIT_AS) AP_DECLARE(void) unixd_set_rlimit(cmd_parms *cmd, struct rlimit **plimit, const char *arg, const char * arg2, int type); @@ -111,7 +115,9 @@ AP_DECLARE(apr_status_t) unixd_accept(void **accepted, ap_listen_rec *lr, apr_po AP_INIT_TAKE1("User", unixd_set_user, NULL, RSRC_CONF, \ "Effective user id for this server"), \ AP_INIT_TAKE1("Group", unixd_set_group, NULL, RSRC_CONF, \ - "Effective group id for this server") + "Effective group id for this server"), \ +AP_INIT_TAKE1("ChrootDir", unixd_set_chroot_dir, NULL, RSRC_CONF, \ + "The directory to chroot(2) into") #endif /** @} */