diff options
Diffstat (limited to '')
-rw-r--r-- | src/nxt_application.c | 17 | ||||
-rw-r--r-- | src/nxt_fs.c | 113 | ||||
-rw-r--r-- | src/nxt_fs.h | 65 | ||||
-rw-r--r-- | src/nxt_isolation.c | 86 | ||||
-rw-r--r-- | src/nxt_main_process.c | 10 | ||||
-rw-r--r-- | src/nxt_process.h | 2 |
6 files changed, 185 insertions, 108 deletions
diff --git a/src/nxt_application.c b/src/nxt_application.c index 3d08643c..5d58e60c 100644 --- a/src/nxt_application.c +++ b/src/nxt_application.c @@ -208,14 +208,14 @@ nxt_discovery_modules(nxt_task_t *task, const char *path) mounts = module[i].mounts; size += mounts->nelts * nxt_length("{\"src\": \"\", \"dst\": \"\", " - "\"fstype\": \"\", \"flags\": , " - "\"data\": \"\"},"); + "\"type\": , \"name\": \"\", " + "\"flags\": , \"data\": \"\"},"); mnt = mounts->elts; for (j = 0; j < mounts->nelts; j++) { size += nxt_strlen(mnt[j].src) + nxt_strlen(mnt[j].dst) - + nxt_strlen(mnt[j].fstype) + NXT_INT_T_LEN + + nxt_strlen(mnt[j].name) + (2 * NXT_INT_T_LEN) + (mnt[j].data == NULL ? 0 : nxt_strlen(mnt[j].data)); } } @@ -242,9 +242,10 @@ nxt_discovery_modules(nxt_task_t *task, const char *path) for (j = 0; j < mounts->nelts; j++) { p = nxt_sprintf(p, end, "{\"src\": \"%s\", \"dst\": \"%s\", " - "\"fstype\": \"%s\", \"flags\": %d, " + "\"name\": \"%s\", \"type\": %d, \"flags\": %d, " "\"data\": \"%s\"},", - mnt[j].src, mnt[j].dst, mnt[j].fstype, mnt[j].flags, + mnt[j].src, mnt[j].dst, mnt[j].name, mnt[j].type, + mnt[j].flags, mnt[j].data == NULL ? (u_char *) "" : mnt[j].data); } @@ -386,11 +387,13 @@ nxt_discovery_module(nxt_task_t *task, nxt_mp_t *mp, nxt_array_t *modules, goto fail; } - to->fstype = nxt_cstr_dup(mp, to->fstype, from->fstype); - if (nxt_slow_path(to->fstype == NULL)) { + to->name = nxt_cstr_dup(mp, to->name, from->name); + if (nxt_slow_path(to->name == NULL)) { goto fail; } + to->type = from->type; + if (from->data != NULL) { to->data = nxt_cstr_dup(mp, to->data, from->data); if (nxt_slow_path(to->data == NULL)) { diff --git a/src/nxt_fs.c b/src/nxt_fs.c index 0228c25a..87d3b4a5 100644 --- a/src/nxt_fs.c +++ b/src/nxt_fs.c @@ -18,15 +18,59 @@ static nxt_int_t nxt_fs_mkdir(const u_char *dir, mode_t mode); nxt_int_t nxt_fs_mount(nxt_task_t *task, nxt_fs_mount_t *mnt) { - int rc; + int rc; + const char *fsname; + unsigned long flags; - rc = mount((const char *) mnt->src, (const char *) mnt->dst, - (const char *) mnt->fstype, mnt->flags, mnt->data); + flags = 0; + + switch (mnt->type) { + case NXT_FS_BIND: + if (nxt_slow_path(mnt->flags != 0)) { + nxt_log(task, NXT_LOG_WARN, + "bind mount ignores additional flags"); + } + + fsname = "bind"; + flags = MS_BIND | MS_REC; + break; + + case NXT_FS_PROC: + fsname = "proc"; + goto getflags; + + case NXT_FS_TMP: + fsname = "tmpfs"; + goto getflags; + + default: + fsname = (const char *) mnt->name; + + getflags: + + if (mnt->flags & NXT_FS_FLAGS_NODEV) { + flags |= MS_NODEV; + } + + if (mnt->flags & NXT_FS_FLAGS_NOEXEC) { + flags |= MS_NOEXEC; + } + + if (mnt->flags & NXT_FS_FLAGS_NOSUID) { + flags |= MS_NOSUID; + } + + if (!(mnt->flags & NXT_FS_FLAGS_NOTIME)) { + flags |= MS_RELATIME; + } + } + + rc = mount((const char *) mnt->src, (const char *) mnt->dst, fsname, flags, + mnt->data); if (nxt_slow_path(rc < 0)) { - nxt_alert(task, "mount(\"%s\", \"%s\", \"%s\", %d, \"%s\") %E", - mnt->src, mnt->dst, mnt->fstype, mnt->flags, mnt->data, - nxt_errno); + nxt_alert(task, "mount(\"%s\", \"%s\", \"%s\", %ul, \"%s\") %E", + mnt->src, mnt->dst, fsname, flags, mnt->data, nxt_errno); return NXT_ERROR; } @@ -34,37 +78,66 @@ nxt_fs_mount(nxt_task_t *task, nxt_fs_mount_t *mnt) return NXT_OK; } - #elif (NXT_HAVE_FREEBSD_NMOUNT) nxt_int_t nxt_fs_mount(nxt_task_t *task, nxt_fs_mount_t *mnt) { + int flags; u_char *data, *p, *end; size_t iovlen; nxt_int_t ret; - const char *fstype; + const char *fsname; struct iovec iov[128]; char errmsg[256]; - if (nxt_strncmp(mnt->fstype, "bind", 4) == 0) { - fstype = "nullfs"; + if (nxt_slow_path((mnt->flags & NXT_FS_FLAGS_NODEV) && !mnt->builtin)) { + nxt_alert(task, "nmount(2) doesn't support \"nodev\" option"); - } else if (nxt_strncmp(mnt->fstype, "proc", 4) == 0) { - fstype = "procfs"; + return NXT_ERROR; + } - } else if (nxt_strncmp(mnt->fstype, "tmpfs", 5) == 0) { - fstype = "tmpfs"; + flags = 0; - } else { - nxt_alert(task, "mount type \"%s\" not implemented.", mnt->fstype); - return NXT_ERROR; + switch (mnt->type) { + case NXT_FS_BIND: + fsname = "nullfs"; + break; + + case NXT_FS_PROC: + fsname = "procfs"; + goto getflags; + + case NXT_FS_TMP: + fsname = "tmpfs"; + goto getflags; + + default: + fsname = (const char *) mnt->name; + + getflags: + + if (mnt->flags & NXT_FS_FLAGS_NOEXEC) { + flags |= MNT_NOEXEC; + } + + if (mnt->flags & NXT_FS_FLAGS_NOSUID) { + flags |= MNT_NOSUID; + } + + if (mnt->flags & NXT_FS_FLAGS_NOTIME) { + flags |= MNT_NOATIME; + } + + if (mnt->flags & NXT_FS_FLAGS_RDONLY) { + flags |= MNT_RDONLY; + } } iov[0].iov_base = (void *) "fstype"; iov[0].iov_len = 7; - iov[1].iov_base = (void *) fstype; - iov[1].iov_len = nxt_strlen(fstype) + 1; + iov[1].iov_base = (void *) fsname; + iov[1].iov_len = nxt_strlen(fsname) + 1; iov[2].iov_base = (void *) "fspath"; iov[2].iov_len = 7; iov[3].iov_base = (void *) mnt->dst; @@ -117,7 +190,7 @@ nxt_fs_mount(nxt_task_t *task, nxt_fs_mount_t *mnt) ret = NXT_OK; - if (nxt_slow_path(nmount(iov, iovlen, 0) < 0)) { + if (nxt_slow_path(nmount(iov, iovlen, flags) < 0)) { nxt_alert(task, "nmount(%p, %d, 0) %s", iov, iovlen, errmsg); ret = NXT_ERROR; } diff --git a/src/nxt_fs.h b/src/nxt_fs.h index bbd7ab9f..ff589979 100644 --- a/src/nxt_fs.h +++ b/src/nxt_fs.h @@ -6,50 +6,33 @@ #define _NXT_FS_H_INCLUDED_ -#ifdef MS_BIND -#define NXT_MS_BIND MS_BIND -#else -#define NXT_MS_BIND 0 -#endif - -#ifdef MS_REC -#define NXT_MS_REC MS_BIND -#else -#define NXT_MS_REC 0 -#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 enum { + NXT_FS_UNKNOWN = 0, + NXT_FS_BIND, + NXT_FS_TMP, + NXT_FS_PROC, + NXT_FS_LAST, +} nxt_fs_type_t; + + +typedef enum { + NXT_FS_FLAGS_NOSUID = 1 << 0, + NXT_FS_FLAGS_NOEXEC = 1 << 1, + NXT_FS_FLAGS_NOTIME = 1 << 2, + NXT_FS_FLAGS_NODEV = 1 << 3, + NXT_FS_FLAGS_RDONLY = 1 << 4, +} nxt_fs_flags_t; typedef struct { - u_char *src; - u_char *dst; - u_char *fstype; - nxt_int_t flags; - u_char *data; - nxt_uint_t builtin; /* 1-bit */ + u_char *src; + u_char *dst; + nxt_fs_type_t type; + u_char *name; + nxt_fs_flags_t flags; + u_char *data; + nxt_uint_t builtin; /* 1-bit */ + nxt_uint_t deps; /* 1-bit */ } nxt_fs_mount_t; diff --git a/src/nxt_isolation.c b/src/nxt_isolation.c index 03160de3..e0f169aa 100644 --- a/src/nxt_isolation.c +++ b/src/nxt_isolation.c @@ -87,15 +87,6 @@ nxt_isolation_main_prefork(nxt_task_t *task, nxt_process_t *process, } #endif -#if (NXT_HAVE_ISOLATION_ROOTFS) - if (process->isolation.rootfs != NULL) { - ret = nxt_isolation_set_mounts(task, process, &app_conf->type); - if (nxt_slow_path(ret != NXT_OK)) { - return ret; - } - } -#endif - if (cap_setid) { ret = nxt_process_creds_set(task, process, &app_conf->user, &app_conf->group); @@ -126,6 +117,29 @@ nxt_isolation_main_prefork(nxt_task_t *task, nxt_process_t *process, } } +#if (NXT_HAVE_ISOLATION_ROOTFS) + if (process->isolation.rootfs != NULL) { + nxt_int_t has_mnt; + + ret = nxt_isolation_set_mounts(task, process, &app_conf->type); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } + + has_mnt = 0; + +#if (NXT_HAVE_CLONE_NEWNS) + has_mnt = nxt_is_clone_flag_set(process->isolation.clone.flags, NEWNS); +#endif + + if (process->user_cred->uid == 0 && !has_mnt) { + nxt_log(task, NXT_LOG_WARN, + "setting user \"root\" with \"rootfs\" is unsafe without " + "\"mount\" namespace isolation"); + } + } +#endif + #if (NXT_HAVE_CLONE_NEWUSER) ret = nxt_isolation_vldt_creds(task, process); if (nxt_slow_path(ret != NXT_OK)) { @@ -568,10 +582,13 @@ nxt_isolation_set_lang_mounts(nxt_task_t *task, nxt_process_t *process, } 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->name = (u_char *) "tmpfs"; + mnt->type = NXT_FS_TMP; + mnt->flags = (NXT_FS_FLAGS_NOSUID | NXT_FS_FLAGS_NODEV + | NXT_FS_FLAGS_NOEXEC); mnt->data = (u_char *) "size=1m,mode=777"; mnt->builtin = 1; + mnt->deps = 0; mnt->dst = nxt_mp_nget(mp, rootfs_len + nxt_length("/tmp") + 1); if (nxt_slow_path(mnt->dst == NULL)) { @@ -582,32 +599,27 @@ nxt_isolation_set_lang_mounts(nxt_task_t *task, nxt_process_t *process, 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 = nxt_array_add(mounts); + if (nxt_slow_path(mnt == NULL)) { + return NXT_ERROR; + } - mnt->dst = nxt_mp_nget(mp, rootfs_len + nxt_length("/proc") + 1); - if (nxt_slow_path(mnt->dst == NULL)) { - return NXT_ERROR; - } + mnt->name = (u_char *) "proc"; + mnt->type = NXT_FS_PROC; + mnt->src = (u_char *) "none"; + 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'; + p = nxt_cpymem(mnt->dst, rootfs, rootfs_len); + p = nxt_cpymem(p, "/proc", 5); + *p = '\0'; - mnt->data = (u_char *) ""; - mnt->flags = 0; - } -#endif + mnt->data = (u_char *) ""; + mnt->flags = NXT_FS_FLAGS_NOEXEC | NXT_FS_FLAGS_NOSUID; + mnt->builtin = 1; + mnt->deps = 0; qsort(mounts->elts, mounts->nelts, sizeof(nxt_fs_mount_t), nxt_isolation_mount_compare); @@ -661,7 +673,7 @@ nxt_isolation_unmount_all(nxt_task_t *task, nxt_process_t *process) while (n > 0) { n--; - if (mnt[n].builtin && !automount->language_deps) { + if (mnt[n].deps && !automount->language_deps) { continue; } @@ -690,11 +702,11 @@ nxt_isolation_prepare_rootfs(nxt_task_t *task, nxt_process_t *process) for (i = 0; i < n; i++) { dst = mnt[i].dst; - if (mnt[i].builtin && !automount->language_deps) { + if (mnt[i].deps && !automount->language_deps) { continue; } - if (nxt_slow_path(nxt_memcmp(mnt[i].fstype, "bind", 4) == 0 + if (nxt_slow_path(mnt[i].type == NXT_FS_BIND && stat((const char *) mnt[i].src, &st) != 0)) { nxt_log(task, NXT_LOG_WARN, "host path not found: %s", mnt[i].src); diff --git a/src/nxt_main_process.c b/src/nxt_main_process.c index d2edab1d..e4ec8b57 100644 --- a/src/nxt_main_process.c +++ b/src/nxt_main_process.c @@ -1163,9 +1163,14 @@ static nxt_conf_map_t nxt_app_lang_mounts_map[] = { offsetof(nxt_fs_mount_t, dst), }, { - nxt_string("fstype"), + nxt_string("name"), NXT_CONF_MAP_CSTRZ, - offsetof(nxt_fs_mount_t, fstype), + offsetof(nxt_fs_mount_t, name), + }, + { + nxt_string("type"), + NXT_CONF_MAP_INT, + offsetof(nxt_fs_mount_t, type), }, { nxt_string("flags"), @@ -1297,6 +1302,7 @@ nxt_main_port_modules_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg) } mnt->builtin = 1; + mnt->deps = 1; ret = nxt_conf_map_object(rt->mem_pool, value, nxt_app_lang_mounts_map, diff --git a/src/nxt_process.h b/src/nxt_process.h index d9b4dff1..ddadb08f 100644 --- a/src/nxt_process.h +++ b/src/nxt_process.h @@ -74,7 +74,7 @@ typedef struct { typedef struct { - uint8_t language_deps; /* 1-byte */ + uint8_t language_deps; /* 1-bit */ } nxt_process_automount_t; |