summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorTiago Natel de Moura <t.nateldemoura@f5.com>2020-10-29 20:30:53 +0000
committerTiago Natel de Moura <t.nateldemoura@f5.com>2020-10-29 20:30:53 +0000
commit0390cb3a61051dd93e206d50591aff5759cf42fc (patch)
treed2105e88cbe4ef30a25243d7ccb07fae706c1003 /src
parent417f5d911ddb3a46b590d89e73313856a32ff435 (diff)
downloadunit-0390cb3a61051dd93e206d50591aff5759cf42fc.tar.gz
unit-0390cb3a61051dd93e206d50591aff5759cf42fc.tar.bz2
Isolation: mounting of procfs by default when using "rootfs".
Diffstat (limited to 'src')
-rw-r--r--src/nxt_application.c17
-rw-r--r--src/nxt_fs.c113
-rw-r--r--src/nxt_fs.h65
-rw-r--r--src/nxt_isolation.c86
-rw-r--r--src/nxt_main_process.c10
-rw-r--r--src/nxt_process.h2
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;