Isolation: mount tmpfs by default.
This commit is contained in:
76
src/nxt_fs.c
76
src/nxt_fs.c
@@ -40,30 +40,31 @@ nxt_fs_mount(nxt_task_t *task, nxt_fs_mount_t *mnt)
|
|||||||
nxt_int_t
|
nxt_int_t
|
||||||
nxt_fs_mount(nxt_task_t *task, nxt_fs_mount_t *mnt)
|
nxt_fs_mount(nxt_task_t *task, nxt_fs_mount_t *mnt)
|
||||||
{
|
{
|
||||||
|
u_char *data, *p, *end;
|
||||||
|
size_t iovlen;
|
||||||
|
nxt_int_t ret;
|
||||||
const char *fstype;
|
const char *fstype;
|
||||||
uint8_t is_bind, is_proc;
|
struct iovec iov[128];
|
||||||
struct iovec iov[8];
|
|
||||||
char errmsg[256];
|
char errmsg[256];
|
||||||
|
|
||||||
is_bind = nxt_strncmp(mnt->fstype, "bind", 4) == 0;
|
if (nxt_strncmp(mnt->fstype, "bind", 4) == 0) {
|
||||||
is_proc = nxt_strncmp(mnt->fstype, "proc", 4) == 0;
|
|
||||||
|
|
||||||
if (nxt_slow_path(!is_bind && !is_proc)) {
|
|
||||||
nxt_alert(task, "mount type \"%s\" not implemented.", mnt->fstype);
|
|
||||||
return NXT_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_bind) {
|
|
||||||
fstype = "nullfs";
|
fstype = "nullfs";
|
||||||
|
|
||||||
} else {
|
} else if (nxt_strncmp(mnt->fstype, "proc", 4) == 0) {
|
||||||
fstype = "procfs";
|
fstype = "procfs";
|
||||||
|
|
||||||
|
} else if (nxt_strncmp(mnt->fstype, "tmpfs", 5) == 0) {
|
||||||
|
fstype = "tmpfs";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
nxt_alert(task, "mount type \"%s\" not implemented.", mnt->fstype);
|
||||||
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
iov[0].iov_base = (void *) "fstype";
|
iov[0].iov_base = (void *) "fstype";
|
||||||
iov[0].iov_len = 7;
|
iov[0].iov_len = 7;
|
||||||
iov[1].iov_base = (void *) fstype;
|
iov[1].iov_base = (void *) fstype;
|
||||||
iov[1].iov_len = strlen(fstype) + 1;
|
iov[1].iov_len = nxt_strlen(fstype) + 1;
|
||||||
iov[2].iov_base = (void *) "fspath";
|
iov[2].iov_base = (void *) "fspath";
|
||||||
iov[2].iov_len = 7;
|
iov[2].iov_len = 7;
|
||||||
iov[3].iov_base = (void *) mnt->dst;
|
iov[3].iov_base = (void *) mnt->dst;
|
||||||
@@ -77,12 +78,55 @@ nxt_fs_mount(nxt_task_t *task, nxt_fs_mount_t *mnt)
|
|||||||
iov[7].iov_base = (void *) errmsg;
|
iov[7].iov_base = (void *) errmsg;
|
||||||
iov[7].iov_len = sizeof(errmsg);
|
iov[7].iov_len = sizeof(errmsg);
|
||||||
|
|
||||||
if (nxt_slow_path(nmount(iov, 8, 0) < 0)) {
|
iovlen = 8;
|
||||||
nxt_alert(task, "nmount(%p, 8, 0) %s", errmsg);
|
|
||||||
|
data = NULL;
|
||||||
|
|
||||||
|
if (mnt->data != NULL) {
|
||||||
|
data = (u_char *) nxt_strdup(mnt->data);
|
||||||
|
if (nxt_slow_path(data == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NXT_OK;
|
end = data - 1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
p = end + 1;
|
||||||
|
end = nxt_strchr(p, '=');
|
||||||
|
if (end == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
*end = '\0';
|
||||||
|
|
||||||
|
iov[iovlen++].iov_base = (void *) p;
|
||||||
|
iov[iovlen++].iov_len = (end - p) + 1;
|
||||||
|
|
||||||
|
p = end + 1;
|
||||||
|
|
||||||
|
end = nxt_strchr(p, ',');
|
||||||
|
if (end != NULL) {
|
||||||
|
*end = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
iov[iovlen++].iov_base = (void *) p;
|
||||||
|
iov[iovlen++].iov_len = nxt_strlen(p) + 1;
|
||||||
|
|
||||||
|
} while (end != NULL && nxt_nitems(iov) > (iovlen + 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = NXT_OK;
|
||||||
|
|
||||||
|
if (nxt_slow_path(nmount(iov, iovlen, 0) < 0)) {
|
||||||
|
nxt_alert(task, "nmount(%p, %d, 0) %s", iov, iovlen, errmsg);
|
||||||
|
ret = NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data != NULL) {
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
24
src/nxt_fs.h
24
src/nxt_fs.h
@@ -18,6 +18,30 @@
|
|||||||
#define NXT_MS_REC 0
|
#define NXT_MS_REC 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MS_NOSUID
|
||||||
|
#define NXT_MS_NOSUID MS_NOSUID
|
||||||
|
#else
|
||||||
|
#define NXT_MS_NOSUID 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MS_NOEXEC
|
||||||
|
#define NXT_MS_NOEXEC MS_NOEXEC
|
||||||
|
#else
|
||||||
|
#define NXT_MS_NOEXEC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MS_RELATIME
|
||||||
|
#define NXT_MS_RELATIME MS_RELATIME
|
||||||
|
#else
|
||||||
|
#define NXT_MS_RELATIME 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef MS_NODEV
|
||||||
|
#define NXT_MS_NODEV MS_NODEV
|
||||||
|
#else
|
||||||
|
#define NXT_MS_NODEV 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
u_char *src;
|
u_char *src;
|
||||||
|
|||||||
@@ -476,14 +476,12 @@ nxt_isolation_set_mounts(nxt_task_t *task, nxt_process_t *process,
|
|||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lang->mounts != NULL && lang->mounts->nelts > 0) {
|
|
||||||
ret = nxt_isolation_set_lang_mounts(task, process, lang->mounts);
|
ret = nxt_isolation_set_lang_mounts(task, process, lang->mounts);
|
||||||
if (nxt_slow_path(ret != NXT_OK)) {
|
if (nxt_slow_path(ret != NXT_OK)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
process->isolation.cleanup = nxt_isolation_unmount_all;
|
process->isolation.cleanup = nxt_isolation_unmount_all;
|
||||||
}
|
|
||||||
|
|
||||||
return NXT_OK;
|
return NXT_OK;
|
||||||
}
|
}
|
||||||
@@ -500,8 +498,6 @@ nxt_isolation_set_lang_mounts(nxt_task_t *task, nxt_process_t *process,
|
|||||||
const u_char *rootfs;
|
const u_char *rootfs;
|
||||||
nxt_fs_mount_t *mnt, *lang_mnt;
|
nxt_fs_mount_t *mnt, *lang_mnt;
|
||||||
|
|
||||||
rootfs = process->isolation.rootfs;
|
|
||||||
rootfs_len = nxt_strlen(rootfs);
|
|
||||||
mp = process->mem_pool;
|
mp = process->mem_pool;
|
||||||
|
|
||||||
/* copy to init mem pool */
|
/* copy to init mem pool */
|
||||||
@@ -514,11 +510,14 @@ nxt_isolation_set_lang_mounts(nxt_task_t *task, nxt_process_t *process,
|
|||||||
mnt = mounts->elts;
|
mnt = mounts->elts;
|
||||||
lang_mnt = lang_mounts->elts;
|
lang_mnt = lang_mounts->elts;
|
||||||
|
|
||||||
|
rootfs = process->isolation.rootfs;
|
||||||
|
rootfs_len = nxt_strlen(rootfs);
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
len = nxt_strlen(lang_mnt[i].dst);
|
len = nxt_strlen(lang_mnt[i].dst);
|
||||||
|
|
||||||
mnt[i].dst = nxt_mp_alloc(mp, rootfs_len + len + 1);
|
mnt[i].dst = nxt_mp_alloc(mp, rootfs_len + len + 1);
|
||||||
if (mnt[i].dst == NULL) {
|
if (nxt_slow_path(mnt[i].dst == NULL)) {
|
||||||
return NXT_ERROR;
|
return NXT_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,6 +526,52 @@ nxt_isolation_set_lang_mounts(nxt_task_t *task, nxt_process_t *process,
|
|||||||
*p = '\0';
|
*p = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mnt = nxt_array_add(mounts);
|
||||||
|
if (nxt_slow_path(mnt == NULL)) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
mnt->src = (u_char *) "tmpfs";
|
||||||
|
mnt->fstype = (u_char *) "tmpfs";
|
||||||
|
mnt->flags = NXT_MS_NOSUID | NXT_MS_NODEV | NXT_MS_NOEXEC | NXT_MS_RELATIME;
|
||||||
|
mnt->data = (u_char *) "size=1m,mode=777";
|
||||||
|
|
||||||
|
mnt->dst = nxt_mp_nget(mp, rootfs_len + nxt_length("/tmp") + 1);
|
||||||
|
if (nxt_slow_path(mnt->dst == NULL)) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = nxt_cpymem(mnt->dst, rootfs, rootfs_len);
|
||||||
|
p = nxt_cpymem(p, "/tmp", 4);
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
#if (NXT_HAVE_CLONE_NEWPID) && (NXT_HAVE_CLONE_NEWNS)
|
||||||
|
|
||||||
|
if (nxt_is_clone_flag_set(process->isolation.clone.flags, NEWPID)
|
||||||
|
&& nxt_is_clone_flag_set(process->isolation.clone.flags, NEWNS))
|
||||||
|
{
|
||||||
|
mnt = nxt_array_add(mounts);
|
||||||
|
if (nxt_slow_path(mnt == NULL)) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
mnt->fstype = (u_char *) "proc";
|
||||||
|
mnt->src = (u_char *) "proc";
|
||||||
|
|
||||||
|
mnt->dst = nxt_mp_nget(mp, rootfs_len + nxt_length("/proc") + 1);
|
||||||
|
if (nxt_slow_path(mnt->dst == NULL)) {
|
||||||
|
return NXT_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = nxt_cpymem(mnt->dst, rootfs, rootfs_len);
|
||||||
|
p = nxt_cpymem(p, "/proc", 5);
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
mnt->data = (u_char *) "";
|
||||||
|
mnt->flags = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
process->isolation.mounts = mounts;
|
process->isolation.mounts = mounts;
|
||||||
|
|
||||||
return NXT_OK;
|
return NXT_OK;
|
||||||
@@ -556,44 +601,12 @@ nxt_int_t
|
|||||||
nxt_isolation_prepare_rootfs(nxt_task_t *task, nxt_process_t *process)
|
nxt_isolation_prepare_rootfs(nxt_task_t *task, nxt_process_t *process)
|
||||||
{
|
{
|
||||||
size_t i, n;
|
size_t i, n;
|
||||||
nxt_int_t ret, hasproc;
|
nxt_int_t ret;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
nxt_array_t *mounts;
|
nxt_array_t *mounts;
|
||||||
const u_char *dst;
|
const u_char *dst;
|
||||||
nxt_fs_mount_t *mnt;
|
nxt_fs_mount_t *mnt;
|
||||||
|
|
||||||
hasproc = 0;
|
|
||||||
|
|
||||||
#if (NXT_HAVE_CLONE_NEWPID) && (NXT_HAVE_CLONE_NEWNS)
|
|
||||||
nxt_fs_mount_t mount;
|
|
||||||
|
|
||||||
if (nxt_is_clone_flag_set(process->isolation.clone.flags, NEWPID)
|
|
||||||
&& nxt_is_clone_flag_set(process->isolation.clone.flags, NEWNS))
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* This mount point will automatically be gone when the namespace is
|
|
||||||
* destroyed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
mount.fstype = (u_char *) "proc";
|
|
||||||
mount.src = (u_char *) "proc";
|
|
||||||
mount.dst = (u_char *) "/proc";
|
|
||||||
mount.data = (u_char *) "";
|
|
||||||
mount.flags = 0;
|
|
||||||
|
|
||||||
ret = nxt_fs_mkdir_all(mount.dst, S_IRWXU | S_IRWXG | S_IRWXO);
|
|
||||||
if (nxt_fast_path(ret == NXT_OK)) {
|
|
||||||
ret = nxt_fs_mount(task, &mount);
|
|
||||||
if (nxt_fast_path(ret == NXT_OK)) {
|
|
||||||
hasproc = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
nxt_log(task, NXT_LOG_WARN, "mkdir(%s) %E", mount.dst, nxt_errno);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mounts = process->isolation.mounts;
|
mounts = process->isolation.mounts;
|
||||||
|
|
||||||
n = mounts->nelts;
|
n = mounts->nelts;
|
||||||
@@ -609,12 +622,6 @@ nxt_isolation_prepare_rootfs(nxt_task_t *task, nxt_process_t *process)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasproc && nxt_memcmp(mnt[i].fstype, "proc", 4) == 0
|
|
||||||
&& nxt_memcmp(mnt[i].dst, "/proc", 5) == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = nxt_fs_mkdir_all(dst, S_IRWXU | S_IRWXG | S_IRWXO);
|
ret = nxt_fs_mkdir_all(dst, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||||
if (nxt_slow_path(ret != NXT_OK)) {
|
if (nxt_slow_path(ret != NXT_OK)) {
|
||||||
nxt_alert(task, "mkdir(%s) %E", dst, nxt_errno);
|
nxt_alert(task, "mkdir(%s) %E", dst, nxt_errno);
|
||||||
|
|||||||
@@ -84,7 +84,11 @@ nxt_runtime_create(nxt_task_t *task)
|
|||||||
lang->version = (u_char *) "";
|
lang->version = (u_char *) "";
|
||||||
lang->file = NULL;
|
lang->file = NULL;
|
||||||
lang->module = &nxt_external_module;
|
lang->module = &nxt_external_module;
|
||||||
lang->mounts = NULL;
|
|
||||||
|
lang->mounts = nxt_array_create(mp, 1, sizeof(nxt_fs_mount_t));
|
||||||
|
if (nxt_slow_path(lang->mounts == NULL)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
listen_sockets = nxt_array_create(mp, 1, sizeof(nxt_listen_socket_t));
|
listen_sockets = nxt_array_create(mp, 1, sizeof(nxt_listen_socket_t));
|
||||||
if (nxt_slow_path(listen_sockets == NULL)) {
|
if (nxt_slow_path(listen_sockets == NULL)) {
|
||||||
|
|||||||
@@ -30,6 +30,16 @@ nxt_strlen(s) \
|
|||||||
strlen((char *) s)
|
strlen((char *) s)
|
||||||
|
|
||||||
|
|
||||||
|
#define \
|
||||||
|
nxt_strdup(s) \
|
||||||
|
strdup((char *) s)
|
||||||
|
|
||||||
|
|
||||||
|
#define \
|
||||||
|
nxt_strchr(buf, delim) \
|
||||||
|
(u_char *) strchr((char *) buf, delim)
|
||||||
|
|
||||||
|
|
||||||
#define \
|
#define \
|
||||||
nxt_memzero(buf, length) \
|
nxt_memzero(buf, length) \
|
||||||
(void) memset(buf, 0, length)
|
(void) memset(buf, 0, length)
|
||||||
|
|||||||
Reference in New Issue
Block a user