From a90a93f1a4785a33ac0a48afa186e84645765d8a Mon Sep 17 00:00:00 2001 From: Gernot Vormayr Date: Tue, 2 Jul 2013 13:06:02 +0200 Subject: [PATCH] Add apparmor change hat functionality to fpm --- sapi/fpm/config.m4 | 17 +++++++++++++++++ sapi/fpm/fpm/fpm_conf.c | 6 ++++++ sapi/fpm/fpm/fpm_conf.h | 3 +++ sapi/fpm/fpm/fpm_unix.c | 30 ++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+) diff --git a/sapi/fpm/config.m4 b/sapi/fpm/config.m4 index 3d34c79588a..87c5a60c50d 100644 --- a/sapi/fpm/config.m4 +++ b/sapi/fpm/config.m4 @@ -536,6 +536,22 @@ AC_DEFUN([AC_FPM_SELECT], ]) dnl }}} +AC_DEFUN([AC_FPM_APPARMOR], +[ + AC_MSG_CHECKING([for apparmor]) + + SAVED_LIBS="$LIBS" + LIBS="$LIBS -lapparmor" + + AC_TRY_LINK([ #include ], [change_hat("test", 0);], [ + AC_DEFINE([HAVE_APPARMOR], 1, [do we have apparmor support?]) + AC_MSG_RESULT([yes]) + ], [ + LIBS="$SAVED_LIBS" + AC_MSG_RESULT([no]) + ]) +]) + AC_MSG_CHECKING(for FPM build) if test "$PHP_FPM" != "no"; then @@ -555,6 +571,7 @@ if test "$PHP_FPM" != "no"; then AC_FPM_EPOLL AC_FPM_POLL AC_FPM_SELECT + AC_FPM_APPARMOR PHP_ARG_WITH(fpm-user,, [ --with-fpm-user[=USER] Set the user for php-fpm to run as. (default: nobody)], nobody, no) diff --git a/sapi/fpm/fpm/fpm_conf.c b/sapi/fpm/fpm/fpm_conf.c index cd5fc34d0f2..9b699af99d8 100644 --- a/sapi/fpm/fpm/fpm_conf.c +++ b/sapi/fpm/fpm/fpm_conf.c @@ -149,6 +149,9 @@ static struct ini_value_parser_s ini_fpm_pool_options[] = { { "chdir", &fpm_conf_set_string, WPO(chdir) }, { "catch_workers_output", &fpm_conf_set_boolean, WPO(catch_workers_output) }, { "security.limit_extensions", &fpm_conf_set_string, WPO(security_limit_extensions) }, +#ifdef HAVE_APPARMOR + { "apparmor_hat", &fpm_conf_set_string, WPO(apparmor_hat) }, +#endif { 0, 0, 0 } }; @@ -644,6 +647,9 @@ int fpm_worker_pool_config_free(struct fpm_worker_pool_config_s *wpc) /* {{{ */ free(wpc->chroot); free(wpc->chdir); free(wpc->security_limit_extensions); +#ifdef HAVE_APPARMOR + free(wpc->apparmor_hat); +#endif for (kv = wpc->php_values; kv; kv = kv_next) { kv_next = kv->next; diff --git a/sapi/fpm/fpm/fpm_conf.h b/sapi/fpm/fpm/fpm_conf.h index efd65dc6d9d..8cd8690f187 100644 --- a/sapi/fpm/fpm/fpm_conf.h +++ b/sapi/fpm/fpm/fpm_conf.h @@ -87,6 +87,9 @@ struct fpm_worker_pool_config_s { struct key_value_s *env; struct key_value_s *php_admin_values; struct key_value_s *php_values; +#ifdef HAVE_APPARMOR + char *apparmor_hat; +#endif }; struct ini_value_parser_s { diff --git a/sapi/fpm/fpm/fpm_unix.c b/sapi/fpm/fpm/fpm_unix.c index 48249e8a494..1159a132472 100644 --- a/sapi/fpm/fpm/fpm_unix.c +++ b/sapi/fpm/fpm/fpm_unix.c @@ -17,6 +17,10 @@ #include #endif +#ifdef HAVE_APPARMOR +#include +#endif + #include "fpm.h" #include "fpm_conf.h" #include "fpm_cleanup.h" @@ -222,6 +226,32 @@ int fpm_unix_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ if (0 > fpm_clock_init()) { return -1; } + +#ifdef HAVE_APPARMOR + if (wp->config->apparmor_hat) { + char *con, *new_con; + if (aa_getcon(&con, NULL) == -1) { + zlog(ZLOG_SYSERROR, "[pool %s] failed to query apparmor confinement. Please check if \"/proc/*/attr/current\" is read and writeable.", wp->config->name); + return -1; + } + new_con = malloc(strlen(con) + strlen(wp->config->apparmor_hat) + 3); // // + 0 Byte + if (!new_con) { + zlog(ZLOG_SYSERROR, "[pool %s] failed to allocate memory for apparmor hat change.", wp->config->name); + return -1; + } + if (0 > sprintf(new_con, "%s//%s", con, wp->config->apparmor_hat)) { + zlog(ZLOG_SYSERROR, "[pool %s] failed to construct apparmor confinement.", wp->config->name); + return -1; + } + if (0 > aa_change_profile(new_con)) { + zlog(ZLOG_SYSERROR, "[pool %s] failed to change to new confinement (%s). Please check if \"/proc/*/attr/current\" is read and writeable and \"change_profile -> %s//*\" is allowed.", wp->config->name, new_con, con); + return -1; + } + free(con); + free(new_con); + } +#endif + return 0; } /* }}} */