]> granicus.if.org Git - php/commitdiff
Add apparmor change hat functionality to fpm
authorGernot Vormayr <gvormayr@gmail.com>
Tue, 2 Jul 2013 11:06:02 +0000 (13:06 +0200)
committerGernot Vormayr <gvormayr@gmail.com>
Tue, 2 Jul 2013 11:06:02 +0000 (13:06 +0200)
sapi/fpm/config.m4
sapi/fpm/fpm/fpm_conf.c
sapi/fpm/fpm/fpm_conf.h
sapi/fpm/fpm/fpm_unix.c

index 3d34c79588a3126c33221c627bcdf41893cf6261..87c5a60c50d0fa000354aa6569b10583211ff5f1 100644 (file)
@@ -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 <sys/apparmor.h> ], [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)
index cd5fc34d0f2d0e7b80e11fb32e4314033c297d7a..9b699af99d8ef5b05968131d1e43472a30f173a3 100644 (file)
@@ -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;
index efd65dc6d9d70f83ce469db6a5b14de35b1694a7..8cd8690f1874b688737180573a8b921d60b59312 100644 (file)
@@ -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 {
index 48249e8a49488bf3cab77245636dd2bd872870b3..1159a132472a19fd8b1f21fad47a46bd5ffe2659 100644 (file)
 #include <sys/prctl.h>
 #endif
 
+#ifdef HAVE_APPARMOR
+#include <sys/apparmor.h>
+#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;
 }
 /* }}} */