summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--auto/modules/php30
-rw-r--r--src/nxt_php_sapi.c162
-rw-r--r--test/test_php_isolation.py51
-rw-r--r--test/test_python_isolation.py30
4 files changed, 138 insertions, 135 deletions
diff --git a/auto/modules/php b/auto/modules/php
index 848fc1bc..41eeb1c3 100644
--- a/auto/modules/php
+++ b/auto/modules/php
@@ -59,12 +59,6 @@ NXT_PHP_MODULE=${NXT_PHP_MODULE=${NXT_PHP##*/}}
NXT_PHP_LIB_PATH=${NXT_PHP_LIB_PATH=}
NXT_PHP_LIB_STATIC=${NXT_PHP_LIB_STATIC=no}
NXT_PHP_ADDITIONAL_FLAGS=
-NXT_PHP_REALPATH=realpath
-
-
-if [ -z `which $NXT_PHP_REALPATH` ]; then
- NXT_PHP_REALPATH="readlink -e"
-fi
$echo "configuring PHP module"
@@ -81,12 +75,6 @@ if /bin/sh -c "${NXT_PHP_CONFIG} --version" >> $NXT_AUTOCONF_ERR 2>&1; then
NXT_PHP_VERSION="`${NXT_PHP_CONFIG} --version`"
NXT_PHP_EXT_DIR="`${NXT_PHP_CONFIG} --extension-dir`"
- NXT_PHP_LIBC_DIR="`${CC} --print-file-name=libc.so`"
- NXT_PHP_LIBC_DIR="`$NXT_PHP_REALPATH $NXT_PHP_LIBC_DIR`"
- NXT_PHP_LIBC_DIR="`dirname $NXT_PHP_LIBC_DIR`"
- NXT_PHP_SYSLIB_DIR="`${CC} --print-file-name=libtinfo.so`"
- NXT_PHP_SYSLIB_DIR="`$NXT_PHP_REALPATH $NXT_PHP_SYSLIB_DIR`"
- NXT_PHP_SYSLIB_DIR="`dirname $NXT_PHP_SYSLIB_DIR`"
$echo " + PHP SAPI: [`${NXT_PHP_CONFIG} --php-sapis`]"
@@ -228,21 +216,6 @@ if grep ^$NXT_PHP_MODULE: $NXT_MAKEFILE 2>&1 > /dev/null; then
fi
-NXT_PHP_MOUNTS_HEADER=nxt_${NXT_PHP_MODULE}_mounts.h
-
-cat << END > $NXT_BUILD_DIR/$NXT_PHP_MOUNTS_HEADER
-static const nxt_fs_mount_t nxt_php_mounts[] = {
- {(u_char *) "$NXT_PHP_EXT_DIR", (u_char *) "$NXT_PHP_EXT_DIR",
- (u_char *) "bind", NXT_MS_BIND | NXT_MS_REC, NULL, 1},
- {(u_char *) "$NXT_PHP_LIBC_DIR", (u_char *) "$NXT_PHP_LIBC_DIR",
- (u_char *) "bind", NXT_MS_BIND | NXT_MS_REC, NULL, 1},
- {(u_char *) "$NXT_PHP_SYSLIB_DIR", (u_char *) "$NXT_PHP_SYSLIB_DIR",
- (u_char *) "bind", NXT_MS_BIND | NXT_MS_REC, NULL, 1},
-};
-
-END
-
-
$echo " + PHP module: ${NXT_PHP_MODULE}.unit.so"
. auto/cc/deps
@@ -268,8 +241,7 @@ for nxt_src in $NXT_PHP_MODULE_SRCS; do
cat << END >> $NXT_MAKEFILE
$NXT_BUILD_DIR/$nxt_obj: $nxt_src $NXT_VERSION_H
- \$(CC) -c \$(CFLAGS) -DNXT_PHP_MOUNTS_H=\"$NXT_PHP_MOUNTS_HEADER\" \\
- $NXT_PHP_ADDITIONAL_FLAGS \$(NXT_INCS) \\
+ \$(CC) -c \$(CFLAGS) $NXT_PHP_ADDITIONAL_FLAGS \$(NXT_INCS) \\
$NXT_PHP_INCLUDE -DNXT_ZEND_SIGNAL_STARTUP=$NXT_ZEND_SIGNAL_STARTUP \\
$nxt_dep_flags \\
-o $NXT_BUILD_DIR/$nxt_obj $nxt_src
diff --git a/src/nxt_php_sapi.c b/src/nxt_php_sapi.c
index d7e5b476..de329ad7 100644
--- a/src/nxt_php_sapi.c
+++ b/src/nxt_php_sapi.c
@@ -14,8 +14,6 @@
#include <nxt_unit.h>
#include <nxt_unit_request.h>
-#include NXT_PHP_MOUNTS_H
-
#if PHP_VERSION_ID >= 50400
#define NXT_HAVE_PHP_IGNORE_CWD 1
@@ -79,9 +77,13 @@ typedef void (*zif_handler)(INTERNAL_FUNCTION_PARAMETERS);
#endif
+static nxt_int_t nxt_php_setup(nxt_task_t *task, nxt_process_t *process,
+ nxt_common_app_conf_t *conf);
static nxt_int_t nxt_php_start(nxt_task_t *task, nxt_process_data_t *data);
static nxt_int_t nxt_php_set_target(nxt_task_t *task, nxt_php_target_t *target,
nxt_conf_value_t *conf);
+static nxt_int_t nxt_php_set_ini_path(nxt_task_t *task, nxt_str_t *path,
+ char *workdir);
static void nxt_php_set_options(nxt_task_t *task, nxt_conf_value_t *options,
int type);
static nxt_int_t nxt_php_alter_option(nxt_str_t *name, nxt_str_t *value,
@@ -252,9 +254,9 @@ NXT_EXPORT nxt_app_module_t nxt_app_module = {
compat,
nxt_string("php"),
PHP_VERSION,
- nxt_php_mounts,
- nxt_nitems(nxt_php_mounts),
NULL,
+ 0,
+ nxt_php_setup,
nxt_php_start,
};
@@ -269,55 +271,20 @@ static void ***tsrm_ls;
static nxt_int_t
-nxt_php_start(nxt_task_t *task, nxt_process_data_t *data)
+nxt_php_setup(nxt_task_t *task, nxt_process_t *process,
+ nxt_common_app_conf_t *conf)
{
- u_char *p;
- uint32_t next;
- nxt_str_t ini_path, name;
- nxt_int_t ret;
- nxt_uint_t n;
- nxt_unit_ctx_t *unit_ctx;
- nxt_unit_init_t php_init;
- nxt_conf_value_t *value;
- nxt_php_app_conf_t *c;
- nxt_common_app_conf_t *conf;
+ nxt_str_t ini_path;
+ nxt_int_t ret;
+ nxt_conf_value_t *value;
+ nxt_php_app_conf_t *c;
static nxt_str_t file_str = nxt_string("file");
static nxt_str_t user_str = nxt_string("user");
static nxt_str_t admin_str = nxt_string("admin");
- conf = data->app;
c = &conf->u.php;
- n = (c->targets != NULL) ? nxt_conf_object_members_count(c->targets) : 1;
-
- nxt_php_targets = nxt_zalloc(sizeof(nxt_php_target_t) * n);
- if (nxt_slow_path(nxt_php_targets == NULL)) {
- return NXT_ERROR;
- }
-
- if (c->targets != NULL) {
- next = 0;
-
- for (n = 0; /* void */; n++) {
- value = nxt_conf_next_object_member(c->targets, &name, &next);
- if (value == NULL) {
- break;
- }
-
- ret = nxt_php_set_target(task, &nxt_php_targets[n], value);
- if (nxt_slow_path(ret != NXT_OK)) {
- return NXT_ERROR;
- }
- }
-
- } else {
- ret = nxt_php_set_target(task, &nxt_php_targets[0], conf->self);
- if (nxt_slow_path(ret != NXT_OK)) {
- return NXT_ERROR;
- }
- }
-
#ifdef ZTS
#if PHP_VERSION_ID >= 70400
@@ -347,15 +314,12 @@ nxt_php_start(nxt_task_t *task, nxt_process_data_t *data)
if (value != NULL) {
nxt_conf_get_string(value, &ini_path);
- p = nxt_malloc(ini_path.length + 1);
- if (nxt_slow_path(p == NULL)) {
+ ret = nxt_php_set_ini_path(task, &ini_path,
+ conf->working_directory);
+
+ if (nxt_slow_path(ret != NXT_OK)) {
return NXT_ERROR;
}
-
- nxt_php_sapi_module.php_ini_path_override = (char *) p;
-
- p = nxt_cpymem(p, ini_path.start, ini_path.length);
- *p = '\0';
}
}
@@ -372,6 +336,55 @@ nxt_php_start(nxt_task_t *task, nxt_process_data_t *data)
nxt_php_set_options(task, value, ZEND_INI_USER);
}
+ return NXT_OK;
+}
+
+
+static nxt_int_t
+nxt_php_start(nxt_task_t *task, nxt_process_data_t *data)
+{
+ uint32_t next;
+ nxt_int_t ret;
+ nxt_str_t name;
+ nxt_uint_t n;
+ nxt_unit_ctx_t *unit_ctx;
+ nxt_unit_init_t php_init;
+ nxt_conf_value_t *value;
+ nxt_php_app_conf_t *c;
+ nxt_common_app_conf_t *conf;
+
+ conf = data->app;
+ c = &conf->u.php;
+
+ n = (c->targets != NULL) ? nxt_conf_object_members_count(c->targets) : 1;
+
+ nxt_php_targets = nxt_zalloc(sizeof(nxt_php_target_t) * n);
+ if (nxt_slow_path(nxt_php_targets == NULL)) {
+ return NXT_ERROR;
+ }
+
+ if (c->targets != NULL) {
+ next = 0;
+
+ for (n = 0; /* void */; n++) {
+ value = nxt_conf_next_object_member(c->targets, &name, &next);
+ if (value == NULL) {
+ break;
+ }
+
+ ret = nxt_php_set_target(task, &nxt_php_targets[n], value);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return NXT_ERROR;
+ }
+ }
+
+ } else {
+ ret = nxt_php_set_target(task, &nxt_php_targets[0], conf->self);
+ if (nxt_slow_path(ret != NXT_OK)) {
+ return NXT_ERROR;
+ }
+ }
+
ret = nxt_unit_default_init(task, &php_init);
if (nxt_slow_path(ret != NXT_OK)) {
nxt_alert(task, "nxt_unit_default_init() failed");
@@ -388,9 +401,8 @@ nxt_php_start(nxt_task_t *task, nxt_process_data_t *data)
nxt_php_unit_ctx = unit_ctx;
- nxt_unit_run(unit_ctx);
-
- nxt_unit_done(unit_ctx);
+ nxt_unit_run(nxt_php_unit_ctx);
+ nxt_unit_done(nxt_php_unit_ctx);
exit(0);
@@ -512,6 +524,46 @@ nxt_php_set_target(nxt_task_t *task, nxt_php_target_t *target,
}
+static nxt_int_t
+nxt_php_set_ini_path(nxt_task_t *task, nxt_str_t *ini_path, char *workdir)
+{
+ size_t wdlen;
+ u_char *p, *start;
+
+ if (ini_path->start[0] == '/' || workdir == NULL) {
+ p = nxt_malloc(ini_path->length + 1);
+ if (nxt_slow_path(p == NULL)) {
+ return NXT_ERROR;
+ }
+
+ start = p;
+
+ } else {
+ wdlen = nxt_strlen(workdir);
+
+ p = nxt_malloc(wdlen + ini_path->length + 2);
+ if (nxt_slow_path(p == NULL)) {
+ return NXT_ERROR;
+ }
+
+ start = p;
+
+ p = nxt_cpymem(p, workdir, wdlen);
+
+ if (workdir[wdlen - 1] != '/') {
+ *p++ = '/';
+ }
+ }
+
+ p = nxt_cpymem(p, ini_path->start, ini_path->length);
+ *p = '\0';
+
+ nxt_php_sapi_module.php_ini_path_override = (char *) start;
+
+ return NXT_OK;
+}
+
+
static void
nxt_php_set_options(nxt_task_t *task, nxt_conf_value_t *options, int type)
{
diff --git a/test/test_php_isolation.py b/test/test_php_isolation.py
index f4170f1b..556bd387 100644
--- a/test/test_php_isolation.py
+++ b/test/test_php_isolation.py
@@ -85,54 +85,3 @@ class TestPHPIsolation(TestApplicationPHP):
assert 'json' in extensions, 'json in extensions list'
assert 'unit' in extensions, 'unit in extensions list'
-
- def test_php_isolation_rootfs_no_language_libs(self, is_su):
- isolation_features = self.available['features']['isolation'].keys()
-
- if not is_su:
- if 'user' not in isolation_features:
- pytest.skip('requires unprivileged userns or root')
-
- if not 'unprivileged_userns_clone' in isolation_features:
- pytest.skip('requires unprivileged userns or root')
-
- if 'mnt' not in isolation_features:
- pytest.skip('requires mnt ns')
-
- isolation = {
- 'rootfs': option.test_dir,
- 'automount': {'language_deps': False},
- 'namespaces': {'credential': not is_su, 'mount': not is_su},
- }
-
- self.load('list-extensions', isolation=isolation)
-
- assert 'success' in self.conf(
- '"/php/list-extensions"', 'applications/list-extensions/root'
- )
-
- assert 'success' in self.conf(
- {'file': '/php/list-extensions/php.ini'},
- 'applications/list-extensions/options',
- )
-
- assert 'success' in self.conf(
- '"/php/list-extensions"',
- 'applications/list-extensions/working_directory',
- )
-
- extensions = self.getjson()['body']
-
- assert 'unit' in extensions, 'unit in extensions list'
- assert 'json' not in extensions, 'json not in extensions list'
-
- assert 'success' in self.conf(
- {'language_deps': True},
- 'applications/list-extensions/isolation/automount',
- )
-
- extensions = self.getjson()['body']
-
- assert 'unit' in extensions, 'unit in extensions list 2'
- assert 'json' in extensions, 'json in extensions list 2'
-
diff --git a/test/test_python_isolation.py b/test/test_python_isolation.py
index 564ec79c..59ac670a 100644
--- a/test/test_python_isolation.py
+++ b/test/test_python_isolation.py
@@ -65,3 +65,33 @@ class TestPythonIsolation(TestApplicationPython):
assert (
ret['body']['FileExists'] == True
), 'application exists in rootfs'
+
+ def test_python_isolation_rootfs_no_language_deps(self, is_su):
+ isolation_features = self.available['features']['isolation'].keys()
+
+ if 'mnt' not in isolation_features:
+ pytest.skip('requires mnt ns')
+
+ if not is_su:
+ if 'user' not in isolation_features:
+ pytest.skip('requires unprivileged userns or root')
+
+ if not 'unprivileged_userns_clone' in isolation_features:
+ pytest.skip('requires unprivileged userns or root')
+
+ isolation = {
+ 'namespaces': {'credential': not is_su, 'mount': True},
+ 'rootfs': self.temp_dir,
+ 'automount': {'language_deps': False}
+ }
+
+ self.load('empty', isolation=isolation)
+
+ assert (self.get()['status'] != 200), 'disabled language_deps'
+
+ isolation['automount']['language_deps'] = True
+
+ self.load('empty', isolation=isolation)
+
+ assert (self.get()['status'] == 200), 'enabled language_deps'
+