diff -Nru mpm-itk-2.4.7-03/CHANGES mpm-itk-2.4.7-04/CHANGES --- mpm-itk-2.4.7-03/CHANGES 2015-09-09 17:35:59.000000000 +0000 +++ mpm-itk-2.4.7-04/CHANGES 2016-02-14 16:16:51.000000000 +0000 @@ -1,3 +1,13 @@ +mpm-itk 2.4.7-04, released 2016-02-14: + + - Fix a compilation error on RHEL6; patch from Hans Kristian Rosbach. + - Add a new flag EnableCapabilities (default on), which can be disabled + to revert to the behavior in place before 2.4.2-02, which causes problems + when the filesystem in use does not respect capabilities (in particular + NFS). + - Update copyright to 2016. + + mpm-itk 2.4.7-03, released 2015-09-09: - Fix an issue where connections would be attempted closed in the parent diff -Nru mpm-itk-2.4.7-03/configure mpm-itk-2.4.7-04/configure --- mpm-itk-2.4.7-03/configure 2015-09-09 17:28:55.000000000 +0000 +++ mpm-itk-2.4.7-04/configure 2016-02-14 16:18:45.000000000 +0000 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for mpm-itk 2.4.7-03. +# Generated by GNU Autoconf 2.69 for mpm-itk 2.4.7-04. # # # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. @@ -576,8 +576,8 @@ # Identity of this package. PACKAGE_NAME='mpm-itk' PACKAGE_TARNAME='mpm-itk' -PACKAGE_VERSION='2.4.7-03' -PACKAGE_STRING='mpm-itk 2.4.7-03' +PACKAGE_VERSION='2.4.7-04' +PACKAGE_STRING='mpm-itk 2.4.7-04' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1194,7 +1194,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures mpm-itk 2.4.7-03 to adapt to many kinds of systems. +\`configure' configures mpm-itk 2.4.7-04 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1256,7 +1256,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of mpm-itk 2.4.7-03:";; + short | recursive ) echo "Configuration of mpm-itk 2.4.7-04:";; esac cat <<\_ACEOF @@ -1341,7 +1341,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -mpm-itk configure 2.4.7-03 +mpm-itk configure 2.4.7-04 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1442,7 +1442,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by mpm-itk $as_me 2.4.7-03, which was +It was created by mpm-itk $as_me 2.4.7-04, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -3209,7 +3209,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by mpm-itk $as_me 2.4.7-03, which was +This file was extended by mpm-itk $as_me 2.4.7-04, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -3271,7 +3271,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -mpm-itk config.status 2.4.7-03 +mpm-itk config.status 2.4.7-04 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -Nru mpm-itk-2.4.7-03/configure.ac mpm-itk-2.4.7-04/configure.ac --- mpm-itk-2.4.7-03/configure.ac 2015-09-09 17:28:51.000000000 +0000 +++ mpm-itk-2.4.7-04/configure.ac 2016-02-14 16:18:34.000000000 +0000 @@ -1,6 +1,6 @@ m4_include([m4/ax_with_apxs.m4]) -AC_INIT([mpm-itk], [2.4.7-03]) +AC_INIT([mpm-itk], [2.4.7-04]) AC_PROG_CC AC_CHECK_LIB(cap, cap_init) AX_WITH_APXS([missing]) diff -Nru mpm-itk-2.4.7-03/debian/changelog mpm-itk-2.4.7-04/debian/changelog --- mpm-itk-2.4.7-03/debian/changelog 2015-09-09 17:37:48.000000000 +0000 +++ mpm-itk-2.4.7-04/debian/changelog 2016-02-15 05:24:25.000000000 +0000 @@ -1,3 +1,9 @@ +mpm-itk (2.4.7-04-1) unstable; urgency=medium + + * New upstream release. + + -- Steinar H. Gunderson Sun, 14 Feb 2016 21:23:59 -0800 + mpm-itk (2.4.7-03-1) unstable; urgency=high * New upstream release. diff -Nru mpm-itk-2.4.7-03/mpm_itk.c mpm-itk-2.4.7-04/mpm_itk.c --- mpm-itk-2.4.7-03/mpm_itk.c 2015-09-09 17:35:12.000000000 +0000 +++ mpm-itk-2.4.7-04/mpm_itk.c 2016-02-14 16:37:42.000000000 +0000 @@ -13,14 +13,14 @@ * See the License for the specific language governing permissions and * limitations under the License. * - * Portions copyright 2005-2015 Steinar H. Gunderson . + * Portions copyright 2005-2016 Steinar H. Gunderson . * Licensed under the same terms as the rest of Apache. * * Portions copyright 2008 Knut Auvor Grythe . * Licensed under the same terms as the rest of Apache. */ -#define MPMITK_VERSION "2.4.7-03" +#define MPMITK_VERSION "2.4.7-04" #include "config.h" @@ -75,13 +75,14 @@ #include /* for bindprocessor() */ #endif +#include +#include + #if HAVE_LIBCAP -#include #include +#include #endif -#include -#include /* config globals */ @@ -90,6 +91,10 @@ static gid_t ap_itk_min_gid=1; static gid_t ap_itk_max_gid=UINT_MAX; +#if HAVE_LIBCAP +static int ap_itk_enable_caps=1; +#endif + module AP_MODULE_DECLARE_DATA mpm_itk_module; #define UNSET_NICE_VALUE 100 @@ -111,31 +116,34 @@ AP_DECLARE_DATA int ap_has_irreversibly_setuid = 0; -#if !HAVE_LIBCAP +/* Only in use if not enabling capabilities. */ AP_DECLARE_DATA uid_t saved_unixd_uid = -1; AP_DECLARE_DATA gid_t saved_unixd_gid = -1; -#endif static int itk_pre_drop_privileges(apr_pool_t *pool, server_rec *s) { #if HAVE_LIBCAP - /* mod_unixd will drop down to a normal user. This means that even if an - * attacker manage to execute code before setuid(), he/she cannot write to - * files owned by uid 0, such as /etc/crontab. We'll need to keep our extra - * privileges, though, since we need them for the actual query processing - * later, so specify that we'll keep them across the setuid that is soon to - * come. - * - * Note that since we still have CAP_SETUID, an attacker can setuid(0) - * and get around this. Thus, we disallow setuid(0) if the platform - * allows it. - */ - restrict_setuid_range(ap_itk_min_uid, ap_itk_max_uid, ap_itk_min_gid, ap_itk_max_gid); - if (prctl(PR_SET_KEEPCAPS, 1)) { - ap_log_error(APLOG_MARK, APLOG_EMERG, errno, NULL, "prctl(PR_SET_KEEPCAPS, 1) failed"); - exit(APEXIT_CHILDFATAL); + if (ap_itk_enable_caps) { + /* mod_unixd will drop down to a normal user. This means that even if an + * attacker manage to execute code before setuid(), he/she cannot write to + * files owned by uid 0, such as /etc/crontab. We'll need to keep our extra + * privileges, though, since we need them for the actual query processing + * later, so specify that we'll keep them across the setuid that is soon to + * come. + * + * Note that since we still have CAP_SETUID, an attacker can setuid(0) + * and get around this. Thus, we disallow setuid(0) if the platform + * allows it. + */ + restrict_setuid_range(ap_itk_min_uid, ap_itk_max_uid, ap_itk_min_gid, ap_itk_max_gid); + if (prctl(PR_SET_KEEPCAPS, 1)) { + ap_log_error(APLOG_MARK, APLOG_EMERG, errno, NULL, "prctl(PR_SET_KEEPCAPS, 1) failed"); + exit(APEXIT_CHILDFATAL); + } + return OK; } -#else +#endif + restrict_setuid_range(ap_itk_min_uid, ap_itk_max_uid, ap_itk_min_gid, ap_itk_max_gid); /* Fiddle with mod_unixd's structures so that it doesn't drop uid 0; * we need that, since we don't have capabilities. */ @@ -143,45 +151,46 @@ saved_unixd_gid = ap_unixd_config.group_id; ap_unixd_config.user_id = 0; ap_unixd_config.group_id = 0; -#endif return OK; } static int itk_post_drop_privileges(apr_pool_t *pool, server_rec *s) { #if HAVE_LIBCAP - cap_t caps; - cap_value_t suidcaps[] = { - CAP_SETUID, - CAP_SETGID, - CAP_DAC_READ_SEARCH, - CAP_SYS_NICE, - }; - - /* We don't need to keep capabilities across setuid anymore, so stop that. */ - if (prctl(PR_SET_KEEPCAPS, 0)) { - ap_log_error(APLOG_MARK, APLOG_EMERG, errno, NULL, "prctl(PR_SET_KEEPCAPS, 0) failed"); - exit(APEXIT_CHILDFATAL); - } - - /* Now drop as many privileges as we can. We'll still - * access files with uid=0, and we can setuid() to anything, but - * at least there's tons of other evilness (like loading kernel - * modules) we can't do directly. (The setuid() capability will - * go away automatically when we setuid() or exec() -- the former - * is likely to come first.) - */ - caps = cap_init(); - cap_clear(caps); - cap_set_flag(caps, CAP_PERMITTED, sizeof(suidcaps)/sizeof(cap_value_t), suidcaps, CAP_SET); - cap_set_flag(caps, CAP_EFFECTIVE, sizeof(suidcaps)/sizeof(cap_value_t), suidcaps, CAP_SET); - cap_set_proc(caps); - cap_free(caps); -#else + if (ap_itk_enable_caps) { + cap_t caps; + cap_value_t suidcaps[] = { + CAP_SETUID, + CAP_SETGID, + CAP_DAC_READ_SEARCH, + CAP_SYS_NICE, + }; + + /* We don't need to keep capabilities across setuid anymore, so stop that. */ + if (prctl(PR_SET_KEEPCAPS, 0)) { + ap_log_error(APLOG_MARK, APLOG_EMERG, errno, NULL, "prctl(PR_SET_KEEPCAPS, 0) failed"); + exit(APEXIT_CHILDFATAL); + } + + /* Now drop as many privileges as we can. We'll still + * access files with uid=0, and we can setuid() to anything, but + * at least there's tons of other evilness (like loading kernel + * modules) we can't do directly. (The setuid() capability will + * go away automatically when we setuid() or exec() -- the former + * is likely to come first.) + */ + caps = cap_init(); + cap_clear(caps); + cap_set_flag(caps, CAP_PERMITTED, sizeof(suidcaps)/sizeof(cap_value_t), suidcaps, CAP_SET); + cap_set_flag(caps, CAP_EFFECTIVE, sizeof(suidcaps)/sizeof(cap_value_t), suidcaps, CAP_SET); + cap_set_proc(caps); + cap_free(caps); + return OK; + } +#endif // Restore the configured unixd uid/gid. ap_unixd_config.user_id = saved_unixd_uid; ap_unixd_config.group_id = saved_unixd_gid; -#endif return OK; } @@ -377,15 +386,17 @@ err = 1; } else { #if HAVE_LIBCAP - /* Drop our remaining privileges. Normally setuid() would do this - * for us, but since we were previously not uid 0 (just a normal - * user with CAP_SETUID), we need to do it ourselves. - */ - cap_t caps; - caps = cap_init(); - cap_clear(caps); - cap_set_proc(caps); - cap_free(caps); + if (ap_itk_enable_caps) { + /* Drop our remaining privileges. Normally setuid() would do this + * for us, but since we were previously not uid 0 (just a normal + * user with CAP_SETUID), we need to do it ourselves. + */ + cap_t caps; + caps = cap_init(); + cap_clear(caps); + cap_set_proc(caps); + cap_free(caps); + } #endif ap_has_irreversibly_setuid = 1; } @@ -531,6 +542,20 @@ return NULL; } + +#if HAVE_LIBCAP +static const char *enable_caps(cmd_parms *cmd, void *dummy, int arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + ap_itk_enable_caps = arg; + return NULL; +} +#endif + + static const char *assign_user_id_expr (cmd_parms *cmd, void *ptr, const char *user_name_expr) { itk_per_dir_conf *dconf = (itk_per_dir_conf *) ptr; @@ -621,6 +646,13 @@ "If seccomp v2 is available (Linux 3.5.0+), limit the process's possible " "primary gid to the given range (inclusive endpoints). " "Note that this does not restrict supplemental gids!"), +#if HAVE_LIBCAP +AP_INIT_FLAG("EnableCapabilities", enable_caps, NULL, RSRC_CONF, + "Drop most root capabilities in the parent process, and instead run as " + "the user given by the User/Group directives with some extra capabilities " + "(in particular setuid). Somewhat more secure, but can cause problems " + "when serving from NFS."), +#endif AP_INIT_TAKE1("MaxClientsVHost", set_max_clients_vhost, NULL, RSRC_CONF, "Maximum number of children alive at the same time for this virtual host."), AP_INIT_TAKE1("NiceValue", set_nice_value, NULL, RSRC_CONF|ACCESS_CONF,