map[SimplifiedCRepro:// autogenerated by syzkaller (https://github.com/google/syzkaller)
#define _GNU_SOURCE
#include <arpa/inet.h>
#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mount.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <linux/genetlink.h>
#include <linux/if_addr.h>
#include <linux/if_link.h>
#include <linux/in6.h>
#include <linux/neighbour.h>
#include <linux/net.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/veth.h>
static bool write_file(const char* file, const char* what, ...)
{
char buf[1024];
va_list args;
va_start(args, what);
vsnprintf(buf, sizeof(buf), what, args);
va_end(args);
buf[sizeof(buf) - 1] = 0;
int len = strlen(buf);
int fd = open(file, O_WRONLY | O_CLOEXEC);
if (fd == -1)
return false;
if (write(fd, buf, len) != len) {
int err = errno;
close(fd);
errno = err;
return false;
}
close(fd);
return true;
}
struct nlmsg {
char* pos;
int nesting;
struct nlattr* nested[8];
char buf[4096];
};
static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
const void* data, int size)
{
memset(nlmsg, 0, sizeof(*nlmsg));
struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
hdr->nlmsg_type = typ;
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
memcpy(hdr + 1, data, size);
nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
}
static void netlink_attr(struct nlmsg* nlmsg, int typ,
const void* data, int size)
{
struct nlattr* attr = (struct nlattr*)nlmsg->pos;
attr->nla_len = sizeof(*attr) + size;
attr->nla_type = typ;
if (size > 0)
memcpy(attr + 1, data, size);
nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
}
static int netlink_send_ext(struct nlmsg* nlmsg, int sock,
uint16_t reply_type, int* reply_len, bool dofail)
{
if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
exit(1);
struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
struct sockaddr_nl addr;
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
ssize_t n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr));
if (n != (ssize_t)hdr->nlmsg_len) {
if (dofail)
exit(1);
return -1;
}
n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
if (reply_len)
*reply_len = 0;
if (n < 0) {
if (dofail)
exit(1);
return -1;
}
if (n < (ssize_t)sizeof(struct nlmsghdr)) {
errno = EINVAL;
if (dofail)
exit(1);
return -1;
}
if (hdr->nlmsg_type == NLMSG_DONE)
return 0;
if (reply_len && hdr->nlmsg_type == reply_type) {
*reply_len = n;
return 0;
}
if (n < (ssize_t)(sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))) {
errno = EINVAL;
if (dofail)
exit(1);
return -1;
}
if (hdr->nlmsg_type != NLMSG_ERROR) {
errno = EINVAL;
if (dofail)
exit(1);
return -1;
}
errno = -((struct nlmsgerr*)(hdr + 1))->error;
return -errno;
}
static int netlink_query_family_id(struct nlmsg* nlmsg, int sock, const char* family_name, bool dofail)
{
struct genlmsghdr genlhdr;
memset(&genlhdr, 0, sizeof(genlhdr));
genlhdr.cmd = CTRL_CMD_GETFAMILY;
netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, family_name, strnlen(family_name, GENL_NAMSIZ - 1) + 1);
int n = 0;
int err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n, dofail);
if (err < 0) {
return -1;
}
uint16_t id = 0;
struct nlattr* 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_t*)(attr + 1);
break;
}
}
if (!id) {
errno = EINVAL;
return -1;
}
recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
return id;
}
const int kInitNetNsFd = 201;
static long syz_init_net_socket(volatile long domain, volatile long type, volatile long proto)
{
return syscall(__NR_socket, domain, type, proto);
}
static long syz_genetlink_get_family_id(volatile long name, volatile long sock_arg)
{
int fd = sock_arg;
if (fd < 0) {
fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
if (fd == -1) {
return -1;
}
}
struct nlmsg nlmsg_tmp;
int ret = netlink_query_family_id(&nlmsg_tmp, fd, (char*)name, false);
if ((int)sock_arg < 0)
close(fd);
if (ret < 0) {
return -1;
}
return ret;
}
static int inject_fault(int nth)
{
int fd;
fd = open("/proc/thread-self/fail-nth", O_RDWR);
if (fd == -1)
exit(1);
char buf[16];
sprintf(buf, "%d", nth);
if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf))
exit(1);
return fd;
}
static const char* setup_fault()
{
int fd = open("/proc/self/make-it-fail", O_WRONLY);
if (fd == -1)
return "CONFIG_FAULT_INJECTION is not enabled";
close(fd);
fd = open("/proc/thread-self/fail-nth", O_WRONLY);
if (fd == -1)
return "kernel does not have systematic fault injection support";
close(fd);
static struct {
const char* file;
const char* val;
bool fatal;
} files[] = {
{"/sys/kernel/debug/failslab/ignore-gfp-wait", "N", true},
{"/sys/kernel/debug/fail_futex/ignore-private", "N", false},
{"/sys/kernel/debug/fail_page_alloc/ignore-gfp-highmem", "N", false},
{"/sys/kernel/debug/fail_page_alloc/ignore-gfp-wait", "N", false},
{"/sys/kernel/debug/fail_page_alloc/min-order", "0", false},
};
unsigned i;
for (i = 0; i < sizeof(files) / sizeof(files[0]); i++) {
if (!write_file(files[i].file, files[i].val)) {
if (files[i].fatal)
return "failed to write fault injection file";
}
}
return NULL;
}
uint64_t r[7] = {0xffffffffffffffff, 0xffffffffffffffff, 0x0, 0xffffffffffffffff, 0x0, 0x0, 0x0};
int main(void)
{
syscall(__NR_mmap, /*addr=*/0x1ffffffff000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
syscall(__NR_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul, /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/7ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
syscall(__NR_mmap, /*addr=*/0x200001000000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
const char* reason;
(void)reason;
if ((reason = setup_fault()))
printf("the reproducer may not work as expected: fault injection setup failed: %s\n", reason);
intptr_t res = 0;
if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {}
// syz_init_net_socket$nl_generic arguments: [
// domain: const = 0x10 (8 bytes)
// type: const = 0x3 (8 bytes)
// proto: const = 0x10 (8 bytes)
// ]
// returns sock_nl_generic_init
res = -1;
res = syz_init_net_socket(/*domain=*/0x10, /*type=*/3, /*proto=*/0x10);
if (res != -1)
r[0] = res;
// syz_init_net_socket$nl_generic arguments: [
// domain: const = 0x10 (8 bytes)
// type: const = 0x3 (8 bytes)
// proto: const = 0x10 (8 bytes)
// ]
// returns sock_nl_generic_init
res = -1;
res = syz_init_net_socket(/*domain=*/0x10, /*type=*/3, /*proto=*/0x10);
if (res != -1)
r[1] = res;
// syz_genetlink_get_family_id$ieee802154 arguments: [
// name: ptr[in, buffer] {
// buffer: {38 30 32 2e 31 35 2e 34 20 4d 41 43 00} (length 0xd)
// }
// fd: sock_nl_generic_init (resource)
// ]
// returns genl_ieee802154_family_id
memcpy((void*)0x200000000400, "802.15.4 MAC\000", 13);
res = -1;
res = syz_genetlink_get_family_id(/*name=*/0x200000000400, /*fd=*/r[1]);
if (res != -1)
r[2] = res;
// sendmsg$IEEE802154_ADD_IFACE arguments: [
// fd: sock_nl_generic_init (resource)
// msg: ptr[in, msghdr_netlink[netlink_msg_t[genl_ieee802154_family_id, genlmsghdr_t[IEEE802154_ADD_IFACE], ieee802154_policy$ADD_IFACE]]] {
// msghdr_netlink[netlink_msg_t[genl_ieee802154_family_id, genlmsghdr_t[IEEE802154_ADD_IFACE], ieee802154_policy$ADD_IFACE]] {
// addr: nil
// addrlen: len = 0x0 (4 bytes)
// pad = 0x0 (4 bytes)
// vec: ptr[in, iovec[in, netlink_msg_t[genl_ieee802154_family_id, genlmsghdr_t[IEEE802154_ADD_IFACE], ieee802154_policy$ADD_IFACE]]] {
// iovec[in, netlink_msg_t[genl_ieee802154_family_id, genlmsghdr_t[IEEE802154_ADD_IFACE], ieee802154_policy$ADD_IFACE]] {
// addr: ptr[in, netlink_msg_t[genl_ieee802154_family_id, genlmsghdr_t[IEEE802154_ADD_IFACE], ieee802154_policy$ADD_IFACE]] {
// netlink_msg_t[genl_ieee802154_family_id, genlmsghdr_t[IEEE802154_ADD_IFACE], ieee802154_policy$ADD_IFACE] {
// len: len = 0x28 (4 bytes)
// type: genl_ieee802154_family_id (resource)
// flags: netlink_msg_flags = 0x1 (2 bytes)
// seq: int32 = 0x70bd25 (4 bytes)
// pid: int32 = 0x25dfdbfc (4 bytes)
// payload: genlmsghdr_t[IEEE802154_ADD_IFACE] {
// cmd: const = 0x21 (1 bytes)
// version: const = 0x0 (1 bytes)
// reserved: const = 0x0 (2 bytes)
// }
// attrs: array[ieee802154_policy$ADD_IFACE] {
// union ieee802154_policy$ADD_IFACE {
// IEEE802154_ATTR_DEV_TYPE: nlattr_t[const[IEEE802154_ATTR_DEV_TYPE, int16], int8[IEEE802154_DEV_WPAN:IEEE802154_DEV_MONITOR]] {
// nla_len: offsetof = 0x5 (2 bytes)
// nla_type: const = 0x20 (2 bytes)
// payload: int8 = 0x1 (1 bytes)
// size: buffer: {} (length 0x0)
// pad = 0x0 (3 bytes)
// }
// }
// union ieee802154_policy$ADD_IFACE {
// IEEE802154_ATTR_PHY_NAME: nlattr_t[const[IEEE802154_ATTR_PHY_NAME, int16], string[ieee802154_phy_names]] {
// nla_len: offsetof = 0x9 (2 bytes)
// nla_type: const = 0x1f (2 bytes)
// payload: buffer: {70 68 79 31 00} (length 0x5)
// size: buffer: {} (length 0x0)
// pad = 0x0 (3 bytes)
// }
// }
// }
// }
// }
// len: len = 0x28 (8 bytes)
// }
// }
// vlen: const = 0x1 (8 bytes)
// ctrl: const = 0x0 (8 bytes)
// ctrllen: const = 0x0 (8 bytes)
// f: send_flags = 0x800 (4 bytes)
// pad = 0x0 (4 bytes)
// }
// }
// f: send_flags = 0x20004040 (8 bytes)
// ]
*(uint64_t*)0x200000000280 = 0;
*(uint32_t*)0x200000000288 = 0;
*(uint64_t*)0x200000000290 = 0x200000000180;
*(uint64_t*)0x200000000180 = 0x200000000140;
*(uint32_t*)0x200000000140 = 0x28;
*(uint16_t*)0x200000000144 = r[2];
*(uint16_t*)0x200000000146 = 1;
*(uint32_t*)0x200000000148 = 0x70bd25;
*(uint32_t*)0x20000000014c = 0x25dfdbfc;
*(uint8_t*)0x200000000150 = 0x21;
*(uint8_t*)0x200000000151 = 0;
*(uint16_t*)0x200000000152 = 0;
*(uint16_t*)0x200000000154 = 5;
*(uint16_t*)0x200000000156 = 0x20;
*(uint8_t*)0x200000000158 = 1;
*(uint16_t*)0x20000000015c = 9;
*(uint16_t*)0x20000000015e = 0x1f;
memcpy((void*)0x200000000160, "phy1\000", 5);
*(uint64_t*)0x200000000188 = 0x28;
*(uint64_t*)0x200000000298 = 1;
*(uint64_t*)0x2000000002a0 = 0;
*(uint64_t*)0x2000000002a8 = 0;
*(uint32_t*)0x2000000002b0 = 0x800;
syscall(__NR_sendmsg, /*fd=*/r[0], /*msg=*/0x200000000280ul, /*f=MSG_FASTOPEN|MSG_NOSIGNAL|MSG_DONTWAIT*/0x20004040ul);
// syz_init_net_socket$nl_generic arguments: [
// domain: const = 0x10 (8 bytes)
// type: const = 0x3 (8 bytes)
// proto: const = 0x10 (8 bytes)
// ]
// returns sock_nl_generic_init
res = -1;
res = syz_init_net_socket(/*domain=*/0x10, /*type=*/3, /*proto=*/0x10);
if (res != -1)
r[3] = res;
// syz_genetlink_get_family_id$nl802154 arguments: [
// name: ptr[in, buffer] {
// buffer: {6e 6c 38 30 32 31 35 34 00} (length 0x9)
// }
// fd: sock_nl_generic_init (resource)
// ]
// returns genl_nl802154_family_id
memcpy((void*)0x200000000040, "nl802154\000", 9);
res = -1;
res = syz_genetlink_get_family_id(/*name=*/0x200000000040, /*fd=*/-1);
if (res != -1)
r[4] = res;
// ioctl$sock_SIOCGIFINDEX_802154 arguments: [
// fd: sock_nl_generic_init (resource)
// cmd: const = 0x8933 (4 bytes)
// arg: ptr[out, ifreq_dev_t[ieee802154_dev_names, ieee802154_ifindex]] {
// ifreq_dev_t[ieee802154_dev_names, ieee802154_ifindex] {
// ifr_ifrn: buffer: {77 70 61 6e 31 00 00 00 00 00 00 00 00 00 00 00} (length 0x10)
// elem: ieee802154_ifindex (resource)
// pad = 0x0 (20 bytes)
// }
// }
// ]
memcpy((void*)0x200000000180, "wpan1\000\000\000\000\000\000\000\000\000\000\000", 16);
res = syscall(__NR_ioctl, /*fd=*/r[3], /*cmd=*/0x8933, /*arg=*/0x200000000180ul);
if (res != -1)
r[5] = *(uint32_t*)0x200000000190;
// getpid arguments: [
// ]
// returns pid
res = syscall(__NR_getpid);
if (res != -1)
r[6] = res;
// sendmsg$NL802154_CMD_SET_WPAN_PHY_NETNS arguments: [
// fd: sock_nl_generic_init (resource)
// msg: ptr[in, msghdr_netlink[netlink_msg_t[genl_nl802154_family_id, genlmsghdr_t[NL802154_CMD_SET_WPAN_PHY_NETNS], nl802154_policy$SET_WPAN_PHY_NETNS]]] {
// msghdr_netlink[netlink_msg_t[genl_nl802154_family_id, genlmsghdr_t[NL802154_CMD_SET_WPAN_PHY_NETNS], nl802154_policy$SET_WPAN_PHY_NETNS]] {
// addr: nil
// addrlen: len = 0x0 (4 bytes)
// pad = 0x0 (4 bytes)
// vec: ptr[in, iovec[in, netlink_msg_t[genl_nl802154_family_id, genlmsghdr_t[NL802154_CMD_SET_WPAN_PHY_NETNS], nl802154_policy$SET_WPAN_PHY_NETNS]]] {
// iovec[in, netlink_msg_t[genl_nl802154_family_id, genlmsghdr_t[NL802154_CMD_SET_WPAN_PHY_NETNS], nl802154_policy$SET_WPAN_PHY_NETNS]] {
// addr: ptr[in, netlink_msg_t[genl_nl802154_family_id, genlmsghdr_t[NL802154_CMD_SET_WPAN_PHY_NETNS], nl802154_policy$SET_WPAN_PHY_NETNS]] {
// netlink_msg_t[genl_nl802154_family_id, genlmsghdr_t[NL802154_CMD_SET_WPAN_PHY_NETNS], nl802154_policy$SET_WPAN_PHY_NETNS] {
// len: len = 0x24 (4 bytes)
// type: genl_nl802154_family_id (resource)
// flags: netlink_msg_flags = 0x1 (2 bytes)
// seq: int32 = 0x70bd27 (4 bytes)
// pid: int32 = 0x0 (4 bytes)
// payload: genlmsghdr_t[NL802154_CMD_SET_WPAN_PHY_NETNS] {
// cmd: const = 0x14 (1 bytes)
// version: const = 0x0 (1 bytes)
// reserved: const = 0x0 (2 bytes)
// }
// attrs: array[nl802154_policy$SET_WPAN_PHY_NETNS] {
// union nl802154_policy$SET_WPAN_PHY_NETNS {
// NL802154_ATTR_IFINDEX: nlattr_t[const[NL802154_ATTR_IFINDEX, int16], ieee802154_ifindex] {
// nla_len: offsetof = 0x8 (2 bytes)
// nla_type: const = 0x3 (2 bytes)
// payload: ieee802154_ifindex (resource)
// size: buffer: {} (length 0x0)
// }
// }
// union nl802154_policy$SET_WPAN_PHY_NETNS {
// NL802154_ATTR_PID: nlattr_t[const[NL802154_ATTR_PID, int16], pid] {
// nla_len: offsetof = 0x8 (2 bytes)
// nla_type: const = 0x1c (2 bytes)
// payload: pid (resource)
// size: buffer: {} (length 0x0)
// }
// }
// }
// }
// }
// len: len = 0x24 (8 bytes)
// }
// }
// vlen: const = 0x1 (8 bytes)
// ctrl: const = 0x0 (8 bytes)
// ctrllen: const = 0x0 (8 bytes)
// f: send_flags = 0x0 (4 bytes)
// pad = 0x0 (4 bytes)
// }
// }
// f: send_flags = 0x0 (8 bytes)
// ]
*(uint64_t*)0x200000000280 = 0;
*(uint32_t*)0x200000000288 = 0;
*(uint64_t*)0x200000000290 = 0x200000000240;
*(uint64_t*)0x200000000240 = 0x2000000002c0;
*(uint32_t*)0x2000000002c0 = 0x24;
*(uint16_t*)0x2000000002c4 = r[4];
*(uint16_t*)0x2000000002c6 = 1;
*(uint32_t*)0x2000000002c8 = 0x70bd27;
*(uint32_t*)0x2000000002cc = 0;
*(uint8_t*)0x2000000002d0 = 0x14;
*(uint8_t*)0x2000000002d1 = 0;
*(uint16_t*)0x2000000002d2 = 0;
*(uint16_t*)0x2000000002d4 = 8;
*(uint16_t*)0x2000000002d6 = 3;
*(uint32_t*)0x2000000002d8 = r[5];
*(uint16_t*)0x2000000002dc = 8;
*(uint16_t*)0x2000000002de = 0x1c;
*(uint32_t*)0x2000000002e0 = r[6];
*(uint64_t*)0x200000000248 = 0x24;
*(uint64_t*)0x200000000298 = 1;
*(uint64_t*)0x2000000002a0 = 0;
*(uint64_t*)0x2000000002a8 = 0;
*(uint32_t*)0x2000000002b0 = 0;
inject_fault(22);
syscall(__NR_sendmsg, /*fd=*/r[3], /*msg=*/0x200000000280ul, /*f=*/0ul);
return 0;
}
]