Last active
April 5, 2024 07:09
-
-
Save oskarirauta/3ca45fc058620363a8fb092687a2c412 to your computer and use it in GitHub Desktop.
procd patches
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- a/jail/jail.c | |
+++ b/jail/jail.c | |
@@ -585,7 +585,7 @@ static struct mknod_args default_devices | |
{ .path = "/dev/full", .mode = (S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH), .dev = makedev(1, 7) }, | |
{ .path = "/dev/random", .mode = (S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH), .dev = makedev(1, 8) }, | |
{ .path = "/dev/urandom", .mode = (S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH), .dev = makedev(1, 9) }, | |
- { .path = "/dev/tty", .mode = (S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP), .dev = makedev(5, 0), .gid = 5 }, | |
+ { .path = "/dev/tty", .mode = (S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH), .dev = makedev(5, 0), .gid = 5 }, | |
{ 0 }, | |
}; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- a/uxc.c | |
+++ b/uxc.c | |
@@ -27,6 +27,7 @@ | |
#include <unistd.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
+#include <sched.h> | |
#include <libubus.h> | |
#include <libubox/avl-cmp.h> | |
@@ -71,6 +72,7 @@ struct settings { | |
enum uxc_cmd { | |
CMD_ATTACH, | |
+ CMD_EXEC, | |
CMD_LIST, | |
CMD_BOOT, | |
CMD_START, | |
@@ -112,6 +114,7 @@ static int usage(void) { | |
printf("commands:\n"); | |
printf("\tlist [--json]\t\t\t\tlist all configured containers\n"); | |
printf("\tattach <conf>\t\t\t\tattach to container console\n"); | |
+ printf("\texec <conf> [cmd]\t\t\texecute command or shell in container\n"); | |
printf("\tcreate <conf>\t\t\t\t(re-)create <conf>\n"); | |
printf("\t\t[--bundle <path>]\t\t\tOCI bundle at <path>\n"); | |
printf("\t\t[--autostart]\t\t\t\tstart on boot\n"); | |
@@ -150,6 +153,29 @@ static const struct blobmsg_policy conf_ | |
[CONF_VOLUMES] = { .name = "volumes", .type = BLOBMSG_TYPE_ARRAY }, | |
}; | |
+static int open_ns(int pid, char *name) { | |
+ | |
+ char *path; | |
+ | |
+ if (asprintf(&path, "/proc/%d/%s", pid, name) == -1 ) { | |
+ fprintf(stderr, "cannot allocate path /proc/%d/%s\n", pid, name); | |
+ return -1; | |
+ } | |
+ | |
+ struct stat st; | |
+ if (stat(path, &st) == 0 && S_ISLNK(st.st_mode)) { | |
+ fprintf(stderr, "file /proc/%d/%s does not exists or is not a symbolic link\n", pid, name); | |
+ return -1; | |
+ } | |
+ | |
+ int fd = open(path, O_RDONLY); | |
+ if ( fd < 0 ) { | |
+ fprintf(stderr, "cannot open /proc/%d/%s\n", pid, name); | |
+ return fd; | |
+ } | |
+ return fd; | |
+} | |
+ | |
static int conf_load(bool load_settings) | |
{ | |
int gl_flags = GLOB_NOESCAPE | GLOB_MARK; | |
@@ -613,6 +639,94 @@ static int uxc_attach(const char *contai | |
return 0; | |
} | |
+static int uxc_exec(const char *container_name, char **args) | |
+{ | |
+ struct blob_attr *cur, *tb[__CONF_MAX], *ts[__STATE_MAX]; | |
+ struct runtime_state *rsstate = NULL; | |
+ int rem, container_pid; | |
+ bool found = false; | |
+ | |
+ blobmsg_for_each_attr(cur, blob_data(conf.head), rem) { | |
+ blobmsg_parse(conf_policy, __CONF_MAX, tb, blobmsg_data(cur), blobmsg_len(cur)); | |
+ if (!tb[CONF_NAME] || !tb[CONF_PATH]) | |
+ continue; | |
+ | |
+ if (strcmp(container_name, blobmsg_get_string(tb[CONF_NAME]))) | |
+ continue; | |
+ | |
+ found = true; | |
+ break; | |
+ } | |
+ | |
+ if (!found) | |
+ return -ENOENT; | |
+ | |
+ rsstate = avl_find_element(&runtime, container_name, rsstate, avl); | |
+ container_pid = 0; | |
+ | |
+ if (rsstate && rsstate->ocistate) { | |
+ blobmsg_parse(state_policy, __STATE_MAX, ts, blobmsg_data(rsstate->ocistate), blobmsg_len(rsstate->ocistate)); | |
+ container_pid = blobmsg_get_u32(ts[STATE_PID]); | |
+ } | |
+ | |
+ if (container_pid < 2) { | |
+ fprintf(stderr, "failed to container pid for %s\n", container_name); | |
+ return -ENOENT; | |
+ } | |
+ | |
+ int ns_ipc = open_ns(container_pid, "ns/ipc"); | |
+ int ns_mnt = open_ns(container_pid, "ns/mnt"); | |
+ int ns_net = open_ns(container_pid, "ns/net"); | |
+ int ns_uts = open_ns(container_pid, "ns/uts"); | |
+ int ns_pid = open_ns(container_pid, "ns/pid"); | |
+ int ns_root = open_ns(container_pid, "root"); | |
+ | |
+ if (ns_ipc == -1 || ns_mnt == -1 || ns_net == -1 || ns_uts == -1 || ns_pid == -1 || ns_root == -1) | |
+ return -ENXIO; | |
+ | |
+ if (setns(ns_ipc, 0) == -1) { | |
+ fprintf(stderr, "failed to enter ipc namespace\n"); | |
+ return -ENXIO; | |
+ } | |
+ | |
+ if (setns(ns_mnt, 0) == -1) { | |
+ fprintf(stderr, "failed to enter mnt namespace\n"); | |
+ return -ENXIO; | |
+ } | |
+ | |
+ if (setns(ns_net, 0) == -1) { | |
+ fprintf(stderr, "failed to enter net namespace\n"); | |
+ return -ENXIO; | |
+ } | |
+ | |
+ if (setns(ns_uts, 0) == -1) { | |
+ fprintf(stderr, "failed to enter uts namespace\n"); | |
+ return -ENXIO; | |
+ } | |
+ | |
+ if (setns(ns_pid, 0) == -1) { | |
+ fprintf(stderr, "failed to enter pid namespace\n"); | |
+ return -ENXIO; | |
+ } | |
+ | |
+ if (fchdir(ns_root) == -1) { | |
+ fprintf(stderr, "failed to change working directory\n"); | |
+ return -ENXIO; | |
+ } | |
+ | |
+ if (chroot(".") == -1) { | |
+ fprintf(stderr, "failed to chroot\n"); | |
+ return -ENXIO; | |
+ } | |
+ | |
+ if (execv(args[0], args) == -1) { | |
+ fprintf(stderr, "failed to execute %s in container %s\n", args[0], container_name); | |
+ return -ENXIO; | |
+ } | |
+ | |
+ return 0; | |
+} | |
+ | |
static int uxc_state(char *name) | |
{ | |
struct runtime_state *rsstate = avl_find_element(&runtime, name, rsstate, avl); | |
@@ -1413,7 +1527,10 @@ int main(int argc, char **argv) | |
if (ret) | |
goto settings_avl_out; | |
- while (true) { | |
+ if ( argc > 1 && !strcmp("exec", argv[1])) | |
+ cmd = CMD_EXEC; | |
+ | |
+ while (cmd != CMD_EXEC) { | |
int option_index = 0; | |
c = getopt_long(argc, argv, OPT_ARGS, long_options, &option_index); | |
if (c == -1) | |
@@ -1466,13 +1583,15 @@ int main(int argc, char **argv) | |
} | |
} | |
- if (optind == argc) | |
+ if (optind == argc && cmd != CMD_EXEC) | |
goto usage_out; | |
if (!strcmp("list", argv[optind])) | |
cmd = CMD_LIST; | |
else if (!strcmp("attach", argv[optind])) | |
cmd = CMD_ATTACH; | |
+ else if (!strcmp("exec", argv[optind])) | |
+ cmd = CMD_EXEC; | |
else if (!strcmp("boot", argv[optind])) | |
cmd = CMD_BOOT; | |
else if(!strcmp("start", argv[optind])) | |
@@ -1498,6 +1617,24 @@ int main(int argc, char **argv) | |
ret = uxc_attach(argv[optind + 1]); | |
break; | |
+ case CMD_EXEC: | |
+ if (argc < 3) | |
+ goto usage_out; | |
+ | |
+ int i; | |
+ char *cmd = argc < 4 ? "/bin/sh" : argv[3]; | |
+ int cnt = argc < 5 ? 2 : ( argc - 2 ); | |
+ char **args = (char **)malloc(cnt * sizeof(char*)); | |
+ | |
+ if (argc > 3) { | |
+ for (i = 0; i < cnt - 1; i++ ) | |
+ args[i] = argv[i + 3]; | |
+ } else args[0] = cmd; | |
+ | |
+ args[cnt - 1] = NULL; | |
+ ret = uxc_exec(argv[optind + 1], args); | |
+ break; | |
+ | |
case CMD_LIST: | |
ret = uxc_list(); | |
break; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- a/uxc.c | |
+++ b/uxc.c | |
@@ -1598,13 +1598,13 @@ int main(int argc, char **argv) | |
cmd = CMD_START; | |
else if(!strcmp("state", argv[optind])) | |
cmd = CMD_STATE; | |
- else if(!strcmp("kill", argv[optind])) | |
+ else if(!strcmp("kill", argv[optind]) || !strcmp("stop", argv[optind])) | |
cmd = CMD_KILL; | |
else if(!strcmp("enable", argv[optind])) | |
cmd = CMD_ENABLE; | |
else if(!strcmp("disable", argv[optind])) | |
cmd = CMD_DISABLE; | |
- else if(!strcmp("delete", argv[optind])) | |
+ else if(!strcmp("delete", argv[optind]) || !strcmp("rm", argv[optind])) | |
cmd = CMD_DELETE; | |
else if(!strcmp("create", argv[optind])) | |
cmd = CMD_CREATE; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- a/uxc.c | |
+++ b/uxc.c | |
@@ -82,6 +82,7 @@ enum uxc_cmd { | |
CMD_DISABLE, | |
CMD_DELETE, | |
CMD_CREATE, | |
+ CMD_RESTART, | |
CMD_UNKNOWN | |
}; | |
@@ -124,6 +125,7 @@ static int usage(void) { | |
printf("\tstart [--console] <conf>\t\tstart container <conf>\n"); | |
printf("\tstate <conf>\t\t\t\tget state of container <conf>\n"); | |
printf("\tkill <conf> [<signal>]\t\t\tsend signal to container <conf>\n"); | |
+ printf("\trestart [--console] <conf> [<signal>]\trestart container <conf>\n"); | |
printf("\tenable <conf>\t\t\t\tstart container <conf> on boot\n"); | |
printf("\tdisable <conf>\t\t\t\tdon't start container <conf> on boot\n"); | |
printf("\tdelete <conf> [--force]\t\t\tdelete <conf>\n"); | |
@@ -1600,6 +1602,8 @@ int main(int argc, char **argv) | |
cmd = CMD_STATE; | |
else if(!strcmp("kill", argv[optind]) || !strcmp("stop", argv[optind])) | |
cmd = CMD_KILL; | |
+ else if(!strcmp("restart", argv[optind])) | |
+ cmd = CMD_RESTART; | |
else if(!strcmp("enable", argv[optind])) | |
cmd = CMD_ENABLE; | |
else if(!strcmp("disable", argv[optind])) | |
@@ -1649,6 +1653,39 @@ int main(int argc, char **argv) | |
ret = uxc_start(argv[optind + 1], console); | |
break; | |
+ | |
+ case CMD_RESTART: | |
+ if (optind == (argc - 3)) | |
+ signal = atoi(argv[optind + 2]); | |
+ else if (optind != argc - 2) | |
+ goto usage_out; | |
+ | |
+ uxc_kill(argv[optind + 1], signal); | |
+ | |
+ runtime_free(); // poll runtime | |
+ sleep(1); | |
+ runtime_load(); | |
+ | |
+ ret = uxc_exists(argv[optind + 1]); | |
+ if (ret) | |
+ goto runtime_out; | |
+ | |
+ ret = uxc_set(argv[optind + 1], bundle, autostart, pidfile, tmprwsize, writepath, requiredmounts); | |
+ if (ret < 0) | |
+ goto runtime_out; | |
+ else if (ret > 0) | |
+ reload_conf(); | |
+ | |
+ ret = uxc_create(argv[optind + 1], false); | |
+ if (ret != 0) | |
+ goto runtime_out; | |
+ | |
+ runtime_free(); // poll runtime again | |
+ sleep(1); | |
+ runtime_load(); | |
+ | |
+ ret = uxc_start(argv[optind + 1], console); | |
+ break; | |
case CMD_STATE: | |
if (optind != argc - 2) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- a/jail/jail.c | |
+++ b/jail/jail.c | |
@@ -322,7 +322,7 @@ static int mount_overlay(char *jail_root | |
fd = creat(upperresolvconf, 0644); | |
if (fd < 0) { | |
- if (errno != EEXIST) | |
+ if (errno != EEXIST && errno != ENOENT) | |
ERROR("creat(%s) failed: %m\n", upperresolvconf); | |
} else { | |
close(fd); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- a/uxc.c | |
+++ b/uxc.c | |
@@ -67,6 +67,7 @@ struct settings { | |
char *tmprwsize; | |
char *writepath; | |
signed char autostart; | |
+ signed char no_resolv; | |
struct blob_attr *volumes; | |
}; | |
@@ -86,7 +87,7 @@ enum uxc_cmd { | |
CMD_UNKNOWN | |
}; | |
-#define OPT_ARGS "ab:fjm:p:t:vVw:" | |
+#define OPT_ARGS "ab:fjm:np:t:vVw:" | |
static struct option long_options[] = { | |
{"autostart", no_argument, 0, 'a' }, | |
{"console", no_argument, 0, 'c' }, | |
@@ -94,6 +95,7 @@ static struct option long_options[] = { | |
{"force", no_argument, 0, 'f' }, | |
{"json", no_argument, 0, 'j' }, | |
{"mounts", required_argument, 0, 'm' }, | |
+ {"no-resolv", no_argument, 0, 'n' }, | |
{"pid-file", required_argument, 0, 'p' }, | |
{"temp-overlay-size", required_argument, 0, 't' }, | |
{"write-overlay-path", required_argument, 0, 'w' }, | |
@@ -122,6 +124,7 @@ static int usage(void) { | |
printf("\t\t[--temp-overlay-size <size>]\t\tuse tmpfs overlay with {size}\n"); | |
printf("\t\t[--write-overlay-path <path>]\t\tuse overlay on {path}\n"); | |
printf("\t\t[--mounts <v1>,<v2>,...,<vN>]\t\trequire filesystems to be available\n"); | |
+ printf("\t\t[--no-resolv]\t\t\t\tskip resolv.conf auto-generation\n"); | |
printf("\tstart [--console] <conf>\t\tstart container <conf>\n"); | |
printf("\tstate <conf>\t\t\t\tget state of container <conf>\n"); | |
printf("\tkill <conf> [<signal>]\t\t\tsend signal to container <conf>\n"); | |
@@ -140,6 +143,7 @@ enum { | |
CONF_PIDFILE, | |
CONF_TEMP_OVERLAY_SIZE, | |
CONF_WRITE_OVERLAY_PATH, | |
+ CONF_NO_RESOLV, | |
CONF_VOLUMES, | |
__CONF_MAX, | |
}; | |
@@ -152,6 +156,7 @@ static const struct blobmsg_policy conf_ | |
[CONF_PIDFILE] = { .name = "pidfile", .type = BLOBMSG_TYPE_STRING }, | |
[CONF_TEMP_OVERLAY_SIZE] = { .name = "temp-overlay-size", .type = BLOBMSG_TYPE_STRING }, | |
[CONF_WRITE_OVERLAY_PATH] = { .name = "write-overlay-path", .type = BLOBMSG_TYPE_STRING }, | |
+ [CONF_NO_RESOLV] = { .name = "no-resolv", .type = BLOBMSG_TYPE_BOOL }, | |
[CONF_VOLUMES] = { .name = "volumes", .type = BLOBMSG_TYPE_ARRAY }, | |
}; | |
@@ -238,6 +243,7 @@ settings_alloc(const char *container_nam | |
s->container_name = new_name; | |
s->avl.key = s->container_name; | |
s->autostart = -1; | |
+ s->no_resolv = -1; | |
s->tmprwsize = NULL; | |
s->writepath = NULL; | |
s->volumes = NULL; | |
@@ -271,6 +277,9 @@ static int settings_add(void) | |
if (tb[CONF_WRITE_OVERLAY_PATH]) | |
s->writepath = blobmsg_get_string(tb[CONF_WRITE_OVERLAY_PATH]); | |
+ if (tb[CONF_NO_RESOLV]) | |
+ s->no_resolv = blobmsg_get_bool(tb[CONF_NO_RESOLV]); | |
+ | |
s->volumes = tb[CONF_VOLUMES]; | |
s->fname = blobmsg_name(cur); | |
@@ -801,7 +810,7 @@ static int uxc_list(void) | |
struct settings *usettings = NULL; | |
char *name, *ocistatus, *status, *tmp; | |
int container_pid = -1; | |
- bool autostart; | |
+ bool autostart, no_resolv; | |
static struct blob_buf buf; | |
void *arr, *obj; | |
@@ -816,6 +825,7 @@ static int uxc_list(void) | |
continue; | |
autostart = tb[CONF_AUTOSTART] && blobmsg_get_bool(tb[CONF_AUTOSTART]); | |
+ no_resolv = tb[CONF_NO_RESOLV] && blobmsg_get_bool(tb[CONF_NO_RESOLV]); | |
ocistatus = NULL; | |
container_pid = 0; | |
@@ -840,6 +850,7 @@ static int uxc_list(void) | |
blobmsg_add_string(&buf, "name", name); | |
blobmsg_add_string(&buf, "status", status); | |
blobmsg_add_u8(&buf, "autostart", autostart); | |
+ blobmsg_add_u8(&buf, "no-resolv", no_resolv); | |
} else { | |
printf("[%c] %s %s", autostart?'*':' ', name, status); | |
} | |
@@ -905,6 +916,7 @@ static int uxc_create(char *name, bool i | |
uint32_t id; | |
struct settings *usettings = NULL; | |
char *path = NULL, *jailname = NULL, *pidfile = NULL, *tmprwsize = NULL, *writepath = NULL; | |
+ bool no_resolv = false; | |
void *in, *ins, *j; | |
bool found = false; | |
@@ -935,6 +947,9 @@ static int uxc_create(char *name, bool i | |
if (tb[CONF_WRITE_OVERLAY_PATH]) | |
writepath = blobmsg_get_string(tb[CONF_WRITE_OVERLAY_PATH]); | |
+ if (tb[CONF_NO_RESOLV]) | |
+ no_resolv = blobmsg_get_bool(tb[CONF_NO_RESOLV]); | |
+ | |
if (tb[CONF_JAIL]) | |
jailname = blobmsg_get_string(tb[CONF_JAIL]); | |
@@ -948,6 +963,8 @@ static int uxc_create(char *name, bool i | |
tmprwsize = usettings->tmprwsize; | |
writepath = NULL; | |
} | |
+ if (usettings->no_resolv) | |
+ no_resolv = usettings->no_resolv; | |
} | |
blob_buf_init(&req, 0); | |
@@ -970,6 +987,9 @@ static int uxc_create(char *name, bool i | |
if (tmprwsize) | |
blobmsg_add_string(&req, "tmpoverlaysize", tmprwsize); | |
+ if (no_resolv) | |
+ blobmsg_add_u8(&req, "no-resolv", !!no_resolv); | |
+ | |
blobmsg_close_table(&req, in); | |
blobmsg_close_table(&req, ins); | |
@@ -1063,7 +1083,7 @@ static int uxc_kill(char *name, int sign | |
} | |
-static int uxc_set(char *name, char *path, signed char autostart, char *pidfile, char *tmprwsize, char *writepath, char *requiredmounts) | |
+static int uxc_set(char *name, char *path, signed char autostart, signed char no_resolv, char *pidfile, char *tmprwsize, char *writepath, char *requiredmounts) | |
{ | |
static struct blob_buf req; | |
struct settings *usettings = NULL; | |
@@ -1125,6 +1145,8 @@ static int uxc_set(char *name, char *pat | |
} | |
if (usettings->autostart >= 0 && autostart < 0) | |
autostart = !!(usettings->autostart); | |
+ if (usettings->no_resolv >= 0 && no_resolv < 0) | |
+ no_resolv = !!(usettings->no_resolv); | |
} | |
if (path) { | |
@@ -1204,6 +1226,9 @@ static int uxc_set(char *name, char *pat | |
blobmsg_close_array(&req, mntarr); | |
} | |
+ if (no_resolv >= 0) | |
+ blobmsg_add_u8(&req, "no-resolv", !!no_resolv); | |
+ | |
tmp = blobmsg_format_json_indent(req.head, true, 0); | |
if (tmp) { | |
dprintf(f, "%s\n", tmp); | |
@@ -1501,6 +1526,7 @@ int main(int argc, char **argv) | |
char *writepath = NULL; | |
char *requiredmounts = NULL; | |
signed char autostart = -1; | |
+ signed char no_resolv = -1; | |
bool force = false; | |
bool console = false; | |
int signal = SIGTERM; | |
@@ -1582,6 +1608,10 @@ int main(int argc, char **argv) | |
case 'm': | |
requiredmounts = optarg; | |
break; | |
+ | |
+ case 'n': | |
+ no_resolv = 1; | |
+ break; | |
} | |
} | |
@@ -1670,7 +1700,7 @@ int main(int argc, char **argv) | |
if (ret) | |
goto runtime_out; | |
- ret = uxc_set(argv[optind + 1], bundle, autostart, pidfile, tmprwsize, writepath, requiredmounts); | |
+ ret = uxc_set(argv[optind + 1], bundle, autostart, -1, pidfile, tmprwsize, writepath, requiredmounts); | |
if (ret < 0) | |
goto runtime_out; | |
else if (ret > 0) | |
@@ -1707,14 +1737,14 @@ int main(int argc, char **argv) | |
if (optind != argc - 2) | |
goto usage_out; | |
- ret = uxc_set(argv[optind + 1], NULL, 1, NULL, NULL, NULL, NULL); | |
+ ret = uxc_set(argv[optind + 1], NULL, 1, -1, NULL, NULL, NULL, NULL); | |
break; | |
case CMD_DISABLE: | |
if (optind != argc - 2) | |
goto usage_out; | |
- ret = uxc_set(argv[optind + 1], NULL, 0, NULL, NULL, NULL, NULL); | |
+ ret = uxc_set(argv[optind + 1], NULL, 0, -1, NULL, NULL, NULL, NULL); | |
break; | |
case CMD_DELETE: | |
@@ -1732,7 +1762,7 @@ int main(int argc, char **argv) | |
if (ret) | |
goto runtime_out; | |
- ret = uxc_set(argv[optind + 1], bundle, autostart, pidfile, tmprwsize, writepath, requiredmounts); | |
+ ret = uxc_set(argv[optind + 1], bundle, autostart, no_resolv, pidfile, tmprwsize, writepath, requiredmounts); | |
if (ret < 0) | |
goto runtime_out; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- a/jail/jail.c | |
+++ b/jail/jail.c | |
@@ -69,7 +69,7 @@ | |
#endif | |
#define STACK_SIZE (1024 * 1024) | |
-#define OPT_ARGS "cC:d:e:EfFG:h:ij:J:ln:NoO:pP:r:R:sS:uU:w:t:T:y" | |
+#define OPT_ARGS "cC:Dd:e:EfFG:h:ij:J:ln:NoO:pP:r:R:sS:uU:w:t:T:y" | |
#define OCI_VERSION_STRING "1.0.2" | |
@@ -154,6 +154,7 @@ static struct { | |
bool immediately; | |
struct blob_attr *annotations; | |
int term_timeout; | |
+ bool no_resolv; | |
} opts; | |
static struct blob_buf ocibuf; | |
@@ -285,7 +286,7 @@ static void free_opts(bool parent) { | |
free_hooklist(opts.hooks.poststop); | |
} | |
-static int mount_overlay(char *jail_root, char *overlaydir) { | |
+static int mount_overlay(char *jail_root, char *overlaydir, bool no_resolv) { | |
char *upperdir, *workdir, *optsstr, *upperetc, *upperresolvconf; | |
const char mountoptsformat[] = "lowerdir=%s,upperdir=%s,workdir=%s"; | |
int ret = -1, fd; | |
@@ -317,7 +318,7 @@ static int mount_overlay(char *jail_root | |
if (mkdir_p(upperetc, 0755)) | |
goto upper_etc_printf; | |
- if (asprintf(&upperresolvconf, "%s/resolv.conf", upperetc) < 0) | |
+ if (no_resolv || asprintf(&upperresolvconf, "%s/resolv.conf", upperetc) < 0) | |
goto upper_etc_printf; | |
fd = creat(upperresolvconf, 0644); | |
@@ -732,7 +733,7 @@ static int build_jail_fs(void) | |
overlaydir = opts.overlaydir; | |
if (overlaydir) { | |
- ret = mount_overlay(jail_root, overlaydir); | |
+ ret = mount_overlay(jail_root, overlaydir, opts.no_resolv); | |
if (ret) | |
return ret; | |
} | |
@@ -751,7 +752,7 @@ static int build_jail_fs(void) | |
create_dev_console(jail_root); | |
/* make sure /etc/resolv.conf exists if in new network namespace */ | |
- if (opts.namespace & CLONE_NEWNET) { | |
+ if (!opts.no_resolv && opts.namespace & CLONE_NEWNET) { | |
char jailetc[PATH_MAX], jaillink[PATH_MAX]; | |
snprintf(jailetc, PATH_MAX, "%s/etc", jail_root); | |
@@ -1020,7 +1021,7 @@ static void usage(void) | |
fprintf(stderr, " -u\t\tjail has a ubus socket\n"); | |
fprintf(stderr, " -U <name>\tuser to run jailed process\n"); | |
fprintf(stderr, " -G <name>\tgroup to run jailed process\n"); | |
- fprintf(stderr, " -o\t\tremont jail root (/) read only\n"); | |
+ fprintf(stderr, " -o\t\tremount jail root (/) read only\n"); | |
fprintf(stderr, " -R <dir>\texternal jail rootfs (system container)\n"); | |
fprintf(stderr, " -O <dir>\tdirectory for r/w overlayfs\n"); | |
fprintf(stderr, " -T <size>\tuse tmpfs r/w overlayfs with <size>\n"); | |
@@ -1029,6 +1030,7 @@ static void usage(void) | |
fprintf(stderr, " -J <dir>\tcreate container from OCI bundle\n"); | |
fprintf(stderr, " -i\t\tstart container immediately\n"); | |
fprintf(stderr, " -P <pidfile>\tcreate <pidfile>\n"); | |
+ fprintf(stderr, " -D\t\tignore resolv.conf setup\n"); | |
fprintf(stderr, "\nWarning: by default root inside the jail is the same\n\ | |
and he has the same powers as root outside the jail,\n\ | |
thus he can escape the jail and/or break stuff.\n\ | |
@@ -2612,6 +2614,8 @@ int main(int argc, char **argv) | |
/* default 5 seconds timeout after SIGTERM before SIGKILL is sent */ | |
opts.term_timeout = 5; | |
+ opts.no_resolv = false; | |
+ | |
umask(022); | |
mount_list_init(); | |
init_library_search(); | |
@@ -2730,6 +2734,9 @@ int main(int argc, char **argv) | |
case 'P': | |
opts.pidfile = optarg; | |
break; | |
+ case 'D': | |
+ opts.no_resolv = true; | |
+ break; | |
} | |
} | |
@@ -2944,7 +2951,7 @@ static void post_main(struct uloop_timeo | |
if (!opts.extroot) | |
add_mount_bind("/etc/nsswitch.conf", 1, -1); | |
#endif | |
- if (opts.setns.ns == -1) { | |
+ if (!opts.no_resolv && opts.setns.ns == -1) { | |
if (!(opts.namespace & CLONE_NEWNET)) { | |
add_mount_bind("/etc/resolv.conf", 1, 0); | |
} else { | |
--- a/service/instance.c | |
+++ b/service/instance.c | |
@@ -69,6 +69,7 @@ enum { | |
INSTANCE_ATTR_TMPOVERLAYSIZE, | |
INSTANCE_ATTR_BUNDLE, | |
INSTANCE_ATTR_WATCHDOG, | |
+ INSTANCE_ATTR_NO_RESOLV, | |
__INSTANCE_ATTR_MAX | |
}; | |
@@ -102,6 +103,7 @@ static const struct blobmsg_policy insta | |
[INSTANCE_ATTR_TMPOVERLAYSIZE] = { "tmpoverlaysize", BLOBMSG_TYPE_STRING }, | |
[INSTANCE_ATTR_BUNDLE] = { "bundle", BLOBMSG_TYPE_STRING }, | |
[INSTANCE_ATTR_WATCHDOG] = { "watchdog", BLOBMSG_TYPE_ARRAY }, | |
+ [INSTANCE_ATTR_NO_RESOLV] = { "no-resolv", BLOBMSG_TYPE_BOOL }, | |
}; | |
enum { | |
@@ -392,6 +394,9 @@ jail_run(struct service_instance *in, ch | |
if (in->require_jail) | |
argv[argc++] = "-E"; | |
+ if (in->no_resolv) | |
+ argv[argc++] = "-D"; | |
+ | |
blobmsg_list_for_each(&in->env, var) { | |
argv[argc++] = "-e"; | |
argv[argc++] = (char *) blobmsg_name(var->data); | |
@@ -1014,6 +1019,9 @@ instance_config_changed(struct service_i | |
if (in->no_new_privs != in_new->no_new_privs) | |
return true; | |
+ if (in->no_resolv != in_new->no_resolv) | |
+ return true; | |
+ | |
if (string_changed(in->jail.name, in_new->jail.name)) | |
return true; | |
@@ -1261,6 +1269,9 @@ instance_jail_parse(struct service_insta | |
if (in->no_new_privs) | |
jail->argc++; | |
+ if (in->no_resolv) | |
+ jail->argc++; | |
+ | |
if (in->bundle) | |
jail->argc += 2; | |
@@ -1369,6 +1380,9 @@ instance_config_parse(struct service_ins | |
if (tb[INSTANCE_ATTR_NO_NEW_PRIVS]) | |
in->no_new_privs = blobmsg_get_bool(tb[INSTANCE_ATTR_NO_NEW_PRIVS]); | |
+ if (tb[INSTANCE_ATTR_NO_RESOLV]) | |
+ in->no_resolv = blobmsg_get_bool(tb[INSTANCE_ATTR_NO_RESOLV]); | |
+ | |
if (!in->trace && tb[INSTANCE_ATTR_SECCOMP]) | |
in->seccomp = strdup(blobmsg_get_string(tb[INSTANCE_ATTR_SECCOMP])); | |
@@ -1534,6 +1548,7 @@ instance_config_move(struct service_inst | |
in->require_jail = in_src->require_jail; | |
in->no_new_privs = in_src->no_new_privs; | |
in->immediately = in_src->immediately; | |
+ in->no_resolv = in_src->no_resolv; | |
in->uid = in_src->uid; | |
in->pw_gid = in_src->pw_gid; | |
in->gr_gid = in_src->gr_gid; | |
@@ -1733,6 +1748,9 @@ void instance_dump(struct blob_buf *b, s | |
if (in->no_new_privs) | |
blobmsg_add_u8(b, "no_new_privs", true); | |
+ if (in->no_resolv) | |
+ blobmsg_add_u8(b, "no_resolv", true); | |
+ | |
if (in->seccomp) | |
blobmsg_add_string(b, "seccomp", in->seccomp); | |
--- a/service/instance.h | |
+++ b/service/instance.h | |
@@ -88,6 +88,7 @@ struct service_instance { | |
char *overlaydir; | |
char *tmpoverlaysize; | |
char *bundle; | |
+ bool no_resolv; | |
int syslog_facility; | |
int exit_code; | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
[ -n "$INCLUDE_ONLY" ] || { | |
. /lib/functions.sh | |
. ../netifd-proto.sh | |
init_proto "$@" | |
} | |
proto_infra_init_config() { | |
no_device=1 | |
available=1 | |
proto_config_add_string "device:device" | |
proto_config_add_string "namespace" | |
proto_config_add_string "ipaddr" | |
proto_config_add_string "netmask" | |
proto_config_add_string "gateway" | |
proto_config_add_string "script" | |
proto_config_add_string "args" | |
} | |
find_pid() { | |
local cfg="$1" | |
local token ns pid | |
for token in $(pidof catatonit); do | |
ns=$(cat /proc/$token/environ | tr '\0' '\n'|grep NAMESPACE|cut -d'=' -f2) | |
[ "$ns" = "$cfg" ] && | |
pid="$token" | |
done | |
echo $pid | |
} | |
proto_infra_setup() { | |
local cfg="$1" | |
local iface namespace ipaddr netmask mask gateway script args | |
local pid=$(find_pid "$cfg") | |
json_get_var iface "device" | |
json_get_vars namespace ipaddr netmask gateway script args | |
[ -z "$iface" ] && | |
iface="$cfg" | |
[ -z "$ipaddr" ] && { | |
echo "ip address not set for $cfg" | |
proto_notify_error "$cfg" "NO_IP_ADDRESS" | |
return 1 | |
} | |
[ -z "$namespace" ] && { | |
echo "namespace not set for $cfg" | |
proto_notify_error "$cfg" "NO_NAMESPACE_SET" | |
return 1 | |
} | |
mask="$netmask" | |
[ $(echo "$netmask" | cut -c1-1) = "/" ] || | |
mask=$(/bin/ipcalc.sh "$ipaddr" "$netmask" | grep PREFIX | cut -d'=' -f2) | |
[ -z "$mask" ] && { | |
echo "invalid netmask for $cfg" | |
proto_notify_error "$cfg" "INVAlID_NETMASK" | |
return 1 | |
} | |
[ -z "$pid" ] && { | |
proto_export NAMESPACE="$cfg" | |
proto_run_command "$cfg" "/usr/bin/unshare" -u -i -n -U -C "/usr/bin/catatonit" -P | |
pid=$(find_pid "$cfg") | |
} | |
[ -z "$pid" ] && { | |
echo "catatonit pid for namespace $cfg was not found, catatonit not running?" | |
proto_notify_error "$cfg" "PID_NOT_FOUND" | |
return 1 | |
} | |
proto_init_update "$iface" 1 | |
proto_add_ipv4_address $ipaddr $mask | |
proto_add_data | |
json_add_string "pid" "$pid" | |
json_add_string "namespace" "$namespace" | |
proto_close_data | |
proto_send_update "$cfg" | |
[ -z $(ip netns list | grep "$namespace") ] || | |
ip netns delete "$namespace" | |
ip netns attach "$namespace" "$pid" | |
ip link set "$iface" netns "$namespace" | |
ip -n "$namespace" addr add "${ipaddr}/${mask}" dev "$iface" | |
ip -n "$namespace" link set dev lo up | |
ip -n "$namespace" link set dev "$iface" up | |
[ -n "$gateway" ] && | |
ip -n "$namespace" route add default via "$gateway" | |
[ -n "$script" -a -x "$script" ] && { | |
interface="$iface" \ | |
pid="$pid" \ | |
ipaddr="$ipaddr" \ | |
netmask="$netmask" \ | |
mask="$mask" \ | |
gateway="$gateway" \ | |
namespace="$namespace" \ | |
$script "$cfg" $args | |
} || { | |
[ -n "$script" ] && | |
echo "post setup script $script for $cfg does not exist or is not executable" | |
} | |
} | |
proto_infra_teardown() { | |
local cfg="$1" | |
return 0 | |
} | |
[ -n "$INCLUDE_ONLY" ] || { | |
add_protocol infra | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment