xref: /unit/src/nxt_isolation.c (revision 2331)
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
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 
831579St.nateldemoura@f5.com     if (app_conf->isolation != NULL) {
841579St.nateldemoura@f5.com         ret = nxt_isolation_set(task, app_conf->isolation, process);
851579St.nateldemoura@f5.com         if (nxt_slow_path(ret != NXT_OK)) {
861579St.nateldemoura@f5.com             return ret;
871579St.nateldemoura@f5.com         }
881579St.nateldemoura@f5.com     }
891579St.nateldemoura@f5.com 
901579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUSER)
911579St.nateldemoura@f5.com     if (nxt_is_clone_flag_set(process->isolation.clone.flags, NEWUSER)) {
921579St.nateldemoura@f5.com         cap_setid = 1;
931579St.nateldemoura@f5.com     }
941579St.nateldemoura@f5.com #endif
951579St.nateldemoura@f5.com 
961579St.nateldemoura@f5.com     if (cap_setid) {
971579St.nateldemoura@f5.com         ret = nxt_process_creds_set(task, process, &app_conf->user,
981579St.nateldemoura@f5.com                                     &app_conf->group);
991579St.nateldemoura@f5.com 
1001579St.nateldemoura@f5.com         if (nxt_slow_path(ret != NXT_OK)) {
1011579St.nateldemoura@f5.com             return ret;
1021579St.nateldemoura@f5.com         }
1031579St.nateldemoura@f5.com 
1041579St.nateldemoura@f5.com     } else {
1051579St.nateldemoura@f5.com         if (!nxt_str_eq(&app_conf->user, (u_char *) rt->user_cred.user,
1061579St.nateldemoura@f5.com                         nxt_strlen(rt->user_cred.user)))
1071579St.nateldemoura@f5.com         {
1081579St.nateldemoura@f5.com             nxt_alert(task, "cannot set user \"%V\" for app \"%V\": "
1091579St.nateldemoura@f5.com                       "missing capabilities", &app_conf->user, &app_conf->name);
1101579St.nateldemoura@f5.com 
1111579St.nateldemoura@f5.com             return NXT_ERROR;
1121579St.nateldemoura@f5.com         }
1131579St.nateldemoura@f5.com 
1141579St.nateldemoura@f5.com         if (app_conf->group.length > 0
1151579St.nateldemoura@f5.com             && !nxt_str_eq(&app_conf->group, (u_char *) rt->group,
1161579St.nateldemoura@f5.com                            nxt_strlen(rt->group)))
1171579St.nateldemoura@f5.com         {
1181579St.nateldemoura@f5.com             nxt_alert(task, "cannot set group \"%V\" for app \"%V\": "
1191579St.nateldemoura@f5.com                             "missing capabilities", &app_conf->group,
1201579St.nateldemoura@f5.com                             &app_conf->name);
1211579St.nateldemoura@f5.com 
1221579St.nateldemoura@f5.com             return NXT_ERROR;
1231579St.nateldemoura@f5.com         }
1241579St.nateldemoura@f5.com     }
1251579St.nateldemoura@f5.com 
1261673St.nateldemoura@f5.com #if (NXT_HAVE_ISOLATION_ROOTFS)
1271673St.nateldemoura@f5.com     if (process->isolation.rootfs != NULL) {
1281673St.nateldemoura@f5.com         nxt_int_t  has_mnt;
1291673St.nateldemoura@f5.com 
1301673St.nateldemoura@f5.com         ret = nxt_isolation_set_mounts(task, process, &app_conf->type);
1311673St.nateldemoura@f5.com         if (nxt_slow_path(ret != NXT_OK)) {
1321673St.nateldemoura@f5.com             return ret;
1331673St.nateldemoura@f5.com         }
1341673St.nateldemoura@f5.com 
1351673St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWNS)
1361673St.nateldemoura@f5.com         has_mnt = nxt_is_clone_flag_set(process->isolation.clone.flags, NEWNS);
1371927Smax.romanov@nginx.com #else
1381927Smax.romanov@nginx.com         has_mnt = 0;
1391673St.nateldemoura@f5.com #endif
1401673St.nateldemoura@f5.com 
1411673St.nateldemoura@f5.com         if (process->user_cred->uid == 0 && !has_mnt) {
1421673St.nateldemoura@f5.com             nxt_log(task, NXT_LOG_WARN,
1431673St.nateldemoura@f5.com                     "setting user \"root\" with \"rootfs\" is unsafe without "
1441673St.nateldemoura@f5.com                     "\"mount\" namespace isolation");
1451673St.nateldemoura@f5.com         }
1461673St.nateldemoura@f5.com     }
1471673St.nateldemoura@f5.com #endif
1481673St.nateldemoura@f5.com 
1491579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUSER)
1501579St.nateldemoura@f5.com     ret = nxt_isolation_vldt_creds(task, process);
1511579St.nateldemoura@f5.com     if (nxt_slow_path(ret != NXT_OK)) {
1521579St.nateldemoura@f5.com         return ret;
1531579St.nateldemoura@f5.com     }
1541579St.nateldemoura@f5.com #endif
1551579St.nateldemoura@f5.com 
1561579St.nateldemoura@f5.com     return NXT_OK;
1571579St.nateldemoura@f5.com }
1581579St.nateldemoura@f5.com 
1591579St.nateldemoura@f5.com 
1601579St.nateldemoura@f5.com static nxt_int_t
1611579St.nateldemoura@f5.com nxt_isolation_set(nxt_task_t *task, nxt_conf_value_t *isolation,
1621579St.nateldemoura@f5.com     nxt_process_t *process)
1631579St.nateldemoura@f5.com {
1642260Sa.clayton@nginx.com #if (NXT_HAVE_CGROUP)
1652260Sa.clayton@nginx.com     if (nxt_slow_path(nxt_isolation_set_cgroup(task, isolation, process)
1662260Sa.clayton@nginx.com                       != NXT_OK))
1672260Sa.clayton@nginx.com     {
1682260Sa.clayton@nginx.com         return NXT_ERROR;
1692260Sa.clayton@nginx.com     }
1702260Sa.clayton@nginx.com #endif
1712260Sa.clayton@nginx.com 
1722321Sa.clayton@nginx.com #if (NXT_HAVE_LINUX_NS)
1731579St.nateldemoura@f5.com     if (nxt_slow_path(nxt_isolation_set_namespaces(task, isolation, process)
1741579St.nateldemoura@f5.com                       != NXT_OK))
1751579St.nateldemoura@f5.com     {
1761579St.nateldemoura@f5.com         return NXT_ERROR;
1771579St.nateldemoura@f5.com     }
1781579St.nateldemoura@f5.com #endif
1791579St.nateldemoura@f5.com 
1801579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUSER)
1811579St.nateldemoura@f5.com     if (nxt_slow_path(nxt_isolation_set_creds(task, isolation, process)
1821579St.nateldemoura@f5.com                       != NXT_OK))
1831579St.nateldemoura@f5.com     {
1841579St.nateldemoura@f5.com         return NXT_ERROR;
1851579St.nateldemoura@f5.com     }
1861579St.nateldemoura@f5.com #endif
1871579St.nateldemoura@f5.com 
1881579St.nateldemoura@f5.com #if (NXT_HAVE_ISOLATION_ROOTFS)
1891579St.nateldemoura@f5.com     if (nxt_slow_path(nxt_isolation_set_rootfs(task, isolation, process)
1901579St.nateldemoura@f5.com                       != NXT_OK))
1911579St.nateldemoura@f5.com     {
1921579St.nateldemoura@f5.com         return NXT_ERROR;
1931579St.nateldemoura@f5.com     }
1941585St.nateldemoura@f5.com 
1951585St.nateldemoura@f5.com     if (nxt_slow_path(nxt_isolation_set_automount(task, isolation, process)
1961585St.nateldemoura@f5.com                       != NXT_OK))
1971585St.nateldemoura@f5.com     {
1981585St.nateldemoura@f5.com         return NXT_ERROR;
1991585St.nateldemoura@f5.com     }
2001579St.nateldemoura@f5.com #endif
2011579St.nateldemoura@f5.com 
2021579St.nateldemoura@f5.com #if (NXT_HAVE_PR_SET_NO_NEW_PRIVS)
2031579St.nateldemoura@f5.com     if (nxt_slow_path(nxt_isolation_set_new_privs(task, isolation, process)
2041579St.nateldemoura@f5.com                       != NXT_OK))
2051579St.nateldemoura@f5.com     {
2061579St.nateldemoura@f5.com         return NXT_ERROR;
2071579St.nateldemoura@f5.com     }
2081579St.nateldemoura@f5.com #endif
2091579St.nateldemoura@f5.com 
2101579St.nateldemoura@f5.com     return NXT_OK;
2111579St.nateldemoura@f5.com }
2121579St.nateldemoura@f5.com 
2131579St.nateldemoura@f5.com 
2142260Sa.clayton@nginx.com #if (NXT_HAVE_CGROUP)
2152260Sa.clayton@nginx.com 
2162260Sa.clayton@nginx.com static nxt_int_t
2172260Sa.clayton@nginx.com nxt_isolation_set_cgroup(nxt_task_t *task, nxt_conf_value_t *isolation,
2182260Sa.clayton@nginx.com     nxt_process_t *process)
2192260Sa.clayton@nginx.com {
2202260Sa.clayton@nginx.com     nxt_str_t         str;
2212260Sa.clayton@nginx.com     nxt_conf_value_t  *obj;
2222260Sa.clayton@nginx.com 
2232260Sa.clayton@nginx.com     static nxt_str_t  cgname = nxt_string("cgroup");
2242260Sa.clayton@nginx.com     static nxt_str_t  path = nxt_string("path");
2252260Sa.clayton@nginx.com 
2262260Sa.clayton@nginx.com     obj = nxt_conf_get_object_member(isolation, &cgname, NULL);
2272260Sa.clayton@nginx.com     if (obj == NULL) {
2282260Sa.clayton@nginx.com         return NXT_OK;
2292260Sa.clayton@nginx.com     }
2302260Sa.clayton@nginx.com 
2312260Sa.clayton@nginx.com     obj = nxt_conf_get_object_member(obj, &path, NULL);
2322260Sa.clayton@nginx.com     if (obj == NULL) {
2332260Sa.clayton@nginx.com         return NXT_ERROR;
2342260Sa.clayton@nginx.com     }
2352260Sa.clayton@nginx.com 
2362260Sa.clayton@nginx.com     nxt_conf_get_string(obj, &str);
2372260Sa.clayton@nginx.com     process->isolation.cgroup.path = nxt_mp_alloc(process->mem_pool,
2382260Sa.clayton@nginx.com                                                   str.length + 1);
2392260Sa.clayton@nginx.com     nxt_memcpy(process->isolation.cgroup.path, str.start, str.length);
2402260Sa.clayton@nginx.com     process->isolation.cgroup.path[str.length] = '\0';
2412260Sa.clayton@nginx.com 
2422260Sa.clayton@nginx.com     process->isolation.cgroup_cleanup = nxt_cgroup_cleanup;
2432260Sa.clayton@nginx.com 
2442260Sa.clayton@nginx.com     return NXT_OK;
2452260Sa.clayton@nginx.com }
2462260Sa.clayton@nginx.com 
2472260Sa.clayton@nginx.com #endif
2482260Sa.clayton@nginx.com 
2492260Sa.clayton@nginx.com 
2502321Sa.clayton@nginx.com #if (NXT_HAVE_LINUX_NS)
2511579St.nateldemoura@f5.com 
2521579St.nateldemoura@f5.com static nxt_int_t
2531579St.nateldemoura@f5.com nxt_isolation_set_namespaces(nxt_task_t *task, nxt_conf_value_t *isolation,
2541579St.nateldemoura@f5.com     nxt_process_t *process)
2551579St.nateldemoura@f5.com {
2561579St.nateldemoura@f5.com     nxt_int_t         ret;
2571579St.nateldemoura@f5.com     nxt_conf_value_t  *obj;
2581579St.nateldemoura@f5.com 
2591579St.nateldemoura@f5.com     static nxt_str_t  nsname = nxt_string("namespaces");
2601579St.nateldemoura@f5.com 
2611579St.nateldemoura@f5.com     obj = nxt_conf_get_object_member(isolation, &nsname, NULL);
2621579St.nateldemoura@f5.com     if (obj != NULL) {
2631579St.nateldemoura@f5.com         ret = nxt_isolation_clone_flags(task, obj, &process->isolation.clone);
2641579St.nateldemoura@f5.com         if (nxt_slow_path(ret != NXT_OK)) {
2651579St.nateldemoura@f5.com             return NXT_ERROR;
2661579St.nateldemoura@f5.com         }
2671579St.nateldemoura@f5.com     }
2681579St.nateldemoura@f5.com 
2691579St.nateldemoura@f5.com     return NXT_OK;
2701579St.nateldemoura@f5.com }
2711579St.nateldemoura@f5.com 
2721579St.nateldemoura@f5.com #endif
2731579St.nateldemoura@f5.com 
2741579St.nateldemoura@f5.com 
2751579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUSER)
2761579St.nateldemoura@f5.com 
2771579St.nateldemoura@f5.com static nxt_int_t
2781579St.nateldemoura@f5.com nxt_isolation_set_creds(nxt_task_t *task, nxt_conf_value_t *isolation,
2791579St.nateldemoura@f5.com     nxt_process_t *process)
2801579St.nateldemoura@f5.com {
2811579St.nateldemoura@f5.com     nxt_int_t         ret;
2821579St.nateldemoura@f5.com     nxt_clone_t       *clone;
2831579St.nateldemoura@f5.com     nxt_conf_value_t  *array;
2841579St.nateldemoura@f5.com 
2851579St.nateldemoura@f5.com     static nxt_str_t uidname = nxt_string("uidmap");
2861579St.nateldemoura@f5.com     static nxt_str_t gidname = nxt_string("gidmap");
2871579St.nateldemoura@f5.com 
2881579St.nateldemoura@f5.com     clone = &process->isolation.clone;
2891579St.nateldemoura@f5.com 
2901579St.nateldemoura@f5.com     array = nxt_conf_get_object_member(isolation, &uidname, NULL);
2911579St.nateldemoura@f5.com     if (array != NULL) {
2921579St.nateldemoura@f5.com         ret = nxt_isolation_credential_map(task, process->mem_pool, array,
2931579St.nateldemoura@f5.com                                            &clone->uidmap);
2941579St.nateldemoura@f5.com 
2951579St.nateldemoura@f5.com         if (nxt_slow_path(ret != NXT_OK)) {
2961579St.nateldemoura@f5.com             return NXT_ERROR;
2971579St.nateldemoura@f5.com         }
2981579St.nateldemoura@f5.com     }
2991579St.nateldemoura@f5.com 
3001579St.nateldemoura@f5.com     array = nxt_conf_get_object_member(isolation, &gidname, NULL);
3011579St.nateldemoura@f5.com     if (array != NULL) {
3021579St.nateldemoura@f5.com         ret = nxt_isolation_credential_map(task, process->mem_pool, array,
3031579St.nateldemoura@f5.com                                            &clone->gidmap);
3041579St.nateldemoura@f5.com 
3051579St.nateldemoura@f5.com         if (nxt_slow_path(ret != NXT_OK)) {
3061579St.nateldemoura@f5.com             return NXT_ERROR;
3071579St.nateldemoura@f5.com         }
3081579St.nateldemoura@f5.com     }
3091579St.nateldemoura@f5.com 
3101579St.nateldemoura@f5.com     return NXT_OK;
3111579St.nateldemoura@f5.com }
3121579St.nateldemoura@f5.com 
3131579St.nateldemoura@f5.com 
3141579St.nateldemoura@f5.com static nxt_int_t
3151579St.nateldemoura@f5.com nxt_isolation_credential_map(nxt_task_t *task, nxt_mp_t *mp,
3161579St.nateldemoura@f5.com     nxt_conf_value_t *map_array, nxt_clone_credential_map_t *map)
3171579St.nateldemoura@f5.com {
3181579St.nateldemoura@f5.com     nxt_int_t         ret;
3191579St.nateldemoura@f5.com     nxt_uint_t        i;
3201579St.nateldemoura@f5.com     nxt_conf_value_t  *obj;
3211579St.nateldemoura@f5.com 
3221579St.nateldemoura@f5.com     static nxt_conf_map_t  nxt_clone_map_entry_conf[] = {
3231579St.nateldemoura@f5.com         {
3241579St.nateldemoura@f5.com             nxt_string("container"),
3251579St.nateldemoura@f5.com             NXT_CONF_MAP_INT,
3261579St.nateldemoura@f5.com             offsetof(nxt_clone_map_entry_t, container),
3271579St.nateldemoura@f5.com         },
3281579St.nateldemoura@f5.com 
3291579St.nateldemoura@f5.com         {
3301579St.nateldemoura@f5.com             nxt_string("host"),
3311579St.nateldemoura@f5.com             NXT_CONF_MAP_INT,
3321579St.nateldemoura@f5.com             offsetof(nxt_clone_map_entry_t, host),
3331579St.nateldemoura@f5.com         },
3341579St.nateldemoura@f5.com 
3351579St.nateldemoura@f5.com         {
3361579St.nateldemoura@f5.com             nxt_string("size"),
3371579St.nateldemoura@f5.com             NXT_CONF_MAP_INT,
3381579St.nateldemoura@f5.com             offsetof(nxt_clone_map_entry_t, size),
3391579St.nateldemoura@f5.com         },
3401579St.nateldemoura@f5.com     };
3411579St.nateldemoura@f5.com 
3421579St.nateldemoura@f5.com     map->size = nxt_conf_array_elements_count(map_array);
3431579St.nateldemoura@f5.com 
3441579St.nateldemoura@f5.com     if (map->size == 0) {
3451579St.nateldemoura@f5.com         return NXT_OK;
3461579St.nateldemoura@f5.com     }
3471579St.nateldemoura@f5.com 
3481579St.nateldemoura@f5.com     map->map = nxt_mp_alloc(mp, map->size * sizeof(nxt_clone_map_entry_t));
3491579St.nateldemoura@f5.com     if (nxt_slow_path(map->map == NULL)) {
3501579St.nateldemoura@f5.com         return NXT_ERROR;
3511579St.nateldemoura@f5.com     }
3521579St.nateldemoura@f5.com 
3531579St.nateldemoura@f5.com     for (i = 0; i < map->size; i++) {
3541579St.nateldemoura@f5.com         obj = nxt_conf_get_array_element(map_array, i);
3551579St.nateldemoura@f5.com 
3561579St.nateldemoura@f5.com         ret = nxt_conf_map_object(mp, obj, nxt_clone_map_entry_conf,
3571579St.nateldemoura@f5.com                                   nxt_nitems(nxt_clone_map_entry_conf),
3581579St.nateldemoura@f5.com                                   map->map + i);
3591579St.nateldemoura@f5.com         if (nxt_slow_path(ret != NXT_OK)) {
3601579St.nateldemoura@f5.com             nxt_alert(task, "clone map entry map error");
3611579St.nateldemoura@f5.com             return NXT_ERROR;
3621579St.nateldemoura@f5.com         }
3631579St.nateldemoura@f5.com     }
3641579St.nateldemoura@f5.com 
3651579St.nateldemoura@f5.com     return NXT_OK;
3661579St.nateldemoura@f5.com }
3671579St.nateldemoura@f5.com 
3681579St.nateldemoura@f5.com 
3691579St.nateldemoura@f5.com static nxt_int_t
3701579St.nateldemoura@f5.com nxt_isolation_vldt_creds(nxt_task_t *task, nxt_process_t *process)
3711579St.nateldemoura@f5.com {
3721579St.nateldemoura@f5.com     nxt_int_t         ret;
3731579St.nateldemoura@f5.com     nxt_clone_t       *clone;
3741579St.nateldemoura@f5.com     nxt_credential_t  *creds;
3751579St.nateldemoura@f5.com 
3761579St.nateldemoura@f5.com     clone = &process->isolation.clone;
3771579St.nateldemoura@f5.com     creds = process->user_cred;
3781579St.nateldemoura@f5.com 
3791579St.nateldemoura@f5.com     if (clone->uidmap.size == 0 && clone->gidmap.size == 0) {
3801579St.nateldemoura@f5.com         return NXT_OK;
3811579St.nateldemoura@f5.com     }
3821579St.nateldemoura@f5.com 
3831579St.nateldemoura@f5.com     if (!nxt_is_clone_flag_set(clone->flags, NEWUSER)) {
3841579St.nateldemoura@f5.com         if (nxt_slow_path(clone->uidmap.size > 0)) {
3851579St.nateldemoura@f5.com             nxt_log(task, NXT_LOG_ERR, "\"uidmap\" is set but "
3861579St.nateldemoura@f5.com                     "\"isolation.namespaces.credential\" is false or unset");
3871579St.nateldemoura@f5.com 
3881579St.nateldemoura@f5.com             return NXT_ERROR;
3891579St.nateldemoura@f5.com         }
3901579St.nateldemoura@f5.com 
3911579St.nateldemoura@f5.com         if (nxt_slow_path(clone->gidmap.size > 0)) {
3921579St.nateldemoura@f5.com             nxt_log(task, NXT_LOG_ERR, "\"gidmap\" is set but "
3931579St.nateldemoura@f5.com                     "\"isolation.namespaces.credential\" is false or unset");
3941579St.nateldemoura@f5.com 
3951579St.nateldemoura@f5.com             return NXT_ERROR;
3961579St.nateldemoura@f5.com         }
3971579St.nateldemoura@f5.com 
3981579St.nateldemoura@f5.com         return NXT_OK;
3991579St.nateldemoura@f5.com     }
4001579St.nateldemoura@f5.com 
4011579St.nateldemoura@f5.com     ret = nxt_clone_vldt_credential_uidmap(task, &clone->uidmap, creds);
4021579St.nateldemoura@f5.com     if (nxt_slow_path(ret != NXT_OK)) {
4031579St.nateldemoura@f5.com         return NXT_ERROR;
4041579St.nateldemoura@f5.com     }
4051579St.nateldemoura@f5.com 
4061579St.nateldemoura@f5.com     return nxt_clone_vldt_credential_gidmap(task, &clone->gidmap, creds);
4071579St.nateldemoura@f5.com }
4081579St.nateldemoura@f5.com 
4091579St.nateldemoura@f5.com #endif
4101579St.nateldemoura@f5.com 
4111579St.nateldemoura@f5.com 
4122321Sa.clayton@nginx.com #if (NXT_HAVE_LINUX_NS)
4131579St.nateldemoura@f5.com 
4141579St.nateldemoura@f5.com static nxt_int_t
4151579St.nateldemoura@f5.com nxt_isolation_clone_flags(nxt_task_t *task, nxt_conf_value_t *namespaces,
4161579St.nateldemoura@f5.com     nxt_clone_t *clone)
4171579St.nateldemoura@f5.com {
4181579St.nateldemoura@f5.com     uint32_t          index;
4191579St.nateldemoura@f5.com     nxt_str_t         name;
4201579St.nateldemoura@f5.com     nxt_int_t         flag;
4211579St.nateldemoura@f5.com     nxt_conf_value_t  *value;
4221579St.nateldemoura@f5.com 
4231579St.nateldemoura@f5.com     index = 0;
4241579St.nateldemoura@f5.com 
4251579St.nateldemoura@f5.com     for ( ;; ) {
4261579St.nateldemoura@f5.com         value = nxt_conf_next_object_member(namespaces, &name, &index);
4271579St.nateldemoura@f5.com 
4281579St.nateldemoura@f5.com         if (value == NULL) {
4291579St.nateldemoura@f5.com             break;
4301579St.nateldemoura@f5.com         }
4311579St.nateldemoura@f5.com 
4321579St.nateldemoura@f5.com         flag = 0;
4331579St.nateldemoura@f5.com 
4341579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUSER)
4351579St.nateldemoura@f5.com         if (nxt_str_eq(&name, "credential", 10)) {
4361579St.nateldemoura@f5.com             flag = CLONE_NEWUSER;
4371579St.nateldemoura@f5.com         }
4381579St.nateldemoura@f5.com #endif
4391579St.nateldemoura@f5.com 
4401579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWPID)
4411579St.nateldemoura@f5.com         if (nxt_str_eq(&name, "pid", 3)) {
4421579St.nateldemoura@f5.com             flag = CLONE_NEWPID;
4431579St.nateldemoura@f5.com         }
4441579St.nateldemoura@f5.com #endif
4451579St.nateldemoura@f5.com 
4461579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWNET)
4471579St.nateldemoura@f5.com         if (nxt_str_eq(&name, "network", 7)) {
4481579St.nateldemoura@f5.com             flag = CLONE_NEWNET;
4491579St.nateldemoura@f5.com         }
4501579St.nateldemoura@f5.com #endif
4511579St.nateldemoura@f5.com 
4521579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUTS)
4531579St.nateldemoura@f5.com         if (nxt_str_eq(&name, "uname", 5)) {
4541579St.nateldemoura@f5.com             flag = CLONE_NEWUTS;
4551579St.nateldemoura@f5.com         }
4561579St.nateldemoura@f5.com #endif
4571579St.nateldemoura@f5.com 
4581579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWNS)
4591579St.nateldemoura@f5.com         if (nxt_str_eq(&name, "mount", 5)) {
4601579St.nateldemoura@f5.com             flag = CLONE_NEWNS;
4611579St.nateldemoura@f5.com         }
4621579St.nateldemoura@f5.com #endif
4631579St.nateldemoura@f5.com 
4641579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWCGROUP)
4651579St.nateldemoura@f5.com         if (nxt_str_eq(&name, "cgroup", 6)) {
4661579St.nateldemoura@f5.com             flag = CLONE_NEWCGROUP;
4671579St.nateldemoura@f5.com         }
4681579St.nateldemoura@f5.com #endif
4691579St.nateldemoura@f5.com 
4701579St.nateldemoura@f5.com         if (!flag) {
4711579St.nateldemoura@f5.com             nxt_alert(task, "unknown namespace flag: \"%V\"", &name);
4721579St.nateldemoura@f5.com             return NXT_ERROR;
4731579St.nateldemoura@f5.com         }
4741579St.nateldemoura@f5.com 
4751579St.nateldemoura@f5.com         if (nxt_conf_get_boolean(value)) {
4761579St.nateldemoura@f5.com             clone->flags |= flag;
4771579St.nateldemoura@f5.com         }
4781579St.nateldemoura@f5.com     }
4791579St.nateldemoura@f5.com 
4801579St.nateldemoura@f5.com     return NXT_OK;
4811579St.nateldemoura@f5.com }
4821579St.nateldemoura@f5.com 
4831579St.nateldemoura@f5.com #endif
4841579St.nateldemoura@f5.com 
4851579St.nateldemoura@f5.com 
4861579St.nateldemoura@f5.com #if (NXT_HAVE_ISOLATION_ROOTFS)
4871579St.nateldemoura@f5.com 
4881579St.nateldemoura@f5.com static nxt_int_t
4891579St.nateldemoura@f5.com nxt_isolation_set_rootfs(nxt_task_t *task, nxt_conf_value_t *isolation,
4901579St.nateldemoura@f5.com     nxt_process_t *process)
4911579St.nateldemoura@f5.com {
4921579St.nateldemoura@f5.com     nxt_str_t         str;
4931579St.nateldemoura@f5.com     nxt_conf_value_t  *obj;
4941579St.nateldemoura@f5.com 
4951579St.nateldemoura@f5.com     static nxt_str_t  rootfs_name = nxt_string("rootfs");
4961579St.nateldemoura@f5.com 
4971579St.nateldemoura@f5.com     obj = nxt_conf_get_object_member(isolation, &rootfs_name, NULL);
4981579St.nateldemoura@f5.com     if (obj != NULL) {
4991579St.nateldemoura@f5.com         nxt_conf_get_string(obj, &str);
5001579St.nateldemoura@f5.com 
5011579St.nateldemoura@f5.com         if (nxt_slow_path(str.length <= 1 || str.start[0] != '/')) {
5021579St.nateldemoura@f5.com             nxt_log(task, NXT_LOG_ERR, "rootfs requires an absolute path other "
5031579St.nateldemoura@f5.com                     "than \"/\" but given \"%V\"", &str);
5041579St.nateldemoura@f5.com 
5051579St.nateldemoura@f5.com             return NXT_ERROR;
5061579St.nateldemoura@f5.com         }
5071579St.nateldemoura@f5.com 
5081579St.nateldemoura@f5.com         if (str.start[str.length - 1] == '/') {
5091579St.nateldemoura@f5.com             str.length--;
5101579St.nateldemoura@f5.com         }
5111579St.nateldemoura@f5.com 
5121579St.nateldemoura@f5.com         process->isolation.rootfs = nxt_mp_alloc(process->mem_pool,
5131579St.nateldemoura@f5.com                                                  str.length + 1);
5141579St.nateldemoura@f5.com 
5151579St.nateldemoura@f5.com         if (nxt_slow_path(process->isolation.rootfs == NULL)) {
5161579St.nateldemoura@f5.com             return NXT_ERROR;
5171579St.nateldemoura@f5.com         }
5181579St.nateldemoura@f5.com 
5191579St.nateldemoura@f5.com         nxt_memcpy(process->isolation.rootfs, str.start, str.length);
5201579St.nateldemoura@f5.com 
5211579St.nateldemoura@f5.com         process->isolation.rootfs[str.length] = '\0';
5221579St.nateldemoura@f5.com     }
5231579St.nateldemoura@f5.com 
5241579St.nateldemoura@f5.com     return NXT_OK;
5251579St.nateldemoura@f5.com }
5261579St.nateldemoura@f5.com 
5271579St.nateldemoura@f5.com 
5281579St.nateldemoura@f5.com static nxt_int_t
5291585St.nateldemoura@f5.com nxt_isolation_set_automount(nxt_task_t *task, nxt_conf_value_t *isolation,
5301585St.nateldemoura@f5.com     nxt_process_t *process)
5311585St.nateldemoura@f5.com {
5321585St.nateldemoura@f5.com     nxt_conf_value_t         *conf, *value;
5331585St.nateldemoura@f5.com     nxt_process_automount_t  *automount;
5341585St.nateldemoura@f5.com 
5351585St.nateldemoura@f5.com     static nxt_str_t  automount_name = nxt_string("automount");
5361585St.nateldemoura@f5.com     static nxt_str_t  langdeps_name = nxt_string("language_deps");
5371704St.nateldemoura@f5.com     static nxt_str_t  tmp_name = nxt_string("tmpfs");
5381708St.nateldemoura@f5.com     static nxt_str_t  proc_name = nxt_string("procfs");
5391585St.nateldemoura@f5.com 
5401585St.nateldemoura@f5.com     automount = &process->isolation.automount;
5411585St.nateldemoura@f5.com 
5421585St.nateldemoura@f5.com     automount->language_deps = 1;
5431704St.nateldemoura@f5.com     automount->tmpfs = 1;
5441708St.nateldemoura@f5.com     automount->procfs = 1;
5451585St.nateldemoura@f5.com 
5461585St.nateldemoura@f5.com     conf = nxt_conf_get_object_member(isolation, &automount_name, NULL);
5471585St.nateldemoura@f5.com     if (conf != NULL) {
5481585St.nateldemoura@f5.com         value = nxt_conf_get_object_member(conf, &langdeps_name, NULL);
5491585St.nateldemoura@f5.com         if (value != NULL) {
5501585St.nateldemoura@f5.com             automount->language_deps = nxt_conf_get_boolean(value);
5511585St.nateldemoura@f5.com         }
5521704St.nateldemoura@f5.com 
5531704St.nateldemoura@f5.com         value = nxt_conf_get_object_member(conf, &tmp_name, NULL);
5541704St.nateldemoura@f5.com         if (value != NULL) {
5551704St.nateldemoura@f5.com             automount->tmpfs = nxt_conf_get_boolean(value);
5561704St.nateldemoura@f5.com         }
5571708St.nateldemoura@f5.com 
5581708St.nateldemoura@f5.com         value = nxt_conf_get_object_member(conf, &proc_name, NULL);
5591708St.nateldemoura@f5.com         if (value != NULL) {
5601708St.nateldemoura@f5.com             automount->procfs = nxt_conf_get_boolean(value);
5611708St.nateldemoura@f5.com         }
5621585St.nateldemoura@f5.com     }
5631585St.nateldemoura@f5.com 
5641585St.nateldemoura@f5.com     return NXT_OK;
5651585St.nateldemoura@f5.com }
5661585St.nateldemoura@f5.com 
5671585St.nateldemoura@f5.com 
5681585St.nateldemoura@f5.com static nxt_int_t
5691579St.nateldemoura@f5.com nxt_isolation_set_mounts(nxt_task_t *task, nxt_process_t *process,
5701579St.nateldemoura@f5.com     nxt_str_t *app_type)
5711579St.nateldemoura@f5.com {
5721579St.nateldemoura@f5.com     nxt_int_t              ret, cap_chroot;
5731579St.nateldemoura@f5.com     nxt_runtime_t          *rt;
5741579St.nateldemoura@f5.com     nxt_app_lang_module_t  *lang;
5751579St.nateldemoura@f5.com 
5761579St.nateldemoura@f5.com     rt = task->thread->runtime;
5771579St.nateldemoura@f5.com     cap_chroot = rt->capabilities.chroot;
5781579St.nateldemoura@f5.com     lang = nxt_app_lang_module(rt, app_type);
5791579St.nateldemoura@f5.com 
5801579St.nateldemoura@f5.com     nxt_assert(lang != NULL);
5811579St.nateldemoura@f5.com 
5821579St.nateldemoura@f5.com #if (NXT_HAVE_CLONE_NEWUSER)
5831579St.nateldemoura@f5.com     if (nxt_is_clone_flag_set(process->isolation.clone.flags, NEWUSER)) {
5841579St.nateldemoura@f5.com         cap_chroot = 1;
5851579St.nateldemoura@f5.com     }
5861579St.nateldemoura@f5.com #endif
5871579St.nateldemoura@f5.com 
5881579St.nateldemoura@f5.com     if (!cap_chroot) {
5891579St.nateldemoura@f5.com         nxt_log(task, NXT_LOG_ERR, "The \"rootfs\" field requires privileges");
5901579St.nateldemoura@f5.com         return NXT_ERROR;
5911579St.nateldemoura@f5.com     }
5921579St.nateldemoura@f5.com 
5931580St.nateldemoura@f5.com     ret = nxt_isolation_set_lang_mounts(task, process, lang->mounts);
5941580St.nateldemoura@f5.com     if (nxt_slow_path(ret != NXT_OK)) {
5951580St.nateldemoura@f5.com         return NXT_ERROR;
5961580St.nateldemoura@f5.com     }
5971579St.nateldemoura@f5.com 
5981580St.nateldemoura@f5.com     process->isolation.cleanup = nxt_isolation_unmount_all;
5991579St.nateldemoura@f5.com 
6001579St.nateldemoura@f5.com     return NXT_OK;
6011579St.nateldemoura@f5.com }
6021579St.nateldemoura@f5.com 
6031579St.nateldemoura@f5.com 
6041579St.nateldemoura@f5.com static nxt_int_t
6051579St.nateldemoura@f5.com nxt_isolation_set_lang_mounts(nxt_task_t *task, nxt_process_t *process,
6061579St.nateldemoura@f5.com     nxt_array_t *lang_mounts)
6071579St.nateldemoura@f5.com {
6081579St.nateldemoura@f5.com     u_char          *p;
6091579St.nateldemoura@f5.com     size_t          i, n, rootfs_len, len;
6101579St.nateldemoura@f5.com     nxt_mp_t        *mp;
6111579St.nateldemoura@f5.com     nxt_array_t     *mounts;
6121579St.nateldemoura@f5.com     const u_char    *rootfs;
6131579St.nateldemoura@f5.com     nxt_fs_mount_t  *mnt, *lang_mnt;
6141579St.nateldemoura@f5.com 
6151579St.nateldemoura@f5.com     mp = process->mem_pool;
6161579St.nateldemoura@f5.com 
6171579St.nateldemoura@f5.com     /* copy to init mem pool */
6181579St.nateldemoura@f5.com     mounts = nxt_array_copy(mp, NULL, lang_mounts);
6191579St.nateldemoura@f5.com     if (mounts == NULL) {
6201579St.nateldemoura@f5.com         return NXT_ERROR;
6211579St.nateldemoura@f5.com     }
6221579St.nateldemoura@f5.com 
6231579St.nateldemoura@f5.com     n = mounts->nelts;
6241579St.nateldemoura@f5.com     mnt = mounts->elts;
6251579St.nateldemoura@f5.com     lang_mnt = lang_mounts->elts;
6261579St.nateldemoura@f5.com 
6271580St.nateldemoura@f5.com     rootfs = process->isolation.rootfs;
6281580St.nateldemoura@f5.com     rootfs_len = nxt_strlen(rootfs);
6291580St.nateldemoura@f5.com 
6301579St.nateldemoura@f5.com     for (i = 0; i < n; i++) {
6311579St.nateldemoura@f5.com         len = nxt_strlen(lang_mnt[i].dst);
6321579St.nateldemoura@f5.com 
6331579St.nateldemoura@f5.com         mnt[i].dst = nxt_mp_alloc(mp, rootfs_len + len + 1);
6341580St.nateldemoura@f5.com         if (nxt_slow_path(mnt[i].dst == NULL)) {
6351579St.nateldemoura@f5.com             return NXT_ERROR;
6361579St.nateldemoura@f5.com         }
6371579St.nateldemoura@f5.com 
6381579St.nateldemoura@f5.com         p = nxt_cpymem(mnt[i].dst, rootfs, rootfs_len);
6391579St.nateldemoura@f5.com         p = nxt_cpymem(p, lang_mnt[i].dst, len);
6401579St.nateldemoura@f5.com         *p = '\0';
6411579St.nateldemoura@f5.com     }
6421579St.nateldemoura@f5.com 
6431704St.nateldemoura@f5.com     if (process->isolation.automount.tmpfs) {
6441704St.nateldemoura@f5.com         mnt = nxt_array_add(mounts);
6451704St.nateldemoura@f5.com         if (nxt_slow_path(mnt == NULL)) {
6461704St.nateldemoura@f5.com             return NXT_ERROR;
6471704St.nateldemoura@f5.com         }
6481580St.nateldemoura@f5.com 
6491704St.nateldemoura@f5.com         mnt->src = (u_char *) "tmpfs";
6501704St.nateldemoura@f5.com         mnt->name = (u_char *) "tmpfs";
6511704St.nateldemoura@f5.com         mnt->type = NXT_FS_TMP;
6521704St.nateldemoura@f5.com         mnt->flags = (NXT_FS_FLAGS_NOSUID
6531704St.nateldemoura@f5.com                       | NXT_FS_FLAGS_NODEV
6541704St.nateldemoura@f5.com                       | NXT_FS_FLAGS_NOEXEC);
655*2331Sa.clayton@nginx.com         mnt->data = (u_char *) "size=1m,mode=1777";
6561704St.nateldemoura@f5.com         mnt->builtin = 1;
6571704St.nateldemoura@f5.com         mnt->deps = 0;
6581580St.nateldemoura@f5.com 
6591704St.nateldemoura@f5.com         mnt->dst = nxt_mp_nget(mp, rootfs_len + nxt_length("/tmp") + 1);
6601704St.nateldemoura@f5.com         if (nxt_slow_path(mnt->dst == NULL)) {
6611704St.nateldemoura@f5.com             return NXT_ERROR;
6621704St.nateldemoura@f5.com         }
6631704St.nateldemoura@f5.com 
6641704St.nateldemoura@f5.com         p = nxt_cpymem(mnt->dst, rootfs, rootfs_len);
6651704St.nateldemoura@f5.com         p = nxt_cpymem(p, "/tmp", 4);
6661704St.nateldemoura@f5.com         *p = '\0';
6671580St.nateldemoura@f5.com     }
6681580St.nateldemoura@f5.com 
6691708St.nateldemoura@f5.com     if (process->isolation.automount.procfs) {
6701708St.nateldemoura@f5.com         mnt = nxt_array_add(mounts);
6711708St.nateldemoura@f5.com         if (nxt_slow_path(mnt == NULL)) {
6721708St.nateldemoura@f5.com             return NXT_ERROR;
6731708St.nateldemoura@f5.com         }
6741580St.nateldemoura@f5.com 
6751708St.nateldemoura@f5.com         mnt->name = (u_char *) "proc";
6761708St.nateldemoura@f5.com         mnt->type = NXT_FS_PROC;
6771708St.nateldemoura@f5.com         mnt->src = (u_char *) "none";
6781708St.nateldemoura@f5.com         mnt->dst = nxt_mp_nget(mp, rootfs_len + nxt_length("/proc") + 1);
6791708St.nateldemoura@f5.com         if (nxt_slow_path(mnt->dst == NULL)) {
6801708St.nateldemoura@f5.com             return NXT_ERROR;
6811708St.nateldemoura@f5.com         }
6821580St.nateldemoura@f5.com 
6831708St.nateldemoura@f5.com         p = nxt_cpymem(mnt->dst, rootfs, rootfs_len);
6841708St.nateldemoura@f5.com         p = nxt_cpymem(p, "/proc", 5);
6851708St.nateldemoura@f5.com         *p = '\0';
6861580St.nateldemoura@f5.com 
6871708St.nateldemoura@f5.com         mnt->data = (u_char *) "";
6881708St.nateldemoura@f5.com         mnt->flags = NXT_FS_FLAGS_NOEXEC | NXT_FS_FLAGS_NOSUID;
6891708St.nateldemoura@f5.com         mnt->builtin = 1;
6901708St.nateldemoura@f5.com         mnt->deps = 0;
6911708St.nateldemoura@f5.com     }
6921580St.nateldemoura@f5.com 
6931671St.nateldemoura@f5.com     qsort(mounts->elts, mounts->nelts, sizeof(nxt_fs_mount_t),
6941671St.nateldemoura@f5.com           nxt_isolation_mount_compare);
6951671St.nateldemoura@f5.com 
6961579St.nateldemoura@f5.com     process->isolation.mounts = mounts;
6971579St.nateldemoura@f5.com 
6981579St.nateldemoura@f5.com     return NXT_OK;
6991579St.nateldemoura@f5.com }
7001579St.nateldemoura@f5.com 
7011579St.nateldemoura@f5.com 
7021671St.nateldemoura@f5.com static int nxt_cdecl
7031671St.nateldemoura@f5.com nxt_isolation_mount_compare(const void *v1, const void *v2)
7041671St.nateldemoura@f5.com {
7051671St.nateldemoura@f5.com     const nxt_fs_mount_t  *mnt1, *mnt2;
7061671St.nateldemoura@f5.com 
7071671St.nateldemoura@f5.com     mnt1 = v1;
7081671St.nateldemoura@f5.com     mnt2 = v2;
7091671St.nateldemoura@f5.com 
7101671St.nateldemoura@f5.com     return nxt_strlen(mnt1->src) > nxt_strlen(mnt2->src);
7111671St.nateldemoura@f5.com }
7121671St.nateldemoura@f5.com 
7131671St.nateldemoura@f5.com 
7141579St.nateldemoura@f5.com void
7151579St.nateldemoura@f5.com nxt_isolation_unmount_all(nxt_task_t *task, nxt_process_t *process)
7161579St.nateldemoura@f5.com {
7171671St.nateldemoura@f5.com     size_t                   n;
7181585St.nateldemoura@f5.com     nxt_array_t              *mounts;
7191671St.nateldemoura@f5.com     nxt_runtime_t            *rt;
7201585St.nateldemoura@f5.com     nxt_fs_mount_t           *mnt;
7211585St.nateldemoura@f5.com     nxt_process_automount_t  *automount;
7221579St.nateldemoura@f5.com 
7231671St.nateldemoura@f5.com     rt = task->thread->runtime;
7241671St.nateldemoura@f5.com 
7251671St.nateldemoura@f5.com     if (!rt->capabilities.setid) {
7261671St.nateldemoura@f5.com         return;
7271671St.nateldemoura@f5.com     }
7281671St.nateldemoura@f5.com 
7291579St.nateldemoura@f5.com     nxt_debug(task, "unmount all (%s)", process->name);
7301579St.nateldemoura@f5.com 
7311585St.nateldemoura@f5.com     automount = &process->isolation.automount;
7321579St.nateldemoura@f5.com     mounts = process->isolation.mounts;
7331579St.nateldemoura@f5.com     n = mounts->nelts;
7341579St.nateldemoura@f5.com     mnt = mounts->elts;
7351579St.nateldemoura@f5.com 
7361671St.nateldemoura@f5.com     while (n > 0) {
7371671St.nateldemoura@f5.com         n--;
7381671St.nateldemoura@f5.com 
7391673St.nateldemoura@f5.com         if (mnt[n].deps && !automount->language_deps) {
7401585St.nateldemoura@f5.com             continue;
7411585St.nateldemoura@f5.com         }
7421585St.nateldemoura@f5.com 
7431671St.nateldemoura@f5.com         nxt_fs_unmount(mnt[n].dst);
7441579St.nateldemoura@f5.com     }
7451579St.nateldemoura@f5.com }
7461579St.nateldemoura@f5.com 
7471579St.nateldemoura@f5.com 
7481579St.nateldemoura@f5.com nxt_int_t
7491579St.nateldemoura@f5.com nxt_isolation_prepare_rootfs(nxt_task_t *task, nxt_process_t *process)
7501579St.nateldemoura@f5.com {
7511585St.nateldemoura@f5.com     size_t                   i, n;
7521585St.nateldemoura@f5.com     nxt_int_t                ret;
7531585St.nateldemoura@f5.com     struct stat              st;
7541585St.nateldemoura@f5.com     nxt_array_t              *mounts;
7551585St.nateldemoura@f5.com     const u_char             *dst;
7561585St.nateldemoura@f5.com     nxt_fs_mount_t           *mnt;
7571585St.nateldemoura@f5.com     nxt_process_automount_t  *automount;
7581579St.nateldemoura@f5.com 
7591585St.nateldemoura@f5.com     automount = &process->isolation.automount;
7601579St.nateldemoura@f5.com     mounts = process->isolation.mounts;
7611579St.nateldemoura@f5.com 
7621579St.nateldemoura@f5.com     n = mounts->nelts;
7631579St.nateldemoura@f5.com     mnt = mounts->elts;
7641579St.nateldemoura@f5.com 
7651579St.nateldemoura@f5.com     for (i = 0; i < n; i++) {
7661579St.nateldemoura@f5.com         dst = mnt[i].dst;
7671579St.nateldemoura@f5.com 
7681673St.nateldemoura@f5.com         if (mnt[i].deps && !automount->language_deps) {
7691585St.nateldemoura@f5.com             continue;
7701585St.nateldemoura@f5.com         }
7711585St.nateldemoura@f5.com 
7721673St.nateldemoura@f5.com         if (nxt_slow_path(mnt[i].type == NXT_FS_BIND
7731579St.nateldemoura@f5.com                           && stat((const char *) mnt[i].src, &st) != 0))
7741579St.nateldemoura@f5.com         {
7751579St.nateldemoura@f5.com             nxt_log(task, NXT_LOG_WARN, "host path not found: %s", mnt[i].src);
7761579St.nateldemoura@f5.com             continue;
7771579St.nateldemoura@f5.com         }
7781579St.nateldemoura@f5.com 
7791579St.nateldemoura@f5.com         ret = nxt_fs_mkdir_all(dst, S_IRWXU | S_IRWXG | S_IRWXO);
7801579St.nateldemoura@f5.com         if (nxt_slow_path(ret != NXT_OK)) {
7811579St.nateldemoura@f5.com             nxt_alert(task, "mkdir(%s) %E", dst, nxt_errno);
7821579St.nateldemoura@f5.com             goto undo;
7831579St.nateldemoura@f5.com         }
7841579St.nateldemoura@f5.com 
7851579St.nateldemoura@f5.com         ret = nxt_fs_mount(task, &mnt[i]);
7861579St.nateldemoura@f5.com         if (nxt_slow_path(ret != NXT_OK)) {
7871579St.nateldemoura@f5.com             goto undo;
7881579St.nateldemoura@f5.com         }
7891579St.nateldemoura@f5.com     }
7901579St.nateldemoura@f5.com 
7911579St.nateldemoura@f5.com     return NXT_OK;
7921579St.nateldemoura@f5.com 
7931579St.nateldemoura@f5.com undo:
7941579St.nateldemoura@f5.com 
7951579St.nateldemoura@f5.com     n = i + 1;
7961579St.nateldemoura@f5.com 
7971579St.nateldemoura@f5.com     for (i = 0; i < n; i++) {
7981579St.nateldemoura@f5.com         nxt_fs_unmount(mnt[i].dst);
7991579St.nateldemoura@f5.com     }
8001579St.nateldemoura@f5.com 
8011579St.nateldemoura@f5.com     return NXT_ERROR;
8021579St.nateldemoura@f5.com }
8031579St.nateldemoura@f5.com 
8041579St.nateldemoura@f5.com 
8052170Salx.manpages@gmail.com #if (NXT_HAVE_LINUX_PIVOT_ROOT) && (NXT_HAVE_CLONE_NEWNS)
8061579St.nateldemoura@f5.com 
8071579St.nateldemoura@f5.com nxt_int_t
8081579St.nateldemoura@f5.com nxt_isolation_change_root(nxt_task_t *task, nxt_process_t *process)
8091579St.nateldemoura@f5.com {
8101579St.nateldemoura@f5.com     char       *rootfs;
8111579St.nateldemoura@f5.com     nxt_int_t  ret;
8121579St.nateldemoura@f5.com 
8131579St.nateldemoura@f5.com     rootfs = (char *) process->isolation.rootfs;
8141579St.nateldemoura@f5.com 
8151579St.nateldemoura@f5.com     nxt_debug(task, "change root: %s", rootfs);
8161579St.nateldemoura@f5.com 
8171595St.nateldemoura@f5.com     if (nxt_is_clone_flag_set(process->isolation.clone.flags, NEWNS)) {
8181579St.nateldemoura@f5.com         ret = nxt_isolation_pivot_root(task, rootfs);
8191579St.nateldemoura@f5.com 
8201579St.nateldemoura@f5.com     } else {
8211579St.nateldemoura@f5.com         ret = nxt_isolation_chroot(task, rootfs);
8221579St.nateldemoura@f5.com     }
8231579St.nateldemoura@f5.com 
8241579St.nateldemoura@f5.com     if (nxt_fast_path(ret == NXT_OK)) {
8251579St.nateldemoura@f5.com         if (nxt_slow_path(chdir("/") < 0)) {
8261579St.nateldemoura@f5.com             nxt_alert(task, "chdir(\"/\") %E", nxt_errno);
8271579St.nateldemoura@f5.com             return NXT_ERROR;
8281579St.nateldemoura@f5.com         }
8291579St.nateldemoura@f5.com     }
8301579St.nateldemoura@f5.com 
8311579St.nateldemoura@f5.com     return ret;
8321579St.nateldemoura@f5.com }
8331579St.nateldemoura@f5.com 
8341579St.nateldemoura@f5.com 
8351579St.nateldemoura@f5.com /*
8361579St.nateldemoura@f5.com  * pivot_root(2) can only be safely used with containers, otherwise it can
8371579St.nateldemoura@f5.com  * umount(2) the global root filesystem and screw up the machine.
8381579St.nateldemoura@f5.com  */
8391579St.nateldemoura@f5.com 
8401579St.nateldemoura@f5.com static nxt_int_t
8411579St.nateldemoura@f5.com nxt_isolation_pivot_root(nxt_task_t *task, const char *path)
8421579St.nateldemoura@f5.com {
8431579St.nateldemoura@f5.com     /*
8441579St.nateldemoura@f5.com      * This implementation makes use of a kernel trick that works for ages
8451579St.nateldemoura@f5.com      * and now documented in Linux kernel 5.
8461579St.nateldemoura@f5.com      * https://lore.kernel.org/linux-man/87r24piwhm.fsf@x220.int.ebiederm.org/T/
8471579St.nateldemoura@f5.com      */
8481579St.nateldemoura@f5.com 
8491579St.nateldemoura@f5.com     if (nxt_slow_path(mount("", "/", "", MS_SLAVE|MS_REC, "") != 0)) {
8501602Sartem.konev@nginx.com         nxt_alert(task, "mount(\"/\", MS_SLAVE|MS_REC) failed: %E", nxt_errno);
8511579St.nateldemoura@f5.com         return NXT_ERROR;
8521579St.nateldemoura@f5.com     }
8531579St.nateldemoura@f5.com 
8541579St.nateldemoura@f5.com     if (nxt_slow_path(nxt_isolation_make_private_mount(task, path) != NXT_OK)) {
8551579St.nateldemoura@f5.com         return NXT_ERROR;
8561579St.nateldemoura@f5.com     }
8571579St.nateldemoura@f5.com 
8581579St.nateldemoura@f5.com     if (nxt_slow_path(mount(path, path, "bind", MS_BIND|MS_REC, "") != 0)) {
8591579St.nateldemoura@f5.com         nxt_alert(task, "error bind mounting rootfs %E", nxt_errno);
8601579St.nateldemoura@f5.com         return NXT_ERROR;
8611579St.nateldemoura@f5.com     }
8621579St.nateldemoura@f5.com 
8631579St.nateldemoura@f5.com     if (nxt_slow_path(chdir(path) != 0)) {
8641579St.nateldemoura@f5.com         nxt_alert(task, "failed to chdir(%s) %E", path, nxt_errno);
8651579St.nateldemoura@f5.com         return NXT_ERROR;
8661579St.nateldemoura@f5.com     }
8671579St.nateldemoura@f5.com 
8681579St.nateldemoura@f5.com     if (nxt_slow_path(nxt_pivot_root(".", ".") != 0)) {
8691579St.nateldemoura@f5.com         nxt_alert(task, "failed to pivot_root %E", nxt_errno);
8701579St.nateldemoura@f5.com         return NXT_ERROR;
8711579St.nateldemoura@f5.com     }
8721579St.nateldemoura@f5.com 
8731579St.nateldemoura@f5.com     /*
8741602Sartem.konev@nginx.com      * Demote the oldroot mount to avoid unmounts getting propagated to
8751602Sartem.konev@nginx.com      * the host.
8761579St.nateldemoura@f5.com      */
8771579St.nateldemoura@f5.com     if (nxt_slow_path(mount("", ".", "", MS_SLAVE | MS_REC, NULL) != 0)) {
8781579St.nateldemoura@f5.com         nxt_alert(task, "failed to bind mount rootfs %E", nxt_errno);
8791579St.nateldemoura@f5.com         return NXT_ERROR;
8801579St.nateldemoura@f5.com     }
8811579St.nateldemoura@f5.com 
8821579St.nateldemoura@f5.com     if (nxt_slow_path(umount2(".", MNT_DETACH) != 0)) {
8831579St.nateldemoura@f5.com         nxt_alert(task, "failed to umount old root directory %E", nxt_errno);
8841579St.nateldemoura@f5.com         return NXT_ERROR;
8851579St.nateldemoura@f5.com     }
8861579St.nateldemoura@f5.com 
8871579St.nateldemoura@f5.com     return NXT_OK;
8881579St.nateldemoura@f5.com }
8891579St.nateldemoura@f5.com 
8901579St.nateldemoura@f5.com 
8911579St.nateldemoura@f5.com static nxt_int_t
8921579St.nateldemoura@f5.com nxt_isolation_make_private_mount(nxt_task_t *task, const char *rootfs)
8931579St.nateldemoura@f5.com {
8941579St.nateldemoura@f5.com     char           *parent_mnt;
8951579St.nateldemoura@f5.com     FILE           *procfile;
8961579St.nateldemoura@f5.com     u_char         **mounts;
8971579St.nateldemoura@f5.com     size_t         len;
8981579St.nateldemoura@f5.com     uint8_t        *shared;
8991579St.nateldemoura@f5.com     nxt_int_t      ret, index, nmounts;
9001579St.nateldemoura@f5.com     struct mntent  *ent;
9011579St.nateldemoura@f5.com 
9021579St.nateldemoura@f5.com     static const char  *mount_path = "/proc/self/mounts";
9031579St.nateldemoura@f5.com 
9041579St.nateldemoura@f5.com     ret = NXT_ERROR;
9051579St.nateldemoura@f5.com     ent = NULL;
9061579St.nateldemoura@f5.com     shared = NULL;
9071579St.nateldemoura@f5.com     procfile = NULL;
9081579St.nateldemoura@f5.com     parent_mnt = NULL;
9091579St.nateldemoura@f5.com 
9101579St.nateldemoura@f5.com     nmounts = 256;
9111579St.nateldemoura@f5.com 
9121579St.nateldemoura@f5.com     mounts = nxt_malloc(nmounts * sizeof(uintptr_t));
9131579St.nateldemoura@f5.com     if (nxt_slow_path(mounts == NULL)) {
9141579St.nateldemoura@f5.com         goto fail;
9151579St.nateldemoura@f5.com     }
9161579St.nateldemoura@f5.com 
9171579St.nateldemoura@f5.com     shared = nxt_malloc(nmounts);
9181579St.nateldemoura@f5.com     if (nxt_slow_path(shared == NULL)) {
9191579St.nateldemoura@f5.com         goto fail;
9201579St.nateldemoura@f5.com     }
9211579St.nateldemoura@f5.com 
9221579St.nateldemoura@f5.com     procfile = setmntent(mount_path, "r");
9231579St.nateldemoura@f5.com     if (nxt_slow_path(procfile == NULL)) {
9241579St.nateldemoura@f5.com         nxt_alert(task, "failed to open %s %E", mount_path, nxt_errno);
9251579St.nateldemoura@f5.com 
9261579St.nateldemoura@f5.com         goto fail;
9271579St.nateldemoura@f5.com     }
9281579St.nateldemoura@f5.com 
9291579St.nateldemoura@f5.com     index = 0;
9301579St.nateldemoura@f5.com 
9311579St.nateldemoura@f5.com again:
9321579St.nateldemoura@f5.com 
9331579St.nateldemoura@f5.com     for ( ; index < nmounts; index++) {
9341579St.nateldemoura@f5.com         ent = getmntent(procfile);
9351579St.nateldemoura@f5.com         if (ent == NULL) {
9361579St.nateldemoura@f5.com             nmounts = index;
9371579St.nateldemoura@f5.com             break;
9381579St.nateldemoura@f5.com         }
9391579St.nateldemoura@f5.com 
9401579St.nateldemoura@f5.com         mounts[index] = (u_char *) strdup(ent->mnt_dir);
9411579St.nateldemoura@f5.com         shared[index] = hasmntopt(ent, "shared") != NULL;
9421579St.nateldemoura@f5.com     }
9431579St.nateldemoura@f5.com 
9441579St.nateldemoura@f5.com     if (ent != NULL) {
9451579St.nateldemoura@f5.com         /* there are still entries to be read */
9461579St.nateldemoura@f5.com 
9471579St.nateldemoura@f5.com         nmounts *= 2;
9481579St.nateldemoura@f5.com         mounts = nxt_realloc(mounts, nmounts);
9491579St.nateldemoura@f5.com         if (nxt_slow_path(mounts == NULL)) {
9501579St.nateldemoura@f5.com             goto fail;
9511579St.nateldemoura@f5.com         }
9521579St.nateldemoura@f5.com 
9531579St.nateldemoura@f5.com         shared = nxt_realloc(shared, nmounts);
9541579St.nateldemoura@f5.com         if (nxt_slow_path(shared == NULL)) {
9551579St.nateldemoura@f5.com             goto fail;
9561579St.nateldemoura@f5.com         }
9571579St.nateldemoura@f5.com 
9581579St.nateldemoura@f5.com         goto again;
9591579St.nateldemoura@f5.com     }
9601579St.nateldemoura@f5.com 
9611579St.nateldemoura@f5.com     for (index = 0; index < nmounts; index++) {
9621579St.nateldemoura@f5.com         if (nxt_strcmp(mounts[index], rootfs) == 0) {
9631579St.nateldemoura@f5.com             parent_mnt = (char *) rootfs;
9641579St.nateldemoura@f5.com             break;
9651579St.nateldemoura@f5.com         }
9661579St.nateldemoura@f5.com     }
9671579St.nateldemoura@f5.com 
9681579St.nateldemoura@f5.com     if (parent_mnt == NULL) {
9691579St.nateldemoura@f5.com         len = nxt_strlen(rootfs);
9701579St.nateldemoura@f5.com 
9711579St.nateldemoura@f5.com         parent_mnt = nxt_malloc(len + 1);
9721579St.nateldemoura@f5.com         if (parent_mnt == NULL) {
9731579St.nateldemoura@f5.com             goto fail;
9741579St.nateldemoura@f5.com         }
9751579St.nateldemoura@f5.com 
9761579St.nateldemoura@f5.com         nxt_memcpy(parent_mnt, rootfs, len);
9771579St.nateldemoura@f5.com         parent_mnt[len] = '\0';
9781579St.nateldemoura@f5.com 
9791579St.nateldemoura@f5.com         if (parent_mnt[len - 1] == '/') {
9801579St.nateldemoura@f5.com             parent_mnt[len - 1] = '\0';
9811579St.nateldemoura@f5.com             len--;
9821579St.nateldemoura@f5.com         }
9831579St.nateldemoura@f5.com 
9841579St.nateldemoura@f5.com         for ( ;; ) {
9851579St.nateldemoura@f5.com             for (index = 0; index < nmounts; index++) {
9861579St.nateldemoura@f5.com                 if (nxt_strcmp(mounts[index], parent_mnt) == 0) {
9871579St.nateldemoura@f5.com                     goto found;
9881579St.nateldemoura@f5.com                 }
9891579St.nateldemoura@f5.com             }
9901579St.nateldemoura@f5.com 
9911579St.nateldemoura@f5.com             if (len == 1 && parent_mnt[0] == '/') {
9921579St.nateldemoura@f5.com                 nxt_alert(task, "parent mount not found");
9931579St.nateldemoura@f5.com                 goto fail;
9941579St.nateldemoura@f5.com             }
9951579St.nateldemoura@f5.com 
9961579St.nateldemoura@f5.com             /* parent dir */
9971579St.nateldemoura@f5.com             while (parent_mnt[len - 1] != '/' && len > 0) {
9981579St.nateldemoura@f5.com                 len--;
9991579St.nateldemoura@f5.com             }
10001579St.nateldemoura@f5.com 
10011579St.nateldemoura@f5.com             if (nxt_slow_path(len == 0)) {
10021579St.nateldemoura@f5.com                 nxt_alert(task, "parent mount not found");
10031579St.nateldemoura@f5.com                 goto fail;
10041579St.nateldemoura@f5.com             }
10051579St.nateldemoura@f5.com 
10061579St.nateldemoura@f5.com             if (len == 1) {
10071579St.nateldemoura@f5.com                 parent_mnt[len] = '\0';     /* / */
10081579St.nateldemoura@f5.com             } else {
10091579St.nateldemoura@f5.com                 parent_mnt[len - 1] = '\0'; /* /<path> */
10101579St.nateldemoura@f5.com             }
10111579St.nateldemoura@f5.com         }
10121579St.nateldemoura@f5.com     }
10131579St.nateldemoura@f5.com 
10141579St.nateldemoura@f5.com found:
10151579St.nateldemoura@f5.com 
10161579St.nateldemoura@f5.com     if (shared[index]) {
10171579St.nateldemoura@f5.com         if (nxt_slow_path(mount("", parent_mnt, "", MS_PRIVATE, "") != 0)) {
10181579St.nateldemoura@f5.com             nxt_alert(task, "mount(\"\", \"%s\", MS_PRIVATE) %E", parent_mnt,
10191579St.nateldemoura@f5.com                       nxt_errno);
10201579St.nateldemoura@f5.com 
10211579St.nateldemoura@f5.com             goto fail;
10221579St.nateldemoura@f5.com         }
10231579St.nateldemoura@f5.com     }
10241579St.nateldemoura@f5.com 
10251579St.nateldemoura@f5.com     ret = NXT_OK;
10261579St.nateldemoura@f5.com 
10271579St.nateldemoura@f5.com fail:
10281579St.nateldemoura@f5.com 
10291579St.nateldemoura@f5.com     if (procfile != NULL) {
10301579St.nateldemoura@f5.com         endmntent(procfile);
10311579St.nateldemoura@f5.com     }
10321579St.nateldemoura@f5.com 
10331579St.nateldemoura@f5.com     if (mounts != NULL) {
10341579St.nateldemoura@f5.com         for (index = 0; index < nmounts; index++) {
10351579St.nateldemoura@f5.com             nxt_free(mounts[index]);
10361579St.nateldemoura@f5.com         }
10371579St.nateldemoura@f5.com 
10381579St.nateldemoura@f5.com         nxt_free(mounts);
10391579St.nateldemoura@f5.com     }
10401579St.nateldemoura@f5.com 
10411579St.nateldemoura@f5.com     if (shared != NULL) {
10421579St.nateldemoura@f5.com         nxt_free(shared);
10431579St.nateldemoura@f5.com     }
10441579St.nateldemoura@f5.com 
10451579St.nateldemoura@f5.com     if (parent_mnt != NULL && parent_mnt != rootfs) {
10461579St.nateldemoura@f5.com         nxt_free(parent_mnt);
10471579St.nateldemoura@f5.com     }
10481579St.nateldemoura@f5.com 
10491579St.nateldemoura@f5.com     return ret;
10501579St.nateldemoura@f5.com }
10511579St.nateldemoura@f5.com 
10521579St.nateldemoura@f5.com 
10531579St.nateldemoura@f5.com nxt_inline int
10541579St.nateldemoura@f5.com nxt_pivot_root(const char *new_root, const char *old_root)
10551579St.nateldemoura@f5.com {
10562153Salx.manpages@gmail.com     return syscall(SYS_pivot_root, new_root, old_root);
10571579St.nateldemoura@f5.com }
10581579St.nateldemoura@f5.com 
10591579St.nateldemoura@f5.com 
10602170Salx.manpages@gmail.com #else /* !(NXT_HAVE_LINUX_PIVOT_ROOT) || !(NXT_HAVE_CLONE_NEWNS) */
10611579St.nateldemoura@f5.com 
10621579St.nateldemoura@f5.com 
10631579St.nateldemoura@f5.com nxt_int_t
10641579St.nateldemoura@f5.com nxt_isolation_change_root(nxt_task_t *task, nxt_process_t *process)
10651579St.nateldemoura@f5.com {
10661579St.nateldemoura@f5.com     char       *rootfs;
10671579St.nateldemoura@f5.com 
10681579St.nateldemoura@f5.com     rootfs = (char *) process->isolation.rootfs;
10691579St.nateldemoura@f5.com 
10701579St.nateldemoura@f5.com     nxt_debug(task, "change root: %s", rootfs);
10711579St.nateldemoura@f5.com 
10721579St.nateldemoura@f5.com     if (nxt_fast_path(nxt_isolation_chroot(task, rootfs) == NXT_OK)) {
10731579St.nateldemoura@f5.com         if (nxt_slow_path(chdir("/") < 0)) {
10741579St.nateldemoura@f5.com             nxt_alert(task, "chdir(\"/\") %E", nxt_errno);
10751579St.nateldemoura@f5.com             return NXT_ERROR;
10761579St.nateldemoura@f5.com         }
10771579St.nateldemoura@f5.com 
10781579St.nateldemoura@f5.com         return NXT_OK;
10791579St.nateldemoura@f5.com     }
10801579St.nateldemoura@f5.com 
10811579St.nateldemoura@f5.com     return NXT_ERROR;
10821579St.nateldemoura@f5.com }
10831579St.nateldemoura@f5.com 
10841579St.nateldemoura@f5.com #endif
10851579St.nateldemoura@f5.com 
10861579St.nateldemoura@f5.com 
10871579St.nateldemoura@f5.com static nxt_int_t
10881579St.nateldemoura@f5.com nxt_isolation_chroot(nxt_task_t *task, const char *path)
10891579St.nateldemoura@f5.com {
10901579St.nateldemoura@f5.com     if (nxt_slow_path(chroot(path) < 0)) {
10911579St.nateldemoura@f5.com         nxt_alert(task, "chroot(%s) %E", path, nxt_errno);
10921579St.nateldemoura@f5.com         return NXT_ERROR;
10931579St.nateldemoura@f5.com     }
10941579St.nateldemoura@f5.com 
10951579St.nateldemoura@f5.com     return NXT_OK;
10961579St.nateldemoura@f5.com }
10971579St.nateldemoura@f5.com 
10981579St.nateldemoura@f5.com #endif /* NXT_HAVE_ISOLATION_ROOTFS */
10991579St.nateldemoura@f5.com 
11001579St.nateldemoura@f5.com 
11011579St.nateldemoura@f5.com #if (NXT_HAVE_PR_SET_NO_NEW_PRIVS)
11021579St.nateldemoura@f5.com 
11031579St.nateldemoura@f5.com static nxt_int_t
11041579St.nateldemoura@f5.com nxt_isolation_set_new_privs(nxt_task_t *task, nxt_conf_value_t *isolation,
11051579St.nateldemoura@f5.com     nxt_process_t *process)
11061579St.nateldemoura@f5.com {
11071579St.nateldemoura@f5.com     nxt_conf_value_t  *obj;
11081579St.nateldemoura@f5.com 
11091579St.nateldemoura@f5.com     static nxt_str_t  new_privs_name = nxt_string("new_privs");
11101579St.nateldemoura@f5.com 
11111579St.nateldemoura@f5.com     obj = nxt_conf_get_object_member(isolation, &new_privs_name, NULL);
11121579St.nateldemoura@f5.com     if (obj != NULL) {
11131579St.nateldemoura@f5.com         process->isolation.new_privs = nxt_conf_get_boolean(obj);
11141579St.nateldemoura@f5.com     }
11151579St.nateldemoura@f5.com 
11161579St.nateldemoura@f5.com     return NXT_OK;
11171579St.nateldemoura@f5.com }
11181579St.nateldemoura@f5.com 
11191579St.nateldemoura@f5.com #endif
1120