X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fnspawn%2Fnspawn.c;h=98e90fe3c9207ab51dde3c3ece05bea4aca7a24e;hp=34e72db063faf4c65916167df36017070295cfba;hb=6afc95b73605833e6e966af1c466b5c08feb953f;hpb=ab046dde6f355f4a8b07ff6120a7ef51f5d49fc9 diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 34e72db06..98e90fe3c 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -43,6 +43,7 @@ #include #include #include +#include #ifdef HAVE_SELINUX #include @@ -79,6 +80,10 @@ #include "rtnl-util.h" #include "udev-util.h" +#ifdef HAVE_SECCOMP +#include "seccomp-util.h" +#endif + typedef enum LinkJournal { LINK_NO, LINK_AUTO, @@ -134,6 +139,7 @@ static bool arg_keep_unit = false; static char **arg_network_interfaces = NULL; static bool arg_network_veth = false; static char *arg_network_bridge = NULL; +static unsigned long arg_personality = 0xffffffffLU; static int help(void) { @@ -152,10 +158,10 @@ static int help(void) { " --network-interface=INTERFACE\n" " Assign an existing network interface to the\n" " container\n" - " --network-veth Add a a virtual ethernet connection between host\n" + " --network-veth Add a virtual ethernet connection between host\n" " and container\n" " --network-bridge=INTERFACE\n" - " Add a a virtual ethernet connection between host\n" + " Add a virtual ethernet connection between host\n" " and container and add it to an existing bridge on\n" " the host\n" " -Z --selinux-context=SECLABEL\n" @@ -202,6 +208,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_NETWORK_INTERFACE, ARG_NETWORK_VETH, ARG_NETWORK_BRIDGE, + ARG_PERSONALITY, }; static const struct option options[] = { @@ -230,6 +237,7 @@ static int parse_argv(int argc, char *argv[]) { { "network-interface", required_argument, NULL, ARG_NETWORK_INTERFACE }, { "network-veth", no_argument, NULL, ARG_NETWORK_VETH }, { "network-bridge", required_argument, NULL, ARG_NETWORK_BRIDGE }, + { "personality", required_argument, NULL, ARG_PERSONALITY }, {} }; @@ -470,6 +478,16 @@ static int parse_argv(int argc, char *argv[]) { arg_keep_unit = true; break; + case ARG_PERSONALITY: + + arg_personality = parse_personality(optarg); + if (arg_personality == 0xffffffffLU) { + log_error("Unknown or unsupported personality '%s'.", optarg); + return -EINVAL; + } + + break; + case '?': return -EINVAL; @@ -1303,7 +1321,7 @@ static int setup_veth(pid_t pid, char iface_name[]) { return r; } - r = sd_rtnl_message_new_link(RTM_NEWLINK, 0, &m); + r = sd_rtnl_message_new_link(rtnl, RTM_NEWLINK, 0, &m); if (r < 0) { log_error("Failed to allocate netlink message: %s", strerror(-r)); return r; @@ -1404,7 +1422,7 @@ static int setup_bridge(const char veth_name[]) { return r; } - r = sd_rtnl_message_new_link(RTM_SETLINK, 0, &m); + r = sd_rtnl_message_new_link(rtnl, RTM_SETLINK, 0, &m); if (r < 0) { log_error("Failed to allocate netlink message: %s", strerror(-r)); return r; @@ -1479,7 +1497,7 @@ static int move_network_interfaces(pid_t pid) { return -EBUSY; } - r = sd_rtnl_message_new_link(RTM_NEWLINK, ifi, &m); + r = sd_rtnl_message_new_link(rtnl, RTM_NEWLINK, ifi, &m); if (r < 0) { log_error("Failed to allocate netlink message: %s", strerror(-r)); return r; @@ -1521,7 +1539,13 @@ static int audit_still_doesnt_work_in_containers(void) { if (!seccomp) return log_oom(); - r = seccomp_rule_add_exact( + r = seccomp_add_secondary_archs(seccomp); + if (r < 0 && r != -EEXIST) { + log_error("Failed to add secondary archs to seccomp filter: %s", strerror(-r)); + goto finish; + } + + r = seccomp_rule_add( seccomp, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), @@ -1554,7 +1578,7 @@ finish: int main(int argc, char *argv[]) { - _cleanup_close_ int master = -1, kdbus_fd = -1, sync_fd = -1, netns_fd = -1; + _cleanup_close_ int master = -1, kdbus_fd = -1, sync_fd = -1; _cleanup_close_pipe_ int kmsg_socket_pair[2] = { -1, -1 }; _cleanup_free_ char *kdbus_domain = NULL; _cleanup_fdset_free_ FDSet *fds = NULL; @@ -1973,6 +1997,13 @@ int main(int argc, char *argv[]) { setup_hostname(); + if (arg_personality != 0xffffffffLU) { + if (personality(arg_personality) < 0) { + log_error("personality() failed: %m"); + goto child_fail; + } + } + eventfd_read(sync_fd, &x); close_nointr_nofail(sync_fd); sync_fd = -1;