aboutsummaryrefslogtreecommitdiffstats
path: root/executor/common_linux.h
diff options
context:
space:
mode:
Diffstat (limited to 'executor/common_linux.h')
-rw-r--r--executor/common_linux.h54
1 files changed, 54 insertions, 0 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h
index 36eff74ef..825472d1b 100644
--- a/executor/common_linux.h
+++ b/executor/common_linux.h
@@ -119,6 +119,12 @@
#include <sys/types.h>
#include <unistd.h>
#endif
+#if defined(SYZ_EXECUTOR) || defined(__NR_syz_genetlink_get_family_id)
+#include <linux/genetlink.h>
+#include <linux/netlink.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#endif
#if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) || \
defined(SYZ_USE_TMP_DIR) || defined(SYZ_HANDLE_SEGV) || defined(SYZ_TUN_ENABLE) || \
@@ -724,6 +730,54 @@ static uintptr_t syz_init_net_socket(uintptr_t domain, uintptr_t type, uintptr_t
#endif
#endif
+#if defined(SYZ_EXECUTOR) || defined(__NR_syz_genetlink_get_family_id)
+static uintptr_t syz_genetlink_get_family_id(uintptr_t name)
+{
+ char buf[512] = {0};
+ struct nlmsghdr* hdr = (struct nlmsghdr*)buf;
+ struct genlmsghdr* genlhdr = (struct genlmsghdr*)NLMSG_DATA(hdr);
+ struct nlattr* attr = (struct nlattr*)(genlhdr + 1);
+ hdr->nlmsg_len = sizeof(*hdr) + sizeof(*genlhdr) + sizeof(*attr) + GENL_NAMSIZ;
+ hdr->nlmsg_type = GENL_ID_CTRL;
+ hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
+ genlhdr->cmd = CTRL_CMD_GETFAMILY;
+ attr->nla_type = CTRL_ATTR_FAMILY_NAME;
+ attr->nla_len = sizeof(*attr) + GENL_NAMSIZ;
+ NONFAILING(strncpy((char*)(attr + 1), (char*)name, GENL_NAMSIZ));
+ struct iovec iov = {hdr, hdr->nlmsg_len};
+ struct sockaddr_nl addr = {0};
+ addr.nl_family = AF_NETLINK;
+ debug("syz_genetlink_get_family_id(%s)\n", (char*)(attr + 1));
+ int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
+ if (fd == -1) {
+ debug("syz_genetlink_get_family_id: socket failed: %d\n", errno);
+ return -1;
+ }
+ struct msghdr msg = {&addr, sizeof(addr), &iov, 1, NULL, 0, 0};
+ if (sendmsg(fd, &msg, 0) == -1) {
+ debug("syz_genetlink_get_family_id: sendmsg failed: %d\n", errno);
+ close(fd);
+ return -1;
+ }
+ ssize_t n = recv(fd, buf, sizeof(buf), 0);
+ close(fd);
+ if (n <= 0) {
+ debug("syz_genetlink_get_family_id: recv failed: %d\n", errno);
+ return -1;
+ }
+ if (hdr->nlmsg_type != GENL_ID_CTRL) {
+ debug("syz_genetlink_get_family_id: wrong reply type: %d\n", hdr->nlmsg_type);
+ return -1;
+ }
+ for (; (char*)attr < buf + n; attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
+ if (attr->nla_type == CTRL_ATTR_FAMILY_ID)
+ return *(uint16*)(attr + 1);
+ }
+ debug("syz_genetlink_get_family_id: no CTRL_ATTR_FAMILY_ID attr\n");
+ return -1;
+}
+#endif
+
#if defined(SYZ_EXECUTOR) || defined(__NR_syz_kvm_setup_cpu)
#if defined(__x86_64__)
#include "common_kvm_amd64.h"