From d40d75d2d787b9d4f949422b88de18ede4ee20b6 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Thu, 24 Oct 2019 10:16:19 +0200 Subject: executor: move fixed pci devlink handle into network namespace In case there is a fixed pci devlink handle "pci/pci/0000:00:10.0" on the system (initial network namespace), it is moved to a working network namespace. Signed-off-by: Jiri Pirko --- pkg/csource/generated.go | 107 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 102 insertions(+), 5 deletions(-) (limited to 'pkg/csource/generated.go') diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go index bcfc0a01f..2266f86d6 100644 --- a/pkg/csource/generated.go +++ b/pkg/csource/generated.go @@ -1130,7 +1130,7 @@ static bool write_file(const char* file, const char* what, ...) } #endif -#if SYZ_EXECUTOR || SYZ_ENABLE_NETDEV || SYZ_TUN_ENABLE +#if SYZ_EXECUTOR || SYZ_ENABLE_NETDEV || SYZ_TUN_ENABLE || SYZ_ENABLE_DEVLINK_PCI #include #include #include @@ -1189,7 +1189,7 @@ static void netlink_done(void) } #endif -static int netlink_send(int sock) +static int netlink_send_ext(int sock, uint16 reply_type, int* reply_len) { if (nlmsg.pos > nlmsg.buf + sizeof(nlmsg.buf) || nlmsg.nesting) fail("nlmsg overflow/bad nesting"); @@ -1202,6 +1202,12 @@ static int netlink_send(int sock) if (n != hdr->nlmsg_len) fail("short netlink write: %d/%d", n, hdr->nlmsg_len); n = recv(sock, nlmsg.buf, sizeof(nlmsg.buf), 0); + if (n < sizeof(struct nlmsghdr)) + fail("short netlink read: %d", n); + if (reply_len && hdr->nlmsg_type == reply_type) { + *reply_len = n; + return 0; + } if (n < sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr)) fail("short netlink read: %d", n); if (hdr->nlmsg_type != NLMSG_ERROR) @@ -1209,6 +1215,11 @@ static int netlink_send(int sock) return -((struct nlmsgerr*)(hdr + 1))->error; } +static int netlink_send(int sock) +{ + return netlink_send_ext(sock, 0, NULL); +} + #if SYZ_EXECUTOR || SYZ_ENABLE_NETDEV static void netlink_add_device_impl(const char* type, const char* name) { @@ -1262,6 +1273,7 @@ static void netlink_add_hsr(int sock, const char* name, const char* slave1, cons } #endif +#if SYZ_EXECUTOR || SYZ_ENABLE_NETDEV || SYZ_TUN_ENABLE static void netlink_device_change(int sock, const char* name, bool up, const char* master, const void* mac, int macsize) { @@ -1313,6 +1325,7 @@ static void netlink_add_addr6(int sock, const char* dev, const char* addr) debug("netlink: add addr %s dev %s: %s\n", addr, dev, strerror(err)); (void)err; } +#endif #if SYZ_EXECUTOR || SYZ_TUN_ENABLE static void netlink_add_neigh(int sock, const char* name, @@ -1432,6 +1445,83 @@ static void initialize_tun(void) } #endif +#if SYZ_EXECUTOR || __NR_syz_init_net_socket || SYZ_ENABLE_DEVLINK_PCI +const int kInitNetNsFd = 239; +#endif + +#if SYZ_EXECUTOR || SYZ_ENABLE_DEVLINK_PCI + +#include + +#define DEVLINK_FAMILY_NAME "devlink" + +#define DEVLINK_CMD_RELOAD 37 +#define DEVLINK_ATTR_BUS_NAME 1 +#define DEVLINK_ATTR_DEV_NAME 2 +#define DEVLINK_ATTR_NETNS_FD 137 + +static void netlink_devlink_netns_move(const char* bus_name, const char* dev_name, int netns_fd) +{ + struct genlmsghdr genlhdr; + struct nlattr* attr; + int sock, err, n; + uint16 id = 0; + + sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); + if (sock == -1) + fail("socket(AF_NETLINK) failed\n"); + memset(&genlhdr, 0, sizeof(genlhdr)); + genlhdr.cmd = CTRL_CMD_GETFAMILY; + netlink_init(GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr)); + netlink_attr(CTRL_ATTR_FAMILY_NAME, DEVLINK_FAMILY_NAME, strlen(DEVLINK_FAMILY_NAME) + 1); + err = netlink_send_ext(sock, GENL_ID_CTRL, &n); + if (err) { + debug("netlink: failed to get devlink family id: %s\n", strerror(err)); + goto error; + } + attr = (struct nlattr*)(nlmsg.buf + NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(genlhdr))); + for (; (char*)attr < nlmsg.buf + n; attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) { + if (attr->nla_type == CTRL_ATTR_FAMILY_ID) { + id = *(uint16*)(attr + 1); + break; + } + } + if (!id) { + debug("netlink: failed to parse message for devlink family id\n"); + goto error; + } + recv(sock, nlmsg.buf, sizeof(nlmsg.buf), 0); /* recv ack */ + memset(&genlhdr, 0, sizeof(genlhdr)); + genlhdr.cmd = DEVLINK_CMD_RELOAD; + netlink_init(id, 0, &genlhdr, sizeof(genlhdr)); + netlink_attr(DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1); + netlink_attr(DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1); + netlink_attr(DEVLINK_ATTR_NETNS_FD, &netns_fd, sizeof(netns_fd)); + netlink_send(sock); +error: + close(sock); +} + +static void initialize_devlink_pci(void) +{ +#if SYZ_EXECUTOR + if (!flag_enable_devlink_pci) + return; +#endif + int netns = open("/proc/self/ns/net", O_RDONLY); + if (netns == -1) + fail("open(/proc/self/ns/net) failed"); + int ret = setns(kInitNetNsFd, 0); + if (ret == -1) + fail("set_ns(init_netns_fd) failed"); + netlink_devlink_netns_move("pci", "0000:00:10.0", netns); + ret = setns(netns, 0); + if (ret == -1) + fail("set_ns(this_netns_fd) failed"); + close(netns); +} +#endif + #if SYZ_EXECUTOR || SYZ_ENABLE_NETDEV #include #include @@ -2671,8 +2761,6 @@ static long syz_open_pts(volatile long a0, volatile long a1) #include #include #include - -const int kInitNetNsFd = 239; static long syz_init_net_socket(volatile long domain, volatile long type, volatile long proto) { int netns = open("/proc/self/ns/net", O_RDONLY); @@ -4571,7 +4659,7 @@ static void sandbox_common() setpgrp(); setsid(); -#if SYZ_EXECUTOR || __NR_syz_init_net_socket +#if SYZ_EXECUTOR || __NR_syz_init_net_socket || SYZ_ENABLE_DEVLINK_PCI int netns = open("/proc/self/ns/net", O_RDONLY); if (netns == -1) fail("open(/proc/self/ns/net) failed"); @@ -4685,6 +4773,9 @@ static int do_sandbox_none(void) if (unshare(CLONE_NEWNET)) { debug("unshare(CLONE_NEWNET): %d\n", errno); } +#if SYZ_EXECUTOR || SYZ_ENABLE_DEVLINK_PCI + initialize_devlink_pci(); +#endif #if SYZ_EXECUTOR || SYZ_TUN_ENABLE initialize_tun(); #endif @@ -4719,6 +4810,9 @@ static int do_sandbox_setuid(void) if (unshare(CLONE_NEWNET)) { debug("unshare(CLONE_NEWNET): %d\n", errno); } +#if SYZ_EXECUTOR || SYZ_ENABLE_DEVLINK_PCI + initialize_devlink_pci(); +#endif #if SYZ_EXECUTOR || SYZ_TUN_ENABLE initialize_tun(); #endif @@ -4763,6 +4857,9 @@ static int namespace_sandbox_proc(void* arg) #endif if (unshare(CLONE_NEWNET)) fail("unshare(CLONE_NEWNET)"); +#if SYZ_EXECUTOR || SYZ_ENABLE_DEVLINK_PCI + initialize_devlink_pci(); +#endif #if SYZ_EXECUTOR || SYZ_TUN_ENABLE initialize_tun(); #endif -- cgit mrf-deployment