TTXProviderMgr* ttx_provider_mgr_new (void) { TTXProviderMgr *self; unsigned u; self = g_new0 (TTXProviderMgr, 1); self->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify)ttx_provider_destroy); for (u = 0; u != G_N_ELEMENTS(TTX_PROVIDERS); ++u) { TTXProvider *prov; if (!(prov = TTX_PROVIDERS[u].new_func())) { g_warning ("invalid provider %u", u); ttx_provider_mgr_destroy (self); return NULL; } g_hash_table_insert (self->hash, g_strdup(TTX_PROVIDERS[u].prov_id), prov); } self->tmpdir = g_strdup_printf ("%s/ttx-XXXXXX", g_get_tmp_dir()); self->tmpdir = g_mkdtemp_full (self->tmpdir, 00700); return self; }
static void set_up_mock_xdg_runtime_dir (void) { GError *error = NULL; GSocketAddress *addr; mock_bus = g_socket_new (G_SOCKET_FAMILY_UNIX, G_SOCKET_TYPE_STREAM, 0, &error); g_assert_no_error (error); g_assert_true (G_IS_SOCKET (mock_bus)); /* alters tmpdir in-place */ if (g_mkdtemp_full (tmpdir, 0700) == NULL) { int errsv = errno; g_error ("g_mkdtemp_full: %s", g_strerror (errsv)); } mock_bus_path = g_strconcat (tmpdir, "/bus", NULL); addr = g_unix_socket_address_new (mock_bus_path); g_socket_bind (mock_bus, addr, FALSE, &error); g_assert_no_error (error); g_object_unref (addr); g_setenv ("XDG_RUNTIME_DIR", tmpdir, TRUE); }
int main(gint argc, gchar **argv) { const gchar *self = *argv++; if (argc < 2) { g_message("%s command [arguments...]", self); return 1; } if (g_getenv("NIX_CHROOTENV")) g_warning("chrootenv doesn't stack!"); else g_setenv("NIX_CHROOTENV", "", TRUE); g_autofree gchar *prefix = g_build_filename(g_get_tmp_dir(), "chrootenvXXXXXX", NULL); fail_if(!g_mkdtemp_full(prefix, 0755)); pid_t cpid = fork(); if (cpid < 0) fail("fork", errno); else if (cpid == 0) { uid_t uid = getuid(); gid_t gid = getgid(); if (unshare(CLONE_NEWNS | CLONE_NEWUSER) < 0) { int unshare_errno = errno; g_message("Requires Linux version >= 3.19 built with CONFIG_USER_NS"); if (g_file_test("/proc/sys/kernel/unprivileged_userns_clone", G_FILE_TEST_EXISTS)) g_message("Run: sudo sysctl -w kernel.unprivileged_userns_clone=1"); fail("unshare", unshare_errno); } spit("/proc/self/setgroups", "deny"); spit("/proc/self/uid_map", "%d %d 1", uid, uid); spit("/proc/self/gid_map", "%d %d 1", gid, gid); bind("/", prefix); fail_if(chroot(prefix)); fail_if(chdir("/")); fail_if(execvp(*argv, argv)); } else { int status; fail_if(waitpid(cpid, &status, 0) != cpid); fail_if(nftw(prefix, nftw_remove, getdtablesize(), FTW_DEPTH | FTW_MOUNT | FTW_PHYS)); if (WIFEXITED(status)) return WEXITSTATUS(status); else if (WIFSIGNALED(status)) kill(getpid(), WTERMSIG(status)); return 1; } }
const gchar *create_tmpdir() { gchar *prefix = g_build_filename(g_get_tmp_dir(), "chrootenvXXXXXX", NULL); fail_if(!g_mkdtemp_full(prefix, 0755)); return prefix; }