11579St.nateldemoura@f5.com /*
21579St.nateldemoura@f5.com * Copyright (C) NGINX, Inc.
31579St.nateldemoura@f5.com */
41579St.nateldemoura@f5.com
51579St.nateldemoura@f5.com #include <nxt_main.h>
61579St.nateldemoura@f5.com #include <nxt_application.h>
71579St.nateldemoura@f5.com #include <nxt_process.h>
81579St.nateldemoura@f5.com #include <nxt_isolation.h>
92260Sa.clayton@nginx.com #include <nxt_cgroup.h>
101579St.nateldemoura@f5.com
112169Salx.manpages@gmail.com #if (NXT_HAVE_MNTENT_H)
121579St.nateldemoura@f5.com #include <mntent.h>
131579St.nateldemoura@f5.com #endif
141579St.nateldemoura@f5.com
151579St.nateldemoura@f5.com
161579St.nateldemoura@f5.com static nxt_int_t nxt_isolation_set(nxt_task_t *task,
171579St.nateldemoura@f5.com nxt_conf_value_t *isolation, nxt_process_t *process);
181579St.nateldemoura@f5.com
192260Sa.clayton@nginx.com #if (NXT_HAVE_CGROUP)
202260Sa.clayton@nginx.com static nxt_int_t nxt_isolation_set_cgroup(nxt_task_t *task,
212260Sa.clayton@nginx.com nxt_conf_value_t *isolation, nxt_process_t *process);
222260Sa.clayton@nginx.com #endif
232260Sa.clayton@nginx.com
242321Sa.clayton@nginx.com #if (NXT_HAVE_LINUX_NS)
251579St.nateldemoura@f5.com static nxt_int_t nxt_isolation_set_namespaces(nxt_task_t *task,
261579St.nateldemoura@f5.com nxt_conf_value_t *isolation, nxt_process_t *process);
271579St.nateldemoura@f5.com static nxt_int_t nxt_isolation_clone_flags(nxt_task_t *task,
281579St.nateldemoura@f5.com nxt_conf_value_t *namespaces, nxt_clone_t *clone);
291579St.nateldemoura@f5.com #endif
301579St.nateldemoura@f5.com
311579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUSER)
321579St.nateldemoura@f5.com static nxt_int_t nxt_isolation_set_creds(nxt_task_t *task,
331579St.nateldemoura@f5.com nxt_conf_value_t *isolation, nxt_process_t *process);
341579St.nateldemoura@f5.com static nxt_int_t nxt_isolation_credential_map(nxt_task_t *task,
351579St.nateldemoura@f5.com nxt_mp_t *mem_pool, nxt_conf_value_t *map_array,
361579St.nateldemoura@f5.com nxt_clone_credential_map_t *map);
371579St.nateldemoura@f5.com static nxt_int_t nxt_isolation_vldt_creds(nxt_task_t *task,
381579St.nateldemoura@f5.com nxt_process_t *process);
391579St.nateldemoura@f5.com #endif
401579St.nateldemoura@f5.com
411579St.nateldemoura@f5.com #if (NXT_HAVE_ISOLATION_ROOTFS)
421579St.nateldemoura@f5.com static nxt_int_t nxt_isolation_set_rootfs(nxt_task_t *task,
431579St.nateldemoura@f5.com nxt_conf_value_t *isolation, nxt_process_t *process);
441585St.nateldemoura@f5.com static nxt_int_t nxt_isolation_set_automount(nxt_task_t *task,
451585St.nateldemoura@f5.com nxt_conf_value_t *isolation, nxt_process_t *process);
461579St.nateldemoura@f5.com static nxt_int_t nxt_isolation_set_mounts(nxt_task_t *task,
471579St.nateldemoura@f5.com nxt_process_t *process, nxt_str_t *app_type);
481579St.nateldemoura@f5.com static nxt_int_t nxt_isolation_set_lang_mounts(nxt_task_t *task,
491579St.nateldemoura@f5.com nxt_process_t *process, nxt_array_t *syspaths);
501671St.nateldemoura@f5.com static int nxt_cdecl nxt_isolation_mount_compare(const void *v1,
511671St.nateldemoura@f5.com const void *v2);
521579St.nateldemoura@f5.com static void nxt_isolation_unmount_all(nxt_task_t *task, nxt_process_t *process);
531579St.nateldemoura@f5.com
542170Salx.manpages@gmail.com #if (NXT_HAVE_LINUX_PIVOT_ROOT) && (NXT_HAVE_CLONE_NEWNS)
551579St.nateldemoura@f5.com static nxt_int_t nxt_isolation_pivot_root(nxt_task_t *task, const char *rootfs);
561579St.nateldemoura@f5.com static nxt_int_t nxt_isolation_make_private_mount(nxt_task_t *task,
571579St.nateldemoura@f5.com const char *rootfs);
581579St.nateldemoura@f5.com nxt_inline int nxt_pivot_root(const char *new_root, const char *old_root);
591579St.nateldemoura@f5.com #endif
601579St.nateldemoura@f5.com
611579St.nateldemoura@f5.com static nxt_int_t nxt_isolation_chroot(nxt_task_t *task, const char *path);
621579St.nateldemoura@f5.com #endif
631579St.nateldemoura@f5.com
641579St.nateldemoura@f5.com #if (NXT_HAVE_PR_SET_NO_NEW_PRIVS)
651579St.nateldemoura@f5.com static nxt_int_t nxt_isolation_set_new_privs(nxt_task_t *task,
661579St.nateldemoura@f5.com nxt_conf_value_t *isolation, nxt_process_t *process);
671579St.nateldemoura@f5.com #endif
681579St.nateldemoura@f5.com
691579St.nateldemoura@f5.com
701579St.nateldemoura@f5.com nxt_int_t
nxt_isolation_main_prefork(nxt_task_t * task,nxt_process_t * process,nxt_mp_t * mp)711579St.nateldemoura@f5.com nxt_isolation_main_prefork(nxt_task_t *task, nxt_process_t *process,
721579St.nateldemoura@f5.com nxt_mp_t *mp)
731579St.nateldemoura@f5.com {
741579St.nateldemoura@f5.com nxt_int_t cap_setid;
751579St.nateldemoura@f5.com nxt_int_t ret;
761579St.nateldemoura@f5.com nxt_runtime_t *rt;
771579St.nateldemoura@f5.com nxt_common_app_conf_t *app_conf;
781579St.nateldemoura@f5.com
791579St.nateldemoura@f5.com rt = task->thread->runtime;
801579St.nateldemoura@f5.com app_conf = process->data.app;
811579St.nateldemoura@f5.com cap_setid = rt->capabilities.setid;
821579St.nateldemoura@f5.com
83*2379Sa.clayton@nginx.com #if (NXT_HAVE_PR_SET_NO_NEW_PRIVS)
84*2379Sa.clayton@nginx.com process->isolation.new_privs = 1;
85*2379Sa.clayton@nginx.com #endif
86*2379Sa.clayton@nginx.com
871579St.nateldemoura@f5.com if (app_conf->isolation != NULL) {
881579St.nateldemoura@f5.com ret = nxt_isolation_set(task, app_conf->isolation, process);
891579St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
901579St.nateldemoura@f5.com return ret;
911579St.nateldemoura@f5.com }
921579St.nateldemoura@f5.com }
931579St.nateldemoura@f5.com
941579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUSER)
951579St.nateldemoura@f5.com if (nxt_is_clone_flag_set(process->isolation.clone.flags, NEWUSER)) {
961579St.nateldemoura@f5.com cap_setid = 1;
971579St.nateldemoura@f5.com }
981579St.nateldemoura@f5.com #endif
991579St.nateldemoura@f5.com
1001579St.nateldemoura@f5.com if (cap_setid) {
1011579St.nateldemoura@f5.com ret = nxt_process_creds_set(task, process, &app_conf->user,
1021579St.nateldemoura@f5.com &app_conf->group);
1031579St.nateldemoura@f5.com
1041579St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
1051579St.nateldemoura@f5.com return ret;
1061579St.nateldemoura@f5.com }
1071579St.nateldemoura@f5.com
1081579St.nateldemoura@f5.com } else {
1091579St.nateldemoura@f5.com if (!nxt_str_eq(&app_conf->user, (u_char *) rt->user_cred.user,
1101579St.nateldemoura@f5.com nxt_strlen(rt->user_cred.user)))
1111579St.nateldemoura@f5.com {
1121579St.nateldemoura@f5.com nxt_alert(task, "cannot set user \"%V\" for app \"%V\": "
1131579St.nateldemoura@f5.com "missing capabilities", &app_conf->user, &app_conf->name);
1141579St.nateldemoura@f5.com
1151579St.nateldemoura@f5.com return NXT_ERROR;
1161579St.nateldemoura@f5.com }
1171579St.nateldemoura@f5.com
1181579St.nateldemoura@f5.com if (app_conf->group.length > 0
1191579St.nateldemoura@f5.com && !nxt_str_eq(&app_conf->group, (u_char *) rt->group,
1201579St.nateldemoura@f5.com nxt_strlen(rt->group)))
1211579St.nateldemoura@f5.com {
1221579St.nateldemoura@f5.com nxt_alert(task, "cannot set group \"%V\" for app \"%V\": "
1231579St.nateldemoura@f5.com "missing capabilities", &app_conf->group,
1241579St.nateldemoura@f5.com &app_conf->name);
1251579St.nateldemoura@f5.com
1261579St.nateldemoura@f5.com return NXT_ERROR;
1271579St.nateldemoura@f5.com }
1281579St.nateldemoura@f5.com }
1291579St.nateldemoura@f5.com
1301673St.nateldemoura@f5.com #if (NXT_HAVE_ISOLATION_ROOTFS)
1311673St.nateldemoura@f5.com if (process->isolation.rootfs != NULL) {
1321673St.nateldemoura@f5.com nxt_int_t has_mnt;
1331673St.nateldemoura@f5.com
1341673St.nateldemoura@f5.com ret = nxt_isolation_set_mounts(task, process, &app_conf->type);
1351673St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
1361673St.nateldemoura@f5.com return ret;
1371673St.nateldemoura@f5.com }
1381673St.nateldemoura@f5.com
1391673St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWNS)
1401673St.nateldemoura@f5.com has_mnt = nxt_is_clone_flag_set(process->isolation.clone.flags, NEWNS);
1411927Smax.romanov@nginx.com #else
1421927Smax.romanov@nginx.com has_mnt = 0;
1431673St.nateldemoura@f5.com #endif
1441673St.nateldemoura@f5.com
1451673St.nateldemoura@f5.com if (process->user_cred->uid == 0 && !has_mnt) {
1461673St.nateldemoura@f5.com nxt_log(task, NXT_LOG_WARN,
1471673St.nateldemoura@f5.com "setting user \"root\" with \"rootfs\" is unsafe without "
1481673St.nateldemoura@f5.com "\"mount\" namespace isolation");
1491673St.nateldemoura@f5.com }
1501673St.nateldemoura@f5.com }
1511673St.nateldemoura@f5.com #endif
1521673St.nateldemoura@f5.com
1531579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUSER)
1541579St.nateldemoura@f5.com ret = nxt_isolation_vldt_creds(task, process);
1551579St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
1561579St.nateldemoura@f5.com return ret;
1571579St.nateldemoura@f5.com }
1581579St.nateldemoura@f5.com #endif
1591579St.nateldemoura@f5.com
1601579St.nateldemoura@f5.com return NXT_OK;
1611579St.nateldemoura@f5.com }
1621579St.nateldemoura@f5.com
1631579St.nateldemoura@f5.com
1641579St.nateldemoura@f5.com static nxt_int_t
nxt_isolation_set(nxt_task_t * task,nxt_conf_value_t * isolation,nxt_process_t * process)1651579St.nateldemoura@f5.com nxt_isolation_set(nxt_task_t *task, nxt_conf_value_t *isolation,
1661579St.nateldemoura@f5.com nxt_process_t *process)
1671579St.nateldemoura@f5.com {
1682260Sa.clayton@nginx.com #if (NXT_HAVE_CGROUP)
1692260Sa.clayton@nginx.com if (nxt_slow_path(nxt_isolation_set_cgroup(task, isolation, process)
1702260Sa.clayton@nginx.com != NXT_OK))
1712260Sa.clayton@nginx.com {
1722260Sa.clayton@nginx.com return NXT_ERROR;
1732260Sa.clayton@nginx.com }
1742260Sa.clayton@nginx.com #endif
1752260Sa.clayton@nginx.com
1762321Sa.clayton@nginx.com #if (NXT_HAVE_LINUX_NS)
1771579St.nateldemoura@f5.com if (nxt_slow_path(nxt_isolation_set_namespaces(task, isolation, process)
1781579St.nateldemoura@f5.com != NXT_OK))
1791579St.nateldemoura@f5.com {
1801579St.nateldemoura@f5.com return NXT_ERROR;
1811579St.nateldemoura@f5.com }
1821579St.nateldemoura@f5.com #endif
1831579St.nateldemoura@f5.com
1841579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUSER)
1851579St.nateldemoura@f5.com if (nxt_slow_path(nxt_isolation_set_creds(task, isolation, process)
1861579St.nateldemoura@f5.com != NXT_OK))
1871579St.nateldemoura@f5.com {
1881579St.nateldemoura@f5.com return NXT_ERROR;
1891579St.nateldemoura@f5.com }
1901579St.nateldemoura@f5.com #endif
1911579St.nateldemoura@f5.com
1921579St.nateldemoura@f5.com #if (NXT_HAVE_ISOLATION_ROOTFS)
1931579St.nateldemoura@f5.com if (nxt_slow_path(nxt_isolation_set_rootfs(task, isolation, process)
1941579St.nateldemoura@f5.com != NXT_OK))
1951579St.nateldemoura@f5.com {
1961579St.nateldemoura@f5.com return NXT_ERROR;
1971579St.nateldemoura@f5.com }
1981585St.nateldemoura@f5.com
1991585St.nateldemoura@f5.com if (nxt_slow_path(nxt_isolation_set_automount(task, isolation, process)
2001585St.nateldemoura@f5.com != NXT_OK))
2011585St.nateldemoura@f5.com {
2021585St.nateldemoura@f5.com return NXT_ERROR;
2031585St.nateldemoura@f5.com }
2041579St.nateldemoura@f5.com #endif
2051579St.nateldemoura@f5.com
2061579St.nateldemoura@f5.com #if (NXT_HAVE_PR_SET_NO_NEW_PRIVS)
2071579St.nateldemoura@f5.com if (nxt_slow_path(nxt_isolation_set_new_privs(task, isolation, process)
2081579St.nateldemoura@f5.com != NXT_OK))
2091579St.nateldemoura@f5.com {
2101579St.nateldemoura@f5.com return NXT_ERROR;
2111579St.nateldemoura@f5.com }
2121579St.nateldemoura@f5.com #endif
2131579St.nateldemoura@f5.com
2141579St.nateldemoura@f5.com return NXT_OK;
2151579St.nateldemoura@f5.com }
2161579St.nateldemoura@f5.com
2171579St.nateldemoura@f5.com
2182260Sa.clayton@nginx.com #if (NXT_HAVE_CGROUP)
2192260Sa.clayton@nginx.com
2202260Sa.clayton@nginx.com static nxt_int_t
nxt_isolation_set_cgroup(nxt_task_t * task,nxt_conf_value_t * isolation,nxt_process_t * process)2212260Sa.clayton@nginx.com nxt_isolation_set_cgroup(nxt_task_t *task, nxt_conf_value_t *isolation,
2222260Sa.clayton@nginx.com nxt_process_t *process)
2232260Sa.clayton@nginx.com {
2242260Sa.clayton@nginx.com nxt_str_t str;
2252260Sa.clayton@nginx.com nxt_conf_value_t *obj;
2262260Sa.clayton@nginx.com
2272260Sa.clayton@nginx.com static nxt_str_t cgname = nxt_string("cgroup");
2282260Sa.clayton@nginx.com static nxt_str_t path = nxt_string("path");
2292260Sa.clayton@nginx.com
2302260Sa.clayton@nginx.com obj = nxt_conf_get_object_member(isolation, &cgname, NULL);
2312260Sa.clayton@nginx.com if (obj == NULL) {
2322260Sa.clayton@nginx.com return NXT_OK;
2332260Sa.clayton@nginx.com }
2342260Sa.clayton@nginx.com
2352260Sa.clayton@nginx.com obj = nxt_conf_get_object_member(obj, &path, NULL);
2362260Sa.clayton@nginx.com if (obj == NULL) {
2372260Sa.clayton@nginx.com return NXT_ERROR;
2382260Sa.clayton@nginx.com }
2392260Sa.clayton@nginx.com
2402260Sa.clayton@nginx.com nxt_conf_get_string(obj, &str);
2412260Sa.clayton@nginx.com process->isolation.cgroup.path = nxt_mp_alloc(process->mem_pool,
2422260Sa.clayton@nginx.com str.length + 1);
2432260Sa.clayton@nginx.com nxt_memcpy(process->isolation.cgroup.path, str.start, str.length);
2442260Sa.clayton@nginx.com process->isolation.cgroup.path[str.length] = '\0';
2452260Sa.clayton@nginx.com
2462260Sa.clayton@nginx.com process->isolation.cgroup_cleanup = nxt_cgroup_cleanup;
2472260Sa.clayton@nginx.com
2482260Sa.clayton@nginx.com return NXT_OK;
2492260Sa.clayton@nginx.com }
2502260Sa.clayton@nginx.com
2512260Sa.clayton@nginx.com #endif
2522260Sa.clayton@nginx.com
2532260Sa.clayton@nginx.com
2542321Sa.clayton@nginx.com #if (NXT_HAVE_LINUX_NS)
2551579St.nateldemoura@f5.com
2561579St.nateldemoura@f5.com static nxt_int_t
nxt_isolation_set_namespaces(nxt_task_t * task,nxt_conf_value_t * isolation,nxt_process_t * process)2571579St.nateldemoura@f5.com nxt_isolation_set_namespaces(nxt_task_t *task, nxt_conf_value_t *isolation,
2581579St.nateldemoura@f5.com nxt_process_t *process)
2591579St.nateldemoura@f5.com {
2601579St.nateldemoura@f5.com nxt_int_t ret;
2611579St.nateldemoura@f5.com nxt_conf_value_t *obj;
2621579St.nateldemoura@f5.com
2631579St.nateldemoura@f5.com static nxt_str_t nsname = nxt_string("namespaces");
2641579St.nateldemoura@f5.com
2651579St.nateldemoura@f5.com obj = nxt_conf_get_object_member(isolation, &nsname, NULL);
2661579St.nateldemoura@f5.com if (obj != NULL) {
2671579St.nateldemoura@f5.com ret = nxt_isolation_clone_flags(task, obj, &process->isolation.clone);
2681579St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
2691579St.nateldemoura@f5.com return NXT_ERROR;
2701579St.nateldemoura@f5.com }
2711579St.nateldemoura@f5.com }
2721579St.nateldemoura@f5.com
2731579St.nateldemoura@f5.com return NXT_OK;
2741579St.nateldemoura@f5.com }
2751579St.nateldemoura@f5.com
2761579St.nateldemoura@f5.com #endif
2771579St.nateldemoura@f5.com
2781579St.nateldemoura@f5.com
2791579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUSER)
2801579St.nateldemoura@f5.com
2811579St.nateldemoura@f5.com static nxt_int_t
nxt_isolation_set_creds(nxt_task_t * task,nxt_conf_value_t * isolation,nxt_process_t * process)2821579St.nateldemoura@f5.com nxt_isolation_set_creds(nxt_task_t *task, nxt_conf_value_t *isolation,
2831579St.nateldemoura@f5.com nxt_process_t *process)
2841579St.nateldemoura@f5.com {
2851579St.nateldemoura@f5.com nxt_int_t ret;
2861579St.nateldemoura@f5.com nxt_clone_t *clone;
2871579St.nateldemoura@f5.com nxt_conf_value_t *array;
2881579St.nateldemoura@f5.com
2891579St.nateldemoura@f5.com static nxt_str_t uidname = nxt_string("uidmap");
2901579St.nateldemoura@f5.com static nxt_str_t gidname = nxt_string("gidmap");
2911579St.nateldemoura@f5.com
2921579St.nateldemoura@f5.com clone = &process->isolation.clone;
2931579St.nateldemoura@f5.com
2941579St.nateldemoura@f5.com array = nxt_conf_get_object_member(isolation, &uidname, NULL);
2951579St.nateldemoura@f5.com if (array != NULL) {
2961579St.nateldemoura@f5.com ret = nxt_isolation_credential_map(task, process->mem_pool, array,
2971579St.nateldemoura@f5.com &clone->uidmap);
2981579St.nateldemoura@f5.com
2991579St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
3001579St.nateldemoura@f5.com return NXT_ERROR;
3011579St.nateldemoura@f5.com }
3021579St.nateldemoura@f5.com }
3031579St.nateldemoura@f5.com
3041579St.nateldemoura@f5.com array = nxt_conf_get_object_member(isolation, &gidname, NULL);
3051579St.nateldemoura@f5.com if (array != NULL) {
3061579St.nateldemoura@f5.com ret = nxt_isolation_credential_map(task, process->mem_pool, array,
3071579St.nateldemoura@f5.com &clone->gidmap);
3081579St.nateldemoura@f5.com
3091579St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
3101579St.nateldemoura@f5.com return NXT_ERROR;
3111579St.nateldemoura@f5.com }
3121579St.nateldemoura@f5.com }
3131579St.nateldemoura@f5.com
3141579St.nateldemoura@f5.com return NXT_OK;
3151579St.nateldemoura@f5.com }
3161579St.nateldemoura@f5.com
3171579St.nateldemoura@f5.com
3181579St.nateldemoura@f5.com static nxt_int_t
nxt_isolation_credential_map(nxt_task_t * task,nxt_mp_t * mp,nxt_conf_value_t * map_array,nxt_clone_credential_map_t * map)3191579St.nateldemoura@f5.com nxt_isolation_credential_map(nxt_task_t *task, nxt_mp_t *mp,
3201579St.nateldemoura@f5.com nxt_conf_value_t *map_array, nxt_clone_credential_map_t *map)
3211579St.nateldemoura@f5.com {
3221579St.nateldemoura@f5.com nxt_int_t ret;
3231579St.nateldemoura@f5.com nxt_uint_t i;
3241579St.nateldemoura@f5.com nxt_conf_value_t *obj;
3251579St.nateldemoura@f5.com
3261579St.nateldemoura@f5.com static nxt_conf_map_t nxt_clone_map_entry_conf[] = {
3271579St.nateldemoura@f5.com {
3281579St.nateldemoura@f5.com nxt_string("container"),
3291579St.nateldemoura@f5.com NXT_CONF_MAP_INT,
3301579St.nateldemoura@f5.com offsetof(nxt_clone_map_entry_t, container),
3311579St.nateldemoura@f5.com },
3321579St.nateldemoura@f5.com
3331579St.nateldemoura@f5.com {
3341579St.nateldemoura@f5.com nxt_string("host"),
3351579St.nateldemoura@f5.com NXT_CONF_MAP_INT,
3361579St.nateldemoura@f5.com offsetof(nxt_clone_map_entry_t, host),
3371579St.nateldemoura@f5.com },
3381579St.nateldemoura@f5.com
3391579St.nateldemoura@f5.com {
3401579St.nateldemoura@f5.com nxt_string("size"),
3411579St.nateldemoura@f5.com NXT_CONF_MAP_INT,
3421579St.nateldemoura@f5.com offsetof(nxt_clone_map_entry_t, size),
3431579St.nateldemoura@f5.com },
3441579St.nateldemoura@f5.com };
3451579St.nateldemoura@f5.com
3461579St.nateldemoura@f5.com map->size = nxt_conf_array_elements_count(map_array);
3471579St.nateldemoura@f5.com
3481579St.nateldemoura@f5.com if (map->size == 0) {
3491579St.nateldemoura@f5.com return NXT_OK;
3501579St.nateldemoura@f5.com }
3511579St.nateldemoura@f5.com
3521579St.nateldemoura@f5.com map->map = nxt_mp_alloc(mp, map->size * sizeof(nxt_clone_map_entry_t));
3531579St.nateldemoura@f5.com if (nxt_slow_path(map->map == NULL)) {
3541579St.nateldemoura@f5.com return NXT_ERROR;
3551579St.nateldemoura@f5.com }
3561579St.nateldemoura@f5.com
3571579St.nateldemoura@f5.com for (i = 0; i < map->size; i++) {
3581579St.nateldemoura@f5.com obj = nxt_conf_get_array_element(map_array, i);
3591579St.nateldemoura@f5.com
3601579St.nateldemoura@f5.com ret = nxt_conf_map_object(mp, obj, nxt_clone_map_entry_conf,
3611579St.nateldemoura@f5.com nxt_nitems(nxt_clone_map_entry_conf),
3621579St.nateldemoura@f5.com map->map + i);
3631579St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
3641579St.nateldemoura@f5.com nxt_alert(task, "clone map entry map error");
3651579St.nateldemoura@f5.com return NXT_ERROR;
3661579St.nateldemoura@f5.com }
3671579St.nateldemoura@f5.com }
3681579St.nateldemoura@f5.com
3691579St.nateldemoura@f5.com return NXT_OK;
3701579St.nateldemoura@f5.com }
3711579St.nateldemoura@f5.com
3721579St.nateldemoura@f5.com
3731579St.nateldemoura@f5.com static nxt_int_t
nxt_isolation_vldt_creds(nxt_task_t * task,nxt_process_t * process)3741579St.nateldemoura@f5.com nxt_isolation_vldt_creds(nxt_task_t *task, nxt_process_t *process)
3751579St.nateldemoura@f5.com {
3761579St.nateldemoura@f5.com nxt_int_t ret;
3771579St.nateldemoura@f5.com nxt_clone_t *clone;
3781579St.nateldemoura@f5.com nxt_credential_t *creds;
3791579St.nateldemoura@f5.com
3801579St.nateldemoura@f5.com clone = &process->isolation.clone;
3811579St.nateldemoura@f5.com creds = process->user_cred;
3821579St.nateldemoura@f5.com
3831579St.nateldemoura@f5.com if (clone->uidmap.size == 0 && clone->gidmap.size == 0) {
3841579St.nateldemoura@f5.com return NXT_OK;
3851579St.nateldemoura@f5.com }
3861579St.nateldemoura@f5.com
3871579St.nateldemoura@f5.com if (!nxt_is_clone_flag_set(clone->flags, NEWUSER)) {
3881579St.nateldemoura@f5.com if (nxt_slow_path(clone->uidmap.size > 0)) {
3891579St.nateldemoura@f5.com nxt_log(task, NXT_LOG_ERR, "\"uidmap\" is set but "
3901579St.nateldemoura@f5.com "\"isolation.namespaces.credential\" is false or unset");
3911579St.nateldemoura@f5.com
3921579St.nateldemoura@f5.com return NXT_ERROR;
3931579St.nateldemoura@f5.com }
3941579St.nateldemoura@f5.com
3951579St.nateldemoura@f5.com if (nxt_slow_path(clone->gidmap.size > 0)) {
3961579St.nateldemoura@f5.com nxt_log(task, NXT_LOG_ERR, "\"gidmap\" is set but "
3971579St.nateldemoura@f5.com "\"isolation.namespaces.credential\" is false or unset");
3981579St.nateldemoura@f5.com
3991579St.nateldemoura@f5.com return NXT_ERROR;
4001579St.nateldemoura@f5.com }
4011579St.nateldemoura@f5.com
4021579St.nateldemoura@f5.com return NXT_OK;
4031579St.nateldemoura@f5.com }
4041579St.nateldemoura@f5.com
4051579St.nateldemoura@f5.com ret = nxt_clone_vldt_credential_uidmap(task, &clone->uidmap, creds);
4061579St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
4071579St.nateldemoura@f5.com return NXT_ERROR;
4081579St.nateldemoura@f5.com }
4091579St.nateldemoura@f5.com
4101579St.nateldemoura@f5.com return nxt_clone_vldt_credential_gidmap(task, &clone->gidmap, creds);
4111579St.nateldemoura@f5.com }
4121579St.nateldemoura@f5.com
4131579St.nateldemoura@f5.com #endif
4141579St.nateldemoura@f5.com
4151579St.nateldemoura@f5.com
4162321Sa.clayton@nginx.com #if (NXT_HAVE_LINUX_NS)
4171579St.nateldemoura@f5.com
4181579St.nateldemoura@f5.com static nxt_int_t
nxt_isolation_clone_flags(nxt_task_t * task,nxt_conf_value_t * namespaces,nxt_clone_t * clone)4191579St.nateldemoura@f5.com nxt_isolation_clone_flags(nxt_task_t *task, nxt_conf_value_t *namespaces,
4201579St.nateldemoura@f5.com nxt_clone_t *clone)
4211579St.nateldemoura@f5.com {
4221579St.nateldemoura@f5.com uint32_t index;
4231579St.nateldemoura@f5.com nxt_str_t name;
4241579St.nateldemoura@f5.com nxt_int_t flag;
4251579St.nateldemoura@f5.com nxt_conf_value_t *value;
4261579St.nateldemoura@f5.com
4271579St.nateldemoura@f5.com index = 0;
4281579St.nateldemoura@f5.com
4291579St.nateldemoura@f5.com for ( ;; ) {
4301579St.nateldemoura@f5.com value = nxt_conf_next_object_member(namespaces, &name, &index);
4311579St.nateldemoura@f5.com
4321579St.nateldemoura@f5.com if (value == NULL) {
4331579St.nateldemoura@f5.com break;
4341579St.nateldemoura@f5.com }
4351579St.nateldemoura@f5.com
4361579St.nateldemoura@f5.com flag = 0;
4371579St.nateldemoura@f5.com
4381579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUSER)
4391579St.nateldemoura@f5.com if (nxt_str_eq(&name, "credential", 10)) {
4401579St.nateldemoura@f5.com flag = CLONE_NEWUSER;
4411579St.nateldemoura@f5.com }
4421579St.nateldemoura@f5.com #endif
4431579St.nateldemoura@f5.com
4441579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWPID)
4451579St.nateldemoura@f5.com if (nxt_str_eq(&name, "pid", 3)) {
4461579St.nateldemoura@f5.com flag = CLONE_NEWPID;
4471579St.nateldemoura@f5.com }
4481579St.nateldemoura@f5.com #endif
4491579St.nateldemoura@f5.com
4501579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWNET)
4511579St.nateldemoura@f5.com if (nxt_str_eq(&name, "network", 7)) {
4521579St.nateldemoura@f5.com flag = CLONE_NEWNET;
4531579St.nateldemoura@f5.com }
4541579St.nateldemoura@f5.com #endif
4551579St.nateldemoura@f5.com
4561579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUTS)
4571579St.nateldemoura@f5.com if (nxt_str_eq(&name, "uname", 5)) {
4581579St.nateldemoura@f5.com flag = CLONE_NEWUTS;
4591579St.nateldemoura@f5.com }
4601579St.nateldemoura@f5.com #endif
4611579St.nateldemoura@f5.com
4621579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWNS)
4631579St.nateldemoura@f5.com if (nxt_str_eq(&name, "mount", 5)) {
4641579St.nateldemoura@f5.com flag = CLONE_NEWNS;
4651579St.nateldemoura@f5.com }
4661579St.nateldemoura@f5.com #endif
4671579St.nateldemoura@f5.com
4681579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWCGROUP)
4691579St.nateldemoura@f5.com if (nxt_str_eq(&name, "cgroup", 6)) {
4701579St.nateldemoura@f5.com flag = CLONE_NEWCGROUP;
4711579St.nateldemoura@f5.com }
4721579St.nateldemoura@f5.com #endif
4731579St.nateldemoura@f5.com
4741579St.nateldemoura@f5.com if (!flag) {
4751579St.nateldemoura@f5.com nxt_alert(task, "unknown namespace flag: \"%V\"", &name);
4761579St.nateldemoura@f5.com return NXT_ERROR;
4771579St.nateldemoura@f5.com }
4781579St.nateldemoura@f5.com
4791579St.nateldemoura@f5.com if (nxt_conf_get_boolean(value)) {
4801579St.nateldemoura@f5.com clone->flags |= flag;
4811579St.nateldemoura@f5.com }
4821579St.nateldemoura@f5.com }
4831579St.nateldemoura@f5.com
4841579St.nateldemoura@f5.com return NXT_OK;
4851579St.nateldemoura@f5.com }
4861579St.nateldemoura@f5.com
4871579St.nateldemoura@f5.com #endif
4881579St.nateldemoura@f5.com
4891579St.nateldemoura@f5.com
4901579St.nateldemoura@f5.com #if (NXT_HAVE_ISOLATION_ROOTFS)
4911579St.nateldemoura@f5.com
4921579St.nateldemoura@f5.com static nxt_int_t
nxt_isolation_set_rootfs(nxt_task_t * task,nxt_conf_value_t * isolation,nxt_process_t * process)4931579St.nateldemoura@f5.com nxt_isolation_set_rootfs(nxt_task_t *task, nxt_conf_value_t *isolation,
4941579St.nateldemoura@f5.com nxt_process_t *process)
4951579St.nateldemoura@f5.com {
4961579St.nateldemoura@f5.com nxt_str_t str;
4971579St.nateldemoura@f5.com nxt_conf_value_t *obj;
4981579St.nateldemoura@f5.com
4991579St.nateldemoura@f5.com static nxt_str_t rootfs_name = nxt_string("rootfs");
5001579St.nateldemoura@f5.com
5011579St.nateldemoura@f5.com obj = nxt_conf_get_object_member(isolation, &rootfs_name, NULL);
5021579St.nateldemoura@f5.com if (obj != NULL) {
5031579St.nateldemoura@f5.com nxt_conf_get_string(obj, &str);
5041579St.nateldemoura@f5.com
5051579St.nateldemoura@f5.com if (nxt_slow_path(str.length <= 1 || str.start[0] != '/')) {
5061579St.nateldemoura@f5.com nxt_log(task, NXT_LOG_ERR, "rootfs requires an absolute path other "
5071579St.nateldemoura@f5.com "than \"/\" but given \"%V\"", &str);
5081579St.nateldemoura@f5.com
5091579St.nateldemoura@f5.com return NXT_ERROR;
5101579St.nateldemoura@f5.com }
5111579St.nateldemoura@f5.com
5121579St.nateldemoura@f5.com if (str.start[str.length - 1] == '/') {
5131579St.nateldemoura@f5.com str.length--;
5141579St.nateldemoura@f5.com }
5151579St.nateldemoura@f5.com
5161579St.nateldemoura@f5.com process->isolation.rootfs = nxt_mp_alloc(process->mem_pool,
5171579St.nateldemoura@f5.com str.length + 1);
5181579St.nateldemoura@f5.com
5191579St.nateldemoura@f5.com if (nxt_slow_path(process->isolation.rootfs == NULL)) {
5201579St.nateldemoura@f5.com return NXT_ERROR;
5211579St.nateldemoura@f5.com }
5221579St.nateldemoura@f5.com
5231579St.nateldemoura@f5.com nxt_memcpy(process->isolation.rootfs, str.start, str.length);
5241579St.nateldemoura@f5.com
5251579St.nateldemoura@f5.com process->isolation.rootfs[str.length] = '\0';
5261579St.nateldemoura@f5.com }
5271579St.nateldemoura@f5.com
5281579St.nateldemoura@f5.com return NXT_OK;
5291579St.nateldemoura@f5.com }
5301579St.nateldemoura@f5.com
5311579St.nateldemoura@f5.com
5321579St.nateldemoura@f5.com static nxt_int_t
nxt_isolation_set_automount(nxt_task_t * task,nxt_conf_value_t * isolation,nxt_process_t * process)5331585St.nateldemoura@f5.com nxt_isolation_set_automount(nxt_task_t *task, nxt_conf_value_t *isolation,
5341585St.nateldemoura@f5.com nxt_process_t *process)
5351585St.nateldemoura@f5.com {
5361585St.nateldemoura@f5.com nxt_conf_value_t *conf, *value;
5371585St.nateldemoura@f5.com nxt_process_automount_t *automount;
5381585St.nateldemoura@f5.com
5391585St.nateldemoura@f5.com static nxt_str_t automount_name = nxt_string("automount");
5401585St.nateldemoura@f5.com static nxt_str_t langdeps_name = nxt_string("language_deps");
5411704St.nateldemoura@f5.com static nxt_str_t tmp_name = nxt_string("tmpfs");
5421708St.nateldemoura@f5.com static nxt_str_t proc_name = nxt_string("procfs");
5431585St.nateldemoura@f5.com
5441585St.nateldemoura@f5.com automount = &process->isolation.automount;
5451585St.nateldemoura@f5.com
5461585St.nateldemoura@f5.com automount->language_deps = 1;
5471704St.nateldemoura@f5.com automount->tmpfs = 1;
5481708St.nateldemoura@f5.com automount->procfs = 1;
5491585St.nateldemoura@f5.com
5501585St.nateldemoura@f5.com conf = nxt_conf_get_object_member(isolation, &automount_name, NULL);
5511585St.nateldemoura@f5.com if (conf != NULL) {
5521585St.nateldemoura@f5.com value = nxt_conf_get_object_member(conf, &langdeps_name, NULL);
5531585St.nateldemoura@f5.com if (value != NULL) {
5541585St.nateldemoura@f5.com automount->language_deps = nxt_conf_get_boolean(value);
5551585St.nateldemoura@f5.com }
5561704St.nateldemoura@f5.com
5571704St.nateldemoura@f5.com value = nxt_conf_get_object_member(conf, &tmp_name, NULL);
5581704St.nateldemoura@f5.com if (value != NULL) {
5591704St.nateldemoura@f5.com automount->tmpfs = nxt_conf_get_boolean(value);
5601704St.nateldemoura@f5.com }
5611708St.nateldemoura@f5.com
5621708St.nateldemoura@f5.com value = nxt_conf_get_object_member(conf, &proc_name, NULL);
5631708St.nateldemoura@f5.com if (value != NULL) {
5641708St.nateldemoura@f5.com automount->procfs = nxt_conf_get_boolean(value);
5651708St.nateldemoura@f5.com }
5661585St.nateldemoura@f5.com }
5671585St.nateldemoura@f5.com
5681585St.nateldemoura@f5.com return NXT_OK;
5691585St.nateldemoura@f5.com }
5701585St.nateldemoura@f5.com
5711585St.nateldemoura@f5.com
5721585St.nateldemoura@f5.com static nxt_int_t
nxt_isolation_set_mounts(nxt_task_t * task,nxt_process_t * process,nxt_str_t * app_type)5731579St.nateldemoura@f5.com nxt_isolation_set_mounts(nxt_task_t *task, nxt_process_t *process,
5741579St.nateldemoura@f5.com nxt_str_t *app_type)
5751579St.nateldemoura@f5.com {
5761579St.nateldemoura@f5.com nxt_int_t ret, cap_chroot;
5771579St.nateldemoura@f5.com nxt_runtime_t *rt;
5781579St.nateldemoura@f5.com nxt_app_lang_module_t *lang;
5791579St.nateldemoura@f5.com
5801579St.nateldemoura@f5.com rt = task->thread->runtime;
5811579St.nateldemoura@f5.com cap_chroot = rt->capabilities.chroot;
5821579St.nateldemoura@f5.com lang = nxt_app_lang_module(rt, app_type);
5831579St.nateldemoura@f5.com
5841579St.nateldemoura@f5.com nxt_assert(lang != NULL);
5851579St.nateldemoura@f5.com
5861579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUSER)
5871579St.nateldemoura@f5.com if (nxt_is_clone_flag_set(process->isolation.clone.flags, NEWUSER)) {
5881579St.nateldemoura@f5.com cap_chroot = 1;
5891579St.nateldemoura@f5.com }
5901579St.nateldemoura@f5.com #endif
5911579St.nateldemoura@f5.com
5921579St.nateldemoura@f5.com if (!cap_chroot) {
5931579St.nateldemoura@f5.com nxt_log(task, NXT_LOG_ERR, "The \"rootfs\" field requires privileges");
5941579St.nateldemoura@f5.com return NXT_ERROR;
5951579St.nateldemoura@f5.com }
5961579St.nateldemoura@f5.com
5971580St.nateldemoura@f5.com ret = nxt_isolation_set_lang_mounts(task, process, lang->mounts);
5981580St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
5991580St.nateldemoura@f5.com return NXT_ERROR;
6001580St.nateldemoura@f5.com }
6011579St.nateldemoura@f5.com
6021580St.nateldemoura@f5.com process->isolation.cleanup = nxt_isolation_unmount_all;
6031579St.nateldemoura@f5.com
6041579St.nateldemoura@f5.com return NXT_OK;
6051579St.nateldemoura@f5.com }
6061579St.nateldemoura@f5.com
6071579St.nateldemoura@f5.com
6081579St.nateldemoura@f5.com static nxt_int_t
nxt_isolation_set_lang_mounts(nxt_task_t * task,nxt_process_t * process,nxt_array_t * lang_mounts)6091579St.nateldemoura@f5.com nxt_isolation_set_lang_mounts(nxt_task_t *task, nxt_process_t *process,
6101579St.nateldemoura@f5.com nxt_array_t *lang_mounts)
6111579St.nateldemoura@f5.com {
6121579St.nateldemoura@f5.com u_char *p;
6131579St.nateldemoura@f5.com size_t i, n, rootfs_len, len;
6141579St.nateldemoura@f5.com nxt_mp_t *mp;
6151579St.nateldemoura@f5.com nxt_array_t *mounts;
6161579St.nateldemoura@f5.com const u_char *rootfs;
6171579St.nateldemoura@f5.com nxt_fs_mount_t *mnt, *lang_mnt;
6181579St.nateldemoura@f5.com
6191579St.nateldemoura@f5.com mp = process->mem_pool;
6201579St.nateldemoura@f5.com
6211579St.nateldemoura@f5.com /* copy to init mem pool */
6221579St.nateldemoura@f5.com mounts = nxt_array_copy(mp, NULL, lang_mounts);
6231579St.nateldemoura@f5.com if (mounts == NULL) {
6241579St.nateldemoura@f5.com return NXT_ERROR;
6251579St.nateldemoura@f5.com }
6261579St.nateldemoura@f5.com
6271579St.nateldemoura@f5.com n = mounts->nelts;
6281579St.nateldemoura@f5.com mnt = mounts->elts;
6291579St.nateldemoura@f5.com lang_mnt = lang_mounts->elts;
6301579St.nateldemoura@f5.com
6311580St.nateldemoura@f5.com rootfs = process->isolation.rootfs;
6321580St.nateldemoura@f5.com rootfs_len = nxt_strlen(rootfs);
6331580St.nateldemoura@f5.com
6341579St.nateldemoura@f5.com for (i = 0; i < n; i++) {
6351579St.nateldemoura@f5.com len = nxt_strlen(lang_mnt[i].dst);
6361579St.nateldemoura@f5.com
6371579St.nateldemoura@f5.com mnt[i].dst = nxt_mp_alloc(mp, rootfs_len + len + 1);
6381580St.nateldemoura@f5.com if (nxt_slow_path(mnt[i].dst == NULL)) {
6391579St.nateldemoura@f5.com return NXT_ERROR;
6401579St.nateldemoura@f5.com }
6411579St.nateldemoura@f5.com
6421579St.nateldemoura@f5.com p = nxt_cpymem(mnt[i].dst, rootfs, rootfs_len);
6431579St.nateldemoura@f5.com p = nxt_cpymem(p, lang_mnt[i].dst, len);
6441579St.nateldemoura@f5.com *p = '\0';
6451579St.nateldemoura@f5.com }
6461579St.nateldemoura@f5.com
6471704St.nateldemoura@f5.com if (process->isolation.automount.tmpfs) {
6481704St.nateldemoura@f5.com mnt = nxt_array_add(mounts);
6491704St.nateldemoura@f5.com if (nxt_slow_path(mnt == NULL)) {
6501704St.nateldemoura@f5.com return NXT_ERROR;
6511704St.nateldemoura@f5.com }
6521580St.nateldemoura@f5.com
6531704St.nateldemoura@f5.com mnt->src = (u_char *) "tmpfs";
6541704St.nateldemoura@f5.com mnt->name = (u_char *) "tmpfs";
6551704St.nateldemoura@f5.com mnt->type = NXT_FS_TMP;
6561704St.nateldemoura@f5.com mnt->flags = (NXT_FS_FLAGS_NOSUID
6571704St.nateldemoura@f5.com | NXT_FS_FLAGS_NODEV
6581704St.nateldemoura@f5.com | NXT_FS_FLAGS_NOEXEC);
6592331Sa.clayton@nginx.com mnt->data = (u_char *) "size=1m,mode=1777";
6601704St.nateldemoura@f5.com mnt->builtin = 1;
6611704St.nateldemoura@f5.com mnt->deps = 0;
6621580St.nateldemoura@f5.com
6631704St.nateldemoura@f5.com mnt->dst = nxt_mp_nget(mp, rootfs_len + nxt_length("/tmp") + 1);
6641704St.nateldemoura@f5.com if (nxt_slow_path(mnt->dst == NULL)) {
6651704St.nateldemoura@f5.com return NXT_ERROR;
6661704St.nateldemoura@f5.com }
6671704St.nateldemoura@f5.com
6681704St.nateldemoura@f5.com p = nxt_cpymem(mnt->dst, rootfs, rootfs_len);
6691704St.nateldemoura@f5.com p = nxt_cpymem(p, "/tmp", 4);
6701704St.nateldemoura@f5.com *p = '\0';
6711580St.nateldemoura@f5.com }
6721580St.nateldemoura@f5.com
6731708St.nateldemoura@f5.com if (process->isolation.automount.procfs) {
6741708St.nateldemoura@f5.com mnt = nxt_array_add(mounts);
6751708St.nateldemoura@f5.com if (nxt_slow_path(mnt == NULL)) {
6761708St.nateldemoura@f5.com return NXT_ERROR;
6771708St.nateldemoura@f5.com }
6781580St.nateldemoura@f5.com
6791708St.nateldemoura@f5.com mnt->name = (u_char *) "proc";
6801708St.nateldemoura@f5.com mnt->type = NXT_FS_PROC;
6811708St.nateldemoura@f5.com mnt->src = (u_char *) "none";
6821708St.nateldemoura@f5.com mnt->dst = nxt_mp_nget(mp, rootfs_len + nxt_length("/proc") + 1);
6831708St.nateldemoura@f5.com if (nxt_slow_path(mnt->dst == NULL)) {
6841708St.nateldemoura@f5.com return NXT_ERROR;
6851708St.nateldemoura@f5.com }
6861580St.nateldemoura@f5.com
6871708St.nateldemoura@f5.com p = nxt_cpymem(mnt->dst, rootfs, rootfs_len);
6881708St.nateldemoura@f5.com p = nxt_cpymem(p, "/proc", 5);
6891708St.nateldemoura@f5.com *p = '\0';
6901580St.nateldemoura@f5.com
6911708St.nateldemoura@f5.com mnt->data = (u_char *) "";
6921708St.nateldemoura@f5.com mnt->flags = NXT_FS_FLAGS_NOEXEC | NXT_FS_FLAGS_NOSUID;
6931708St.nateldemoura@f5.com mnt->builtin = 1;
6941708St.nateldemoura@f5.com mnt->deps = 0;
6951708St.nateldemoura@f5.com }
6961580St.nateldemoura@f5.com
6971671St.nateldemoura@f5.com qsort(mounts->elts, mounts->nelts, sizeof(nxt_fs_mount_t),
6981671St.nateldemoura@f5.com nxt_isolation_mount_compare);
6991671St.nateldemoura@f5.com
7001579St.nateldemoura@f5.com process->isolation.mounts = mounts;
7011579St.nateldemoura@f5.com
7021579St.nateldemoura@f5.com return NXT_OK;
7031579St.nateldemoura@f5.com }
7041579St.nateldemoura@f5.com
7051579St.nateldemoura@f5.com
7061671St.nateldemoura@f5.com static int nxt_cdecl
nxt_isolation_mount_compare(const void * v1,const void * v2)7071671St.nateldemoura@f5.com nxt_isolation_mount_compare(const void *v1, const void *v2)
7081671St.nateldemoura@f5.com {
7091671St.nateldemoura@f5.com const nxt_fs_mount_t *mnt1, *mnt2;
7101671St.nateldemoura@f5.com
7111671St.nateldemoura@f5.com mnt1 = v1;
7121671St.nateldemoura@f5.com mnt2 = v2;
7131671St.nateldemoura@f5.com
7141671St.nateldemoura@f5.com return nxt_strlen(mnt1->src) > nxt_strlen(mnt2->src);
7151671St.nateldemoura@f5.com }
7161671St.nateldemoura@f5.com
7171671St.nateldemoura@f5.com
7181579St.nateldemoura@f5.com void
nxt_isolation_unmount_all(nxt_task_t * task,nxt_process_t * process)7191579St.nateldemoura@f5.com nxt_isolation_unmount_all(nxt_task_t *task, nxt_process_t *process)
7201579St.nateldemoura@f5.com {
7211671St.nateldemoura@f5.com size_t n;
7221585St.nateldemoura@f5.com nxt_array_t *mounts;
7231671St.nateldemoura@f5.com nxt_runtime_t *rt;
7241585St.nateldemoura@f5.com nxt_fs_mount_t *mnt;
7251585St.nateldemoura@f5.com nxt_process_automount_t *automount;
7261579St.nateldemoura@f5.com
7271671St.nateldemoura@f5.com rt = task->thread->runtime;
7281671St.nateldemoura@f5.com
7291671St.nateldemoura@f5.com if (!rt->capabilities.setid) {
7301671St.nateldemoura@f5.com return;
7311671St.nateldemoura@f5.com }
7321671St.nateldemoura@f5.com
7331579St.nateldemoura@f5.com nxt_debug(task, "unmount all (%s)", process->name);
7341579St.nateldemoura@f5.com
7351585St.nateldemoura@f5.com automount = &process->isolation.automount;
7361579St.nateldemoura@f5.com mounts = process->isolation.mounts;
7371579St.nateldemoura@f5.com n = mounts->nelts;
7381579St.nateldemoura@f5.com mnt = mounts->elts;
7391579St.nateldemoura@f5.com
7401671St.nateldemoura@f5.com while (n > 0) {
7411671St.nateldemoura@f5.com n--;
7421671St.nateldemoura@f5.com
7431673St.nateldemoura@f5.com if (mnt[n].deps && !automount->language_deps) {
7441585St.nateldemoura@f5.com continue;
7451585St.nateldemoura@f5.com }
7461585St.nateldemoura@f5.com
7471671St.nateldemoura@f5.com nxt_fs_unmount(mnt[n].dst);
7481579St.nateldemoura@f5.com }
7491579St.nateldemoura@f5.com }
7501579St.nateldemoura@f5.com
7511579St.nateldemoura@f5.com
7521579St.nateldemoura@f5.com nxt_int_t
nxt_isolation_prepare_rootfs(nxt_task_t * task,nxt_process_t * process)7531579St.nateldemoura@f5.com nxt_isolation_prepare_rootfs(nxt_task_t *task, nxt_process_t *process)
7541579St.nateldemoura@f5.com {
7551585St.nateldemoura@f5.com size_t i, n;
7561585St.nateldemoura@f5.com nxt_int_t ret;
7571585St.nateldemoura@f5.com struct stat st;
7581585St.nateldemoura@f5.com nxt_array_t *mounts;
7591585St.nateldemoura@f5.com const u_char *dst;
7601585St.nateldemoura@f5.com nxt_fs_mount_t *mnt;
7611585St.nateldemoura@f5.com nxt_process_automount_t *automount;
7621579St.nateldemoura@f5.com
7631585St.nateldemoura@f5.com automount = &process->isolation.automount;
7641579St.nateldemoura@f5.com mounts = process->isolation.mounts;
7651579St.nateldemoura@f5.com
7661579St.nateldemoura@f5.com n = mounts->nelts;
7671579St.nateldemoura@f5.com mnt = mounts->elts;
7681579St.nateldemoura@f5.com
7691579St.nateldemoura@f5.com for (i = 0; i < n; i++) {
7701579St.nateldemoura@f5.com dst = mnt[i].dst;
7711579St.nateldemoura@f5.com
7721673St.nateldemoura@f5.com if (mnt[i].deps && !automount->language_deps) {
7731585St.nateldemoura@f5.com continue;
7741585St.nateldemoura@f5.com }
7751585St.nateldemoura@f5.com
7761673St.nateldemoura@f5.com if (nxt_slow_path(mnt[i].type == NXT_FS_BIND
7771579St.nateldemoura@f5.com && stat((const char *) mnt[i].src, &st) != 0))
7781579St.nateldemoura@f5.com {
7791579St.nateldemoura@f5.com nxt_log(task, NXT_LOG_WARN, "host path not found: %s", mnt[i].src);
7801579St.nateldemoura@f5.com continue;
7811579St.nateldemoura@f5.com }
7821579St.nateldemoura@f5.com
7831579St.nateldemoura@f5.com ret = nxt_fs_mkdir_all(dst, S_IRWXU | S_IRWXG | S_IRWXO);
7841579St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
7851579St.nateldemoura@f5.com nxt_alert(task, "mkdir(%s) %E", dst, nxt_errno);
7861579St.nateldemoura@f5.com goto undo;
7871579St.nateldemoura@f5.com }
7881579St.nateldemoura@f5.com
7891579St.nateldemoura@f5.com ret = nxt_fs_mount(task, &mnt[i]);
7901579St.nateldemoura@f5.com if (nxt_slow_path(ret != NXT_OK)) {
7911579St.nateldemoura@f5.com goto undo;
7921579St.nateldemoura@f5.com }
7931579St.nateldemoura@f5.com }
7941579St.nateldemoura@f5.com
7951579St.nateldemoura@f5.com return NXT_OK;
7961579St.nateldemoura@f5.com
7971579St.nateldemoura@f5.com undo:
7981579St.nateldemoura@f5.com
7991579St.nateldemoura@f5.com n = i + 1;
8001579St.nateldemoura@f5.com
8011579St.nateldemoura@f5.com for (i = 0; i < n; i++) {
8021579St.nateldemoura@f5.com nxt_fs_unmount(mnt[i].dst);
8031579St.nateldemoura@f5.com }
8041579St.nateldemoura@f5.com
8051579St.nateldemoura@f5.com return NXT_ERROR;
8061579St.nateldemoura@f5.com }
8071579St.nateldemoura@f5.com
8081579St.nateldemoura@f5.com
8092170Salx.manpages@gmail.com #if (NXT_HAVE_LINUX_PIVOT_ROOT) && (NXT_HAVE_CLONE_NEWNS)
8101579St.nateldemoura@f5.com
8111579St.nateldemoura@f5.com nxt_int_t
nxt_isolation_change_root(nxt_task_t * task,nxt_process_t * process)8121579St.nateldemoura@f5.com nxt_isolation_change_root(nxt_task_t *task, nxt_process_t *process)
8131579St.nateldemoura@f5.com {
8141579St.nateldemoura@f5.com char *rootfs;
8151579St.nateldemoura@f5.com nxt_int_t ret;
8161579St.nateldemoura@f5.com
8171579St.nateldemoura@f5.com rootfs = (char *) process->isolation.rootfs;
8181579St.nateldemoura@f5.com
8191579St.nateldemoura@f5.com nxt_debug(task, "change root: %s", rootfs);
8201579St.nateldemoura@f5.com
8211595St.nateldemoura@f5.com if (nxt_is_clone_flag_set(process->isolation.clone.flags, NEWNS)) {
8221579St.nateldemoura@f5.com ret = nxt_isolation_pivot_root(task, rootfs);
8231579St.nateldemoura@f5.com
8241579St.nateldemoura@f5.com } else {
8251579St.nateldemoura@f5.com ret = nxt_isolation_chroot(task, rootfs);
8261579St.nateldemoura@f5.com }
8271579St.nateldemoura@f5.com
8281579St.nateldemoura@f5.com if (nxt_fast_path(ret == NXT_OK)) {
8291579St.nateldemoura@f5.com if (nxt_slow_path(chdir("/") < 0)) {
8301579St.nateldemoura@f5.com nxt_alert(task, "chdir(\"/\") %E", nxt_errno);
8311579St.nateldemoura@f5.com return NXT_ERROR;
8321579St.nateldemoura@f5.com }
8331579St.nateldemoura@f5.com }
8341579St.nateldemoura@f5.com
8351579St.nateldemoura@f5.com return ret;
8361579St.nateldemoura@f5.com }
8371579St.nateldemoura@f5.com
8381579St.nateldemoura@f5.com
8391579St.nateldemoura@f5.com /*
8401579St.nateldemoura@f5.com * pivot_root(2) can only be safely used with containers, otherwise it can
8411579St.nateldemoura@f5.com * umount(2) the global root filesystem and screw up the machine.
8421579St.nateldemoura@f5.com */
8431579St.nateldemoura@f5.com
8441579St.nateldemoura@f5.com static nxt_int_t
nxt_isolation_pivot_root(nxt_task_t * task,const char * path)8451579St.nateldemoura@f5.com nxt_isolation_pivot_root(nxt_task_t *task, const char *path)
8461579St.nateldemoura@f5.com {
8471579St.nateldemoura@f5.com /*
8481579St.nateldemoura@f5.com * This implementation makes use of a kernel trick that works for ages
8491579St.nateldemoura@f5.com * and now documented in Linux kernel 5.
8501579St.nateldemoura@f5.com * https://lore.kernel.org/linux-man/87r24piwhm.fsf@x220.int.ebiederm.org/T/
8511579St.nateldemoura@f5.com */
8521579St.nateldemoura@f5.com
8531579St.nateldemoura@f5.com if (nxt_slow_path(mount("", "/", "", MS_SLAVE|MS_REC, "") != 0)) {
8541602Sartem.konev@nginx.com nxt_alert(task, "mount(\"/\", MS_SLAVE|MS_REC) failed: %E", nxt_errno);
8551579St.nateldemoura@f5.com return NXT_ERROR;
8561579St.nateldemoura@f5.com }
8571579St.nateldemoura@f5.com
8581579St.nateldemoura@f5.com if (nxt_slow_path(nxt_isolation_make_private_mount(task, path) != NXT_OK)) {
8591579St.nateldemoura@f5.com return NXT_ERROR;
8601579St.nateldemoura@f5.com }
8611579St.nateldemoura@f5.com
8621579St.nateldemoura@f5.com if (nxt_slow_path(mount(path, path, "bind", MS_BIND|MS_REC, "") != 0)) {
8631579St.nateldemoura@f5.com nxt_alert(task, "error bind mounting rootfs %E", nxt_errno);
8641579St.nateldemoura@f5.com return NXT_ERROR;
8651579St.nateldemoura@f5.com }
8661579St.nateldemoura@f5.com
8671579St.nateldemoura@f5.com if (nxt_slow_path(chdir(path) != 0)) {
8681579St.nateldemoura@f5.com nxt_alert(task, "failed to chdir(%s) %E", path, nxt_errno);
8691579St.nateldemoura@f5.com return NXT_ERROR;
8701579St.nateldemoura@f5.com }
8711579St.nateldemoura@f5.com
8721579St.nateldemoura@f5.com if (nxt_slow_path(nxt_pivot_root(".", ".") != 0)) {
8731579St.nateldemoura@f5.com nxt_alert(task, "failed to pivot_root %E", nxt_errno);
8741579St.nateldemoura@f5.com return NXT_ERROR;
8751579St.nateldemoura@f5.com }
8761579St.nateldemoura@f5.com
8771579St.nateldemoura@f5.com /*
8781602Sartem.konev@nginx.com * Demote the oldroot mount to avoid unmounts getting propagated to
879