support creating new uts namespaces (and setting hostnames)
Bug: None
Test: `sudo ./minijail0 --uts=foo /bin/hostname` shows "foo"
Change-Id: Ibfd36fb64983413688fcbb58541b2aae3132df49
diff --git a/libminijail.c b/libminijail.c
index 1da4e19..81cea4b 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -106,6 +106,7 @@
int skip_remount_private : 1;
int pids : 1;
int ipc : 1;
+ int uts : 1;
int net : 1;
int enter_net : 1;
int ns_cgroups : 1;
@@ -144,6 +145,7 @@
char *pid_file_path;
char *uidmap;
char *gidmap;
+ char *hostname;
size_t filter_len;
struct sock_fprog *filter_prog;
char *alt_syscall_table;
@@ -439,6 +441,22 @@
j->flags.ipc = 1;
}
+void API minijail_namespace_uts(struct minijail *j)
+{
+ j->flags.uts = 1;
+}
+
+int API minijail_namespace_set_hostname(struct minijail *j, const char *name)
+{
+ if (j->hostname)
+ return -EINVAL;
+ minijail_namespace_uts(j);
+ j->hostname = strdup(name);
+ if (!j->hostname)
+ return -ENOMEM;
+ return 0;
+}
+
void API minijail_namespace_net(struct minijail *j)
{
j->flags.net = 1;
@@ -869,6 +887,8 @@
}
if (j->chrootdir)
marshal_append(state, j->chrootdir, strlen(j->chrootdir) + 1);
+ if (j->hostname)
+ marshal_append(state, j->hostname, strlen(j->hostname) + 1);
if (j->alt_syscall_table) {
marshal_append(state, j->alt_syscall_table,
strlen(j->alt_syscall_table) + 1);
@@ -956,6 +976,15 @@
goto bad_chrootdir;
}
+ if (j->hostname) { /* stale pointer */
+ char *hostname = consumestr(&serialized, &length);
+ if (!hostname)
+ goto bad_hostname;
+ j->hostname = strdup(hostname);
+ if (!j->hostname)
+ goto bad_hostname;
+ }
+
if (j->alt_syscall_table) { /* stale pointer */
char *alt_syscall_table = consumestr(&serialized, &length);
if (!alt_syscall_table)
@@ -1062,6 +1091,9 @@
if (j->chrootdir)
free(j->chrootdir);
bad_chrootdir:
+ if (j->hostname)
+ free(j->hostname);
+bad_hostname:
if (j->suppl_gid_list)
free(j->suppl_gid_list);
bad_gid_list:
@@ -1071,6 +1103,7 @@
j->user = NULL;
j->suppl_gid_list = NULL;
j->chrootdir = NULL;
+ j->hostname = NULL;
j->alt_syscall_table = NULL;
j->cgroup_count = 0;
out:
@@ -1594,6 +1627,14 @@
pdie("unshare(CLONE_NEWIPC) failed");
}
+ if (j->flags.uts) {
+ if (unshare(CLONE_NEWUTS))
+ pdie("unshare(CLONE_NEWUTS) failed");
+
+ if (j->hostname && sethostname(j->hostname, strlen(j->hostname)))
+ pdie("sethostname(%s) failed", j->hostname);
+ }
+
if (j->flags.enter_net) {
if (setns(j->netns_fd, CLONE_NEWNET))
pdie("setns(CLONE_NEWNET) failed");
@@ -2345,6 +2386,8 @@
free(j->uidmap);
if (j->gidmap)
free(j->gidmap);
+ if (j->hostname)
+ free(j->hostname);
if (j->alt_syscall_table)
free(j->alt_syscall_table);
for (i = 0; i < j->cgroup_count; ++i)