aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Pirko <jiri@mellanox.com>2019-10-24 10:16:19 +0200
committerDmitry Vyukov <dvyukov@google.com>2019-11-03 14:20:59 +0100
commitd40d75d2d787b9d4f949422b88de18ede4ee20b6 (patch)
tree18713cd0e1884616ceee1c74381eba65419aff9f
parent97f4b019d87a073ff02a3ff8b08ada59aea6e688 (diff)
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 <jiri@mellanox.com>
-rw-r--r--executor/common_linux.h106
-rw-r--r--executor/executor.cc2
-rw-r--r--pkg/csource/common.go1
-rw-r--r--pkg/csource/generated.go107
-rw-r--r--pkg/csource/options.go12
-rw-r--r--pkg/csource/options_test.go18
-rw-r--r--pkg/host/host.go2
-rw-r--r--pkg/host/host_linux.go8
-rw-r--r--pkg/ipc/ipc.go1
-rw-r--r--pkg/runtest/run.go3
-rw-r--r--sys/linux/socket_netlink_generic_devlink.txt1
-rw-r--r--syz-fuzzer/fuzzer.go3
-rw-r--r--tools/syz-execprog/execprog.go3
-rw-r--r--tools/syz-prog2c/prog2c.go1
-rw-r--r--tools/syz-reprolist/reprolist.go4
-rw-r--r--tools/syz-stress/stress.go3
16 files changed, 257 insertions, 18 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h
index 1c0f51b5e..0b7e15a63 100644
--- a/executor/common_linux.h
+++ b/executor/common_linux.h
@@ -106,7 +106,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 <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
@@ -165,7 +165,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");
@@ -178,6 +178,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)
@@ -185,6 +191,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)
{
@@ -238,6 +249,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)
{
@@ -289,6 +301,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,
@@ -422,6 +435,83 @@ static void initialize_tun(void)
}
#endif
+#if SYZ_EXECUTOR || __NR_syz_init_net_socket || SYZ_ENABLE_DEVLINK_PCI
+const int kInitNetNsFd = 239; // see kMaxFd
+#endif
+
+#if SYZ_EXECUTOR || SYZ_ENABLE_DEVLINK_PCI
+
+#include <linux/genetlink.h>
+
+#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 <arpa/inet.h>
#include <errno.h>
@@ -909,7 +999,6 @@ static long syz_open_pts(volatile long a0, volatile long a1)
#include <sys/types.h>
#include <unistd.h>
-const int kInitNetNsFd = 239; // see kMaxFd
// syz_init_net_socket opens a socket in init net namespace.
// Used for families that can only be created in init net namespace.
static long syz_init_net_socket(volatile long domain, volatile long type, volatile long proto)
@@ -1911,7 +2000,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");
@@ -2049,6 +2138,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
@@ -2083,6 +2175,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
@@ -2135,6 +2230,9 @@ static int namespace_sandbox_proc(void* arg)
// because we want the tun device in the test namespace.
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
// We setup tun here as it needs to be in the test net namespace,
// which in turn needs to be in the test user namespace.
diff --git a/executor/executor.cc b/executor/executor.cc
index 30d497ea9..2016a8bf5 100644
--- a/executor/executor.cc
+++ b/executor/executor.cc
@@ -118,6 +118,7 @@ static bool flag_enable_net_dev;
static bool flag_enable_net_reset;
static bool flag_enable_cgroups;
static bool flag_enable_close_fds;
+static bool flag_enable_devlink_pci;
static bool flag_collect_cover;
static bool flag_dedup_cover;
@@ -481,6 +482,7 @@ void parse_env_flags(uint64 flags)
flag_enable_net_reset = flags & (1 << 8);
flag_enable_cgroups = flags & (1 << 9);
flag_enable_close_fds = flags & (1 << 10);
+ flag_enable_devlink_pci = flags & (1 << 11);
}
#if SYZ_EXECUTOR_USES_FORK_SERVER
diff --git a/pkg/csource/common.go b/pkg/csource/common.go
index e537ed724..67d31ad81 100644
--- a/pkg/csource/common.go
+++ b/pkg/csource/common.go
@@ -95,6 +95,7 @@ func defineList(p, mmapProg *prog.Prog, opts Options) (defines []string) {
"SYZ_ENABLE_BINFMT_MISC": opts.EnableBinfmtMisc,
"SYZ_ENABLE_CLOSE_FDS": opts.EnableCloseFds,
"SYZ_ENABLE_KCSAN": opts.EnableKCSAN,
+ "SYZ_ENABLE_DEVLINK_PCI": opts.EnableDevlinkPCI,
"SYZ_USE_TMP_DIR": opts.UseTmpDir,
"SYZ_HANDLE_SEGV": opts.HandleSegv,
"SYZ_REPRO": opts.Repro,
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 <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
@@ -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 <linux/genetlink.h>
+
+#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 <arpa/inet.h>
#include <errno.h>
@@ -2671,8 +2761,6 @@ static long syz_open_pts(volatile long a0, volatile long a1)
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
-
-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
diff --git a/pkg/csource/options.go b/pkg/csource/options.go
index 7ad8c1d9c..a4cc45d45 100644
--- a/pkg/csource/options.go
+++ b/pkg/csource/options.go
@@ -38,6 +38,7 @@ type Options struct {
EnableBinfmtMisc bool `json:"binfmt_misc,omitempty"`
EnableCloseFds bool `json:"close_fds"`
EnableKCSAN bool `json:"kcsan,omitempty"`
+ EnableDevlinkPCI bool `json:"devlinkpci,omitempty"`
UseTmpDir bool `json:"tmpdir,omitempty"`
HandleSegv bool `json:"segv,omitempty"`
@@ -127,6 +128,9 @@ func (opts Options) checkLinuxOnly(OS string) error {
if opts.EnableKCSAN {
return fmt.Errorf("option EnableKCSAN is not supported on %v", OS)
}
+ if opts.EnableDevlinkPCI {
+ return fmt.Errorf("option EnableDevlinkPCI is not supported on %v", OS)
+ }
if opts.Sandbox == sandboxNamespace ||
(opts.Sandbox == sandboxSetuid && !(OS == openbsd || OS == freebsd || OS == netbsd)) ||
opts.Sandbox == sandboxAndroidUntrustedApp {
@@ -154,6 +158,7 @@ func DefaultOpts(cfg *mgrconfig.Config) Options {
EnableCgroups: true,
EnableBinfmtMisc: true,
EnableCloseFds: true,
+ EnableDevlinkPCI: true,
UseTmpDir: true,
HandleSegv: true,
Repro: true,
@@ -165,6 +170,12 @@ func DefaultOpts(cfg *mgrconfig.Config) Options {
opts.EnableCgroups = false
opts.EnableBinfmtMisc = false
opts.EnableCloseFds = false
+ opts.EnableDevlinkPCI = false
+ }
+ if cfg.Sandbox == "" || cfg.Sandbox == "setuid" {
+ opts.EnableNetReset = false
+ }
+ if err := opts.Check(cfg.TargetOS); err != nil {
}
if cfg.Sandbox == "" || cfg.Sandbox == "setuid" {
opts.EnableNetReset = false
@@ -244,6 +255,7 @@ func defaultFeatures(value bool) Features {
"cgroups": {"setup cgroups for testing", value},
"binfmt_misc": {"setup binfmt_misc for testing", value},
"close_fds": {"close fds after each program", value},
+ "devlink_pci": {"setup devlink PCI device", value},
}
}
diff --git a/pkg/csource/options_test.go b/pkg/csource/options_test.go
index 13afa84d3..34c64f9e2 100644
--- a/pkg/csource/options_test.go
+++ b/pkg/csource/options_test.go
@@ -213,31 +213,31 @@ func TestParseFeaturesFlags(t *testing.T) {
Features map[string]bool
}{
{"none", "none", true, map[string]bool{
- "tun": true, "net_dev": true, "net_reset": true, "cgroups": true, "binfmt_misc": true, "close_fds": true,
+ "tun": true, "net_dev": true, "net_reset": true, "cgroups": true, "binfmt_misc": true, "close_fds": true, "devlink_pci": true,
}},
{"none", "none", false, map[string]bool{
- "tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": false,
+ "tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": false, "devlink_pci": false,
}},
{"all", "none", true, map[string]bool{
- "tun": true, "net_dev": true, "net_reset": true, "cgroups": true, "binfmt_misc": true, "close_fds": true,
+ "tun": true, "net_dev": true, "net_reset": true, "cgroups": true, "binfmt_misc": true, "close_fds": true, "devlink_pci": true,
}},
{"", "none", true, map[string]bool{
- "tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": false,
+ "tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": false, "devlink_pci": false,
}},
{"none", "all", true, map[string]bool{
- "tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": false,
+ "tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": false, "devlink_pci": false,
}},
{"none", "", true, map[string]bool{
- "tun": true, "net_dev": true, "net_reset": true, "cgroups": true, "binfmt_misc": true, "close_fds": true,
+ "tun": true, "net_dev": true, "net_reset": true, "cgroups": true, "binfmt_misc": true, "close_fds": true, "devlink_pci": true,
}},
{"tun,net_dev", "none", true, map[string]bool{
- "tun": true, "net_dev": true, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": false,
+ "tun": true, "net_dev": true, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": false, "devlink_pci": false,
}},
{"none", "cgroups,net_dev", true, map[string]bool{
- "tun": true, "net_dev": false, "net_reset": true, "cgroups": false, "binfmt_misc": true, "close_fds": true,
+ "tun": true, "net_dev": false, "net_reset": true, "cgroups": false, "binfmt_misc": true, "close_fds": true, "devlink_pci": true,
}},
{"close_fds", "none", true, map[string]bool{
- "tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": true,
+ "tun": false, "net_dev": false, "net_reset": false, "cgroups": false, "binfmt_misc": false, "close_fds": true, "devlink_pci": false,
}},
}
for i, test := range tests {
diff --git a/pkg/host/host.go b/pkg/host/host.go
index dbd3b9ec3..f18233085 100644
--- a/pkg/host/host.go
+++ b/pkg/host/host.go
@@ -76,6 +76,7 @@ const (
FeatureNetworkInjection
FeatureNetworkDevices
FeatureKCSAN
+ FeatureDevlinkPCI
numFeatures
)
@@ -108,6 +109,7 @@ func Check(target *prog.Target) (*Features, error) {
FeatureNetworkInjection: {Name: "net packet injection", Reason: unsupported},
FeatureNetworkDevices: {Name: "net device setup", Reason: unsupported},
FeatureKCSAN: {Name: "concurrency sanitizer", Reason: unsupported},
+ FeatureDevlinkPCI: {Name: "devlink PCI setup", Reason: unsupported},
}
switch target.OS {
case "akaros", "fuchsia", "test":
diff --git a/pkg/host/host_linux.go b/pkg/host/host_linux.go
index a1d5ff1b3..c908ee411 100644
--- a/pkg/host/host_linux.go
+++ b/pkg/host/host_linux.go
@@ -396,6 +396,7 @@ func init() {
checkFeature[FeatureNetworkInjection] = checkNetworkInjection
checkFeature[FeatureNetworkDevices] = unconditionallyEnabled
checkFeature[FeatureKCSAN] = checkKCSAN
+ checkFeature[FeatureDevlinkPCI] = checkDevlinkPCI
}
func checkCoverage() string {
@@ -564,3 +565,10 @@ func checkKCSAN() string {
}
return ""
}
+
+func checkDevlinkPCI() string {
+ if err := osutil.IsAccessible("/sys/bus/pci/devices/0000:00:10.0/"); err != nil {
+ return "PCI device 0000:00:10.0 is not available"
+ }
+ return ""
+}
diff --git a/pkg/ipc/ipc.go b/pkg/ipc/ipc.go
index aea594fba..34b4ce2d0 100644
--- a/pkg/ipc/ipc.go
+++ b/pkg/ipc/ipc.go
@@ -37,6 +37,7 @@ const (
FlagEnableNetReset // reset network namespace between programs
FlagEnableCgroups // setup cgroups for testing
FlagEnableCloseFds // close fds after each program
+ FlagEnableDevlinkPCI // setup devlink PCI device
// Executor does not know about these:
FlagUseShmem // use shared memory instead of pipes for communication
FlagUseForkServer // use extended protocol with handshake
diff --git a/pkg/runtest/run.go b/pkg/runtest/run.go
index 0248b0b31..633e67455 100644
--- a/pkg/runtest/run.go
+++ b/pkg/runtest/run.go
@@ -381,6 +381,9 @@ func (ctx *Context) createSyzTest(p *prog.Prog, sandbox string, threaded, cov bo
}
cfg.Flags |= ipc.FlagEnableNetReset
cfg.Flags |= ipc.FlagEnableCgroups
+ if ctx.Features[host.FeatureDevlinkPCI].Enabled {
+ cfg.Flags |= ipc.FlagEnableDevlinkPCI
+ }
req := &RunRequest{
P: p,
Cfg: cfg,
diff --git a/sys/linux/socket_netlink_generic_devlink.txt b/sys/linux/socket_netlink_generic_devlink.txt
index f090e4104..7a89fc648 100644
--- a/sys/linux/socket_netlink_generic_devlink.txt
+++ b/sys/linux/socket_netlink_generic_devlink.txt
@@ -25,6 +25,7 @@ devlink_handle_nsim {
devlink_handle_pci {
DEVLINK_ATTR_BUS_NAME nlattr[DEVLINK_ATTR_BUS_NAME, string["pci"]]
+# 0000:00:10.0 is a fixed pci address what is moved from initial network namespace by initialize_devlink()
DEVLINK_ATTR_DEV_NAME nlattr[DEVLINK_ATTR_DEV_NAME, string["0000:00:10.0"]]
} [packed, align_4]
diff --git a/syz-fuzzer/fuzzer.go b/syz-fuzzer/fuzzer.go
index 41da54d1c..5cc7df893 100644
--- a/syz-fuzzer/fuzzer.go
+++ b/syz-fuzzer/fuzzer.go
@@ -214,6 +214,9 @@ func main() {
config.Flags |= ipc.FlagEnableNetReset
config.Flags |= ipc.FlagEnableCgroups
config.Flags |= ipc.FlagEnableCloseFds
+ if r.CheckResult.Features[host.FeatureDevlinkPCI].Enabled {
+ config.Flags |= ipc.FlagEnableDevlinkPCI
+ }
if *flagRunTest {
runTest(target, manager, *flagName, config.Executor)
diff --git a/tools/syz-execprog/execprog.go b/tools/syz-execprog/execprog.go
index 32ba987ae..909715b7c 100644
--- a/tools/syz-execprog/execprog.go
+++ b/tools/syz-execprog/execprog.go
@@ -326,5 +326,8 @@ func createConfig(target *prog.Target,
if featuresFlags["close_fds"].Enabled {
config.Flags |= ipc.FlagEnableCloseFds
}
+ if featuresFlags["devlink_pci"].Enabled && features[host.FeatureDevlinkPCI].Enabled {
+ config.Flags |= ipc.FlagEnableDevlinkPCI
+ }
return config, execOpts
}
diff --git a/tools/syz-prog2c/prog2c.go b/tools/syz-prog2c/prog2c.go
index de704b353..c1a3f50ef 100644
--- a/tools/syz-prog2c/prog2c.go
+++ b/tools/syz-prog2c/prog2c.go
@@ -88,6 +88,7 @@ func main() {
EnableBinfmtMisc: features["binfmt_misc"].Enabled,
EnableCloseFds: features["close_fds"].Enabled,
EnableKCSAN: features["kcsan"].Enabled,
+ EnableDevlinkPCI: features["devlink_pci"].Enabled,
UseTmpDir: *flagUseTmpDir,
HandleSegv: *flagHandleSegv,
Repro: false,
diff --git a/tools/syz-reprolist/reprolist.go b/tools/syz-reprolist/reprolist.go
index 85e328fac..5d082b37e 100644
--- a/tools/syz-reprolist/reprolist.go
+++ b/tools/syz-reprolist/reprolist.go
@@ -215,6 +215,10 @@ func createProg2CArgs(bug *dashapi.LoadBugResp, opts csource.Options, file strin
if opts.EnableCloseFds && haveCloseFds {
enable = append(enable, "close_fds")
}
+ if opts.EnableDevlinkPCI {
+ enable = append(enable, "devlink_pci")
+ flags = append(flags, "-devlinkpci")
+ }
if !haveEnableFlag {
args = append(args, flags...)
} else if len(enable) != 0 {
diff --git a/tools/syz-stress/stress.go b/tools/syz-stress/stress.go
index af78906ab..9323013c0 100644
--- a/tools/syz-stress/stress.go
+++ b/tools/syz-stress/stress.go
@@ -98,6 +98,9 @@ func main() {
if featuresFlags["close_fds"].Enabled {
config.Flags |= ipc.FlagEnableCloseFds
}
+ if featuresFlags["devlink_pci"].Enabled && features[host.FeatureDevlinkPCI].Enabled {
+ config.Flags |= ipc.FlagEnableDevlinkPCI
+ }
if err = host.Setup(target, features, featuresFlags, config.Executor); err != nil {
log.Fatal(err)
}