// https://syzkaller.appspot.com/bug?id=44c526a5c65e628a6caea184e06d876efbe5a37d // autogenerated by syzkaller (https://github.com/google/syzkaller) #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static unsigned long long procid; static void sleep_ms(uint64_t ms) { usleep(ms * 1000); } static uint64_t current_time_ms(void) { struct timespec ts; if (clock_gettime(CLOCK_MONOTONIC, &ts)) exit(1); return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000; } static void use_temporary_dir(void) { char tmpdir_template[] = "./syzkaller.XXXXXX"; char* tmpdir = mkdtemp(tmpdir_template); if (!tmpdir) exit(1); if (chmod(tmpdir, 0777)) exit(1); if (chdir(tmpdir)) exit(1); } #define BITMASK(bf_off, bf_len) (((1ull << (bf_len)) - 1) << (bf_off)) #define STORE_BY_BITMASK(type, htobe, addr, val, bf_off, bf_len) \ *(type*)(addr) = \ htobe((htobe(*(type*)(addr)) & ~BITMASK((bf_off), (bf_len))) | \ (((type)(val) << (bf_off)) & BITMASK((bf_off), (bf_len)))) 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 void netlink_nest(struct nlmsg* nlmsg, int typ) { struct nlattr* attr = (struct nlattr*)nlmsg->pos; attr->nla_type = typ; nlmsg->pos += sizeof(*attr); nlmsg->nested[nlmsg->nesting++] = attr; } static void netlink_done(struct nlmsg* nlmsg) { struct nlattr* attr = nlmsg->nested[--nlmsg->nesting]; attr->nla_len = nlmsg->pos - (char*)attr; } 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_send(struct nlmsg* nlmsg, int sock) { return netlink_send_ext(nlmsg, sock, 0, NULL, true); } 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; } static int netlink_next_msg(struct nlmsg* nlmsg, unsigned int offset, unsigned int total_len) { struct nlmsghdr* hdr = (struct nlmsghdr*)(nlmsg->buf + offset); if (offset == total_len || offset + hdr->nlmsg_len > total_len) return -1; return hdr->nlmsg_len; } static void netlink_add_device_impl(struct nlmsg* nlmsg, const char* type, const char* name, bool up) { struct ifinfomsg hdr; memset(&hdr, 0, sizeof(hdr)); if (up) hdr.ifi_flags = hdr.ifi_change = IFF_UP; netlink_init(nlmsg, RTM_NEWLINK, NLM_F_EXCL | NLM_F_CREATE, &hdr, sizeof(hdr)); if (name) netlink_attr(nlmsg, IFLA_IFNAME, name, strlen(name)); netlink_nest(nlmsg, IFLA_LINKINFO); netlink_attr(nlmsg, IFLA_INFO_KIND, type, strlen(type)); } static void netlink_add_device(struct nlmsg* nlmsg, int sock, const char* type, const char* name) { netlink_add_device_impl(nlmsg, type, name, false); netlink_done(nlmsg); int err = netlink_send(nlmsg, sock); if (err < 0) { } } static void netlink_add_veth(struct nlmsg* nlmsg, int sock, const char* name, const char* peer) { netlink_add_device_impl(nlmsg, "veth", name, false); netlink_nest(nlmsg, IFLA_INFO_DATA); netlink_nest(nlmsg, VETH_INFO_PEER); nlmsg->pos += sizeof(struct ifinfomsg); netlink_attr(nlmsg, IFLA_IFNAME, peer, strlen(peer)); netlink_done(nlmsg); netlink_done(nlmsg); netlink_done(nlmsg); int err = netlink_send(nlmsg, sock); if (err < 0) { } } static void netlink_add_xfrm(struct nlmsg* nlmsg, int sock, const char* name) { netlink_add_device_impl(nlmsg, "xfrm", name, true); netlink_nest(nlmsg, IFLA_INFO_DATA); int if_id = 1; netlink_attr(nlmsg, 2, &if_id, sizeof(if_id)); netlink_done(nlmsg); netlink_done(nlmsg); int err = netlink_send(nlmsg, sock); if (err < 0) { } } static void netlink_add_hsr(struct nlmsg* nlmsg, int sock, const char* name, const char* slave1, const char* slave2) { netlink_add_device_impl(nlmsg, "hsr", name, false); netlink_nest(nlmsg, IFLA_INFO_DATA); int ifindex1 = if_nametoindex(slave1); netlink_attr(nlmsg, IFLA_HSR_SLAVE1, &ifindex1, sizeof(ifindex1)); int ifindex2 = if_nametoindex(slave2); netlink_attr(nlmsg, IFLA_HSR_SLAVE2, &ifindex2, sizeof(ifindex2)); netlink_done(nlmsg); netlink_done(nlmsg); int err = netlink_send(nlmsg, sock); if (err < 0) { } } static void netlink_add_linked(struct nlmsg* nlmsg, int sock, const char* type, const char* name, const char* link) { netlink_add_device_impl(nlmsg, type, name, false); netlink_done(nlmsg); int ifindex = if_nametoindex(link); netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex)); int err = netlink_send(nlmsg, sock); if (err < 0) { } } static void netlink_add_vlan(struct nlmsg* nlmsg, int sock, const char* name, const char* link, uint16_t id, uint16_t proto) { netlink_add_device_impl(nlmsg, "vlan", name, false); netlink_nest(nlmsg, IFLA_INFO_DATA); netlink_attr(nlmsg, IFLA_VLAN_ID, &id, sizeof(id)); netlink_attr(nlmsg, IFLA_VLAN_PROTOCOL, &proto, sizeof(proto)); netlink_done(nlmsg); netlink_done(nlmsg); int ifindex = if_nametoindex(link); netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex)); int err = netlink_send(nlmsg, sock); if (err < 0) { } } static void netlink_add_macvlan(struct nlmsg* nlmsg, int sock, const char* name, const char* link) { netlink_add_device_impl(nlmsg, "macvlan", name, false); netlink_nest(nlmsg, IFLA_INFO_DATA); uint32_t mode = MACVLAN_MODE_BRIDGE; netlink_attr(nlmsg, IFLA_MACVLAN_MODE, &mode, sizeof(mode)); netlink_done(nlmsg); netlink_done(nlmsg); int ifindex = if_nametoindex(link); netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex)); int err = netlink_send(nlmsg, sock); if (err < 0) { } } static void netlink_add_geneve(struct nlmsg* nlmsg, int sock, const char* name, uint32_t vni, struct in_addr* addr4, struct in6_addr* addr6) { netlink_add_device_impl(nlmsg, "geneve", name, false); netlink_nest(nlmsg, IFLA_INFO_DATA); netlink_attr(nlmsg, IFLA_GENEVE_ID, &vni, sizeof(vni)); if (addr4) netlink_attr(nlmsg, IFLA_GENEVE_REMOTE, addr4, sizeof(*addr4)); if (addr6) netlink_attr(nlmsg, IFLA_GENEVE_REMOTE6, addr6, sizeof(*addr6)); netlink_done(nlmsg); netlink_done(nlmsg); int err = netlink_send(nlmsg, sock); if (err < 0) { } } #define IFLA_IPVLAN_FLAGS 2 #define IPVLAN_MODE_L3S 2 #undef IPVLAN_F_VEPA #define IPVLAN_F_VEPA 2 static void netlink_add_ipvlan(struct nlmsg* nlmsg, int sock, const char* name, const char* link, uint16_t mode, uint16_t flags) { netlink_add_device_impl(nlmsg, "ipvlan", name, false); netlink_nest(nlmsg, IFLA_INFO_DATA); netlink_attr(nlmsg, IFLA_IPVLAN_MODE, &mode, sizeof(mode)); netlink_attr(nlmsg, IFLA_IPVLAN_FLAGS, &flags, sizeof(flags)); netlink_done(nlmsg); netlink_done(nlmsg); int ifindex = if_nametoindex(link); netlink_attr(nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex)); int err = netlink_send(nlmsg, sock); if (err < 0) { } } static void netlink_device_change(struct nlmsg* nlmsg, int sock, const char* name, bool up, const char* master, const void* mac, int macsize, const char* new_name) { struct ifinfomsg hdr; memset(&hdr, 0, sizeof(hdr)); if (up) hdr.ifi_flags = hdr.ifi_change = IFF_UP; hdr.ifi_index = if_nametoindex(name); netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr)); if (new_name) netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name)); if (master) { int ifindex = if_nametoindex(master); netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex)); } if (macsize) netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize); int err = netlink_send(nlmsg, sock); if (err < 0) { } } static int netlink_add_addr(struct nlmsg* nlmsg, int sock, const char* dev, const void* addr, int addrsize) { struct ifaddrmsg hdr; memset(&hdr, 0, sizeof(hdr)); hdr.ifa_family = addrsize == 4 ? AF_INET : AF_INET6; hdr.ifa_prefixlen = addrsize == 4 ? 24 : 120; hdr.ifa_scope = RT_SCOPE_UNIVERSE; hdr.ifa_index = if_nametoindex(dev); netlink_init(nlmsg, RTM_NEWADDR, NLM_F_CREATE | NLM_F_REPLACE, &hdr, sizeof(hdr)); netlink_attr(nlmsg, IFA_LOCAL, addr, addrsize); netlink_attr(nlmsg, IFA_ADDRESS, addr, addrsize); return netlink_send(nlmsg, sock); } static void netlink_add_addr4(struct nlmsg* nlmsg, int sock, const char* dev, const char* addr) { struct in_addr in_addr; inet_pton(AF_INET, addr, &in_addr); int err = netlink_add_addr(nlmsg, sock, dev, &in_addr, sizeof(in_addr)); if (err < 0) { } } static void netlink_add_addr6(struct nlmsg* nlmsg, int sock, const char* dev, const char* addr) { struct in6_addr in6_addr; inet_pton(AF_INET6, addr, &in6_addr); int err = netlink_add_addr(nlmsg, sock, dev, &in6_addr, sizeof(in6_addr)); if (err < 0) { } } static struct nlmsg nlmsg; #define DEVLINK_FAMILY_NAME "devlink" #define DEVLINK_CMD_PORT_GET 5 #define DEVLINK_ATTR_BUS_NAME 1 #define DEVLINK_ATTR_DEV_NAME 2 #define DEVLINK_ATTR_NETDEV_NAME 7 static struct nlmsg nlmsg2; static void initialize_devlink_ports(const char* bus_name, const char* dev_name, const char* netdev_prefix) { struct genlmsghdr genlhdr; int len, total_len, id, err, offset; uint16_t netdev_index; int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); if (sock == -1) exit(1); int rtsock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (rtsock == -1) exit(1); id = netlink_query_family_id(&nlmsg, sock, DEVLINK_FAMILY_NAME, true); if (id == -1) goto error; memset(&genlhdr, 0, sizeof(genlhdr)); genlhdr.cmd = DEVLINK_CMD_PORT_GET; netlink_init(&nlmsg, id, NLM_F_DUMP, &genlhdr, sizeof(genlhdr)); netlink_attr(&nlmsg, DEVLINK_ATTR_BUS_NAME, bus_name, strlen(bus_name) + 1); netlink_attr(&nlmsg, DEVLINK_ATTR_DEV_NAME, dev_name, strlen(dev_name) + 1); err = netlink_send_ext(&nlmsg, sock, id, &total_len, true); if (err < 0) { goto error; } offset = 0; netdev_index = 0; while ((len = netlink_next_msg(&nlmsg, offset, total_len)) != -1) { struct nlattr* attr = (struct nlattr*)(nlmsg.buf + offset + NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(genlhdr))); for (; (char*)attr < nlmsg.buf + offset + len; attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) { if (attr->nla_type == DEVLINK_ATTR_NETDEV_NAME) { char* port_name; char netdev_name[IFNAMSIZ]; port_name = (char*)(attr + 1); snprintf(netdev_name, sizeof(netdev_name), "%s%d", netdev_prefix, netdev_index); netlink_device_change(&nlmsg2, rtsock, port_name, true, 0, 0, 0, netdev_name); break; } } offset += len; netdev_index++; } error: close(rtsock); close(sock); } #define WIFI_INITIAL_DEVICE_COUNT 2 #define WIFI_MAC_BASE \ { \ 0x08, 0x02, 0x11, 0x00, 0x00, 0x00 \ } #define WIFI_IBSS_BSSID \ { \ 0x50, 0x50, 0x50, 0x50, 0x50, 0x50 \ } #define WIFI_IBSS_SSID \ { \ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 \ } #define WIFI_DEFAULT_FREQUENCY 2412 #define WIFI_DEFAULT_SIGNAL 0 #define WIFI_DEFAULT_RX_RATE 1 #define HWSIM_CMD_REGISTER 1 #define HWSIM_CMD_FRAME 2 #define HWSIM_CMD_NEW_RADIO 4 #define HWSIM_ATTR_SUPPORT_P2P_DEVICE 14 #define HWSIM_ATTR_PERM_ADDR 22 #define IF_OPER_UP 6 struct join_ibss_props { int wiphy_freq; bool wiphy_freq_fixed; uint8_t* mac; uint8_t* ssid; int ssid_len; }; static int set_interface_state(const char* interface_name, int on) { struct ifreq ifr; int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock < 0) { return -1; } memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, interface_name); int ret = ioctl(sock, SIOCGIFFLAGS, &ifr); if (ret < 0) { close(sock); return -1; } if (on) ifr.ifr_flags |= IFF_UP; else ifr.ifr_flags &= ~IFF_UP; ret = ioctl(sock, SIOCSIFFLAGS, &ifr); close(sock); if (ret < 0) { return -1; } return 0; } static int nl80211_set_interface(struct nlmsg* nlmsg, int sock, int nl80211_family, uint32_t ifindex, uint32_t iftype) { struct genlmsghdr genlhdr; memset(&genlhdr, 0, sizeof(genlhdr)); genlhdr.cmd = NL80211_CMD_SET_INTERFACE; netlink_init(nlmsg, nl80211_family, 0, &genlhdr, sizeof(genlhdr)); netlink_attr(nlmsg, NL80211_ATTR_IFINDEX, &ifindex, sizeof(ifindex)); netlink_attr(nlmsg, NL80211_ATTR_IFTYPE, &iftype, sizeof(iftype)); int err = netlink_send(nlmsg, sock); if (err < 0) { } return err; } static int nl80211_join_ibss(struct nlmsg* nlmsg, int sock, int nl80211_family, uint32_t ifindex, struct join_ibss_props* props) { struct genlmsghdr genlhdr; memset(&genlhdr, 0, sizeof(genlhdr)); genlhdr.cmd = NL80211_CMD_JOIN_IBSS; netlink_init(nlmsg, nl80211_family, 0, &genlhdr, sizeof(genlhdr)); netlink_attr(nlmsg, NL80211_ATTR_IFINDEX, &ifindex, sizeof(ifindex)); netlink_attr(nlmsg, NL80211_ATTR_SSID, props->ssid, props->ssid_len); netlink_attr(nlmsg, NL80211_ATTR_WIPHY_FREQ, &(props->wiphy_freq), sizeof(props->wiphy_freq)); if (props->mac) netlink_attr(nlmsg, NL80211_ATTR_MAC, props->mac, ETH_ALEN); if (props->wiphy_freq_fixed) netlink_attr(nlmsg, NL80211_ATTR_FREQ_FIXED, NULL, 0); int err = netlink_send(nlmsg, sock); if (err < 0) { } return err; } static int get_ifla_operstate(struct nlmsg* nlmsg, int ifindex) { struct ifinfomsg info; memset(&info, 0, sizeof(info)); info.ifi_family = AF_UNSPEC; info.ifi_index = ifindex; int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (sock == -1) { return -1; } netlink_init(nlmsg, RTM_GETLINK, 0, &info, sizeof(info)); int n; int err = netlink_send_ext(nlmsg, sock, RTM_NEWLINK, &n, true); close(sock); if (err) { return -1; } struct rtattr* attr = IFLA_RTA(NLMSG_DATA(nlmsg->buf)); for (; RTA_OK(attr, n); attr = RTA_NEXT(attr, n)) { if (attr->rta_type == IFLA_OPERSTATE) return *((int32_t*)RTA_DATA(attr)); } return -1; } static int await_ifla_operstate(struct nlmsg* nlmsg, char* interface, int operstate) { int ifindex = if_nametoindex(interface); while (true) { usleep(1000); int ret = get_ifla_operstate(nlmsg, ifindex); if (ret < 0) return ret; if (ret == operstate) return 0; } return 0; } static int nl80211_setup_ibss_interface(struct nlmsg* nlmsg, int sock, int nl80211_family_id, char* interface, struct join_ibss_props* ibss_props) { int ifindex = if_nametoindex(interface); if (ifindex == 0) { return -1; } int ret = nl80211_set_interface(nlmsg, sock, nl80211_family_id, ifindex, NL80211_IFTYPE_ADHOC); if (ret < 0) { return -1; } ret = set_interface_state(interface, 1); if (ret < 0) { return -1; } ret = nl80211_join_ibss(nlmsg, sock, nl80211_family_id, ifindex, ibss_props); if (ret < 0) { return -1; } return 0; } static int hwsim80211_create_device(struct nlmsg* nlmsg, int sock, int hwsim_family, uint8_t mac_addr[ETH_ALEN]) { struct genlmsghdr genlhdr; memset(&genlhdr, 0, sizeof(genlhdr)); genlhdr.cmd = HWSIM_CMD_NEW_RADIO; netlink_init(nlmsg, hwsim_family, 0, &genlhdr, sizeof(genlhdr)); netlink_attr(nlmsg, HWSIM_ATTR_SUPPORT_P2P_DEVICE, NULL, 0); netlink_attr(nlmsg, HWSIM_ATTR_PERM_ADDR, mac_addr, ETH_ALEN); int err = netlink_send(nlmsg, sock); if (err < 0) { } return err; } static void initialize_wifi_devices(void) { int rfkill = open("/dev/rfkill", O_RDWR); if (rfkill == -1) { if (errno != ENOENT && errno != EACCES) exit(1); } else { struct rfkill_event event = {0}; event.type = RFKILL_TYPE_ALL; event.op = RFKILL_OP_CHANGE_ALL; if (write(rfkill, &event, sizeof(event)) != (ssize_t)(sizeof(event))) exit(1); close(rfkill); } uint8_t mac_addr[6] = WIFI_MAC_BASE; int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); if (sock < 0) { return; } int hwsim_family_id = netlink_query_family_id(&nlmsg, sock, "MAC80211_HWSIM", true); int nl80211_family_id = netlink_query_family_id(&nlmsg, sock, "nl80211", true); uint8_t ssid[] = WIFI_IBSS_SSID; uint8_t bssid[] = WIFI_IBSS_BSSID; struct join_ibss_props ibss_props = {.wiphy_freq = WIFI_DEFAULT_FREQUENCY, .wiphy_freq_fixed = true, .mac = bssid, .ssid = ssid, .ssid_len = sizeof(ssid)}; for (int device_id = 0; device_id < WIFI_INITIAL_DEVICE_COUNT; device_id++) { mac_addr[5] = device_id; int ret = hwsim80211_create_device(&nlmsg, sock, hwsim_family_id, mac_addr); if (ret < 0) exit(1); char interface[6] = "wlan0"; interface[4] += device_id; if (nl80211_setup_ibss_interface(&nlmsg, sock, nl80211_family_id, interface, &ibss_props) < 0) exit(1); } for (int device_id = 0; device_id < WIFI_INITIAL_DEVICE_COUNT; device_id++) { char interface[6] = "wlan0"; interface[4] += device_id; int ret = await_ifla_operstate(&nlmsg, interface, IF_OPER_UP); if (ret < 0) exit(1); } close(sock); } static int runcmdline(char* cmdline) { int ret = system(cmdline); if (ret) { } return ret; } #define DEV_IPV4 "172.20.20.%d" #define DEV_IPV6 "fe80::%02x" #define DEV_MAC 0x00aaaaaaaaaa static void netdevsim_add(unsigned int addr, unsigned int port_count) { write_file("/sys/bus/netdevsim/del_device", "%u", addr); if (write_file("/sys/bus/netdevsim/new_device", "%u %u", addr, port_count)) { char buf[32]; snprintf(buf, sizeof(buf), "netdevsim%d", addr); initialize_devlink_ports("netdevsim", buf, "netdevsim"); } } #define WG_GENL_NAME "wireguard" enum wg_cmd { WG_CMD_GET_DEVICE, WG_CMD_SET_DEVICE, }; enum wgdevice_attribute { WGDEVICE_A_UNSPEC, WGDEVICE_A_IFINDEX, WGDEVICE_A_IFNAME, WGDEVICE_A_PRIVATE_KEY, WGDEVICE_A_PUBLIC_KEY, WGDEVICE_A_FLAGS, WGDEVICE_A_LISTEN_PORT, WGDEVICE_A_FWMARK, WGDEVICE_A_PEERS, }; enum wgpeer_attribute { WGPEER_A_UNSPEC, WGPEER_A_PUBLIC_KEY, WGPEER_A_PRESHARED_KEY, WGPEER_A_FLAGS, WGPEER_A_ENDPOINT, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, WGPEER_A_LAST_HANDSHAKE_TIME, WGPEER_A_RX_BYTES, WGPEER_A_TX_BYTES, WGPEER_A_ALLOWEDIPS, WGPEER_A_PROTOCOL_VERSION, }; enum wgallowedip_attribute { WGALLOWEDIP_A_UNSPEC, WGALLOWEDIP_A_FAMILY, WGALLOWEDIP_A_IPADDR, WGALLOWEDIP_A_CIDR_MASK, }; static void netlink_wireguard_setup(void) { const char ifname_a[] = "wg0"; const char ifname_b[] = "wg1"; const char ifname_c[] = "wg2"; const char private_a[] = "\xa0\x5c\xa8\x4f\x6c\x9c\x8e\x38\x53\xe2\xfd\x7a\x70\xae\x0f\xb2\x0f\xa1" "\x52\x60\x0c\xb0\x08\x45\x17\x4f\x08\x07\x6f\x8d\x78\x43"; const char private_b[] = "\xb0\x80\x73\xe8\xd4\x4e\x91\xe3\xda\x92\x2c\x22\x43\x82\x44\xbb\x88\x5c" "\x69\xe2\x69\xc8\xe9\xd8\x35\xb1\x14\x29\x3a\x4d\xdc\x6e"; const char private_c[] = "\xa0\xcb\x87\x9a\x47\xf5\xbc\x64\x4c\x0e\x69\x3f\xa6\xd0\x31\xc7\x4a\x15" "\x53\xb6\xe9\x01\xb9\xff\x2f\x51\x8c\x78\x04\x2f\xb5\x42"; const char public_a[] = "\x97\x5c\x9d\x81\xc9\x83\xc8\x20\x9e\xe7\x81\x25\x4b\x89\x9f\x8e\xd9\x25" "\xae\x9f\x09\x23\xc2\x3c\x62\xf5\x3c\x57\xcd\xbf\x69\x1c"; const char public_b[] = "\xd1\x73\x28\x99\xf6\x11\xcd\x89\x94\x03\x4d\x7f\x41\x3d\xc9\x57\x63\x0e" "\x54\x93\xc2\x85\xac\xa4\x00\x65\xcb\x63\x11\xbe\x69\x6b"; const char public_c[] = "\xf4\x4d\xa3\x67\xa8\x8e\xe6\x56\x4f\x02\x02\x11\x45\x67\x27\x08\x2f\x5c" "\xeb\xee\x8b\x1b\xf5\xeb\x73\x37\x34\x1b\x45\x9b\x39\x22"; const uint16_t listen_a = 20001; const uint16_t listen_b = 20002; const uint16_t listen_c = 20003; const uint16_t af_inet = AF_INET; const uint16_t af_inet6 = AF_INET6; const struct sockaddr_in endpoint_b_v4 = { .sin_family = AF_INET, .sin_port = htons(listen_b), .sin_addr = {htonl(INADDR_LOOPBACK)}}; const struct sockaddr_in endpoint_c_v4 = { .sin_family = AF_INET, .sin_port = htons(listen_c), .sin_addr = {htonl(INADDR_LOOPBACK)}}; struct sockaddr_in6 endpoint_a_v6 = {.sin6_family = AF_INET6, .sin6_port = htons(listen_a)}; endpoint_a_v6.sin6_addr = in6addr_loopback; struct sockaddr_in6 endpoint_c_v6 = {.sin6_family = AF_INET6, .sin6_port = htons(listen_c)}; endpoint_c_v6.sin6_addr = in6addr_loopback; const struct in_addr first_half_v4 = {0}; const struct in_addr second_half_v4 = {(uint32_t)htonl(128 << 24)}; const struct in6_addr first_half_v6 = {{{0}}}; const struct in6_addr second_half_v6 = {{{0x80}}}; const uint8_t half_cidr = 1; const uint16_t persistent_keepalives[] = {1, 3, 7, 9, 14, 19}; struct genlmsghdr genlhdr = {.cmd = WG_CMD_SET_DEVICE, .version = 1}; int sock; int id, err; sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC); if (sock == -1) { return; } id = netlink_query_family_id(&nlmsg, sock, WG_GENL_NAME, true); if (id == -1) goto error; netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr)); netlink_attr(&nlmsg, WGDEVICE_A_IFNAME, ifname_a, strlen(ifname_a) + 1); netlink_attr(&nlmsg, WGDEVICE_A_PRIVATE_KEY, private_a, 32); netlink_attr(&nlmsg, WGDEVICE_A_LISTEN_PORT, &listen_a, 2); netlink_nest(&nlmsg, NLA_F_NESTED | WGDEVICE_A_PEERS); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_b, 32); netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_b_v4, sizeof(endpoint_b_v4)); netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, &persistent_keepalives[0], 2); netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2); netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v4, sizeof(first_half_v4)); netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1); netlink_done(&nlmsg); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2); netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v6, sizeof(first_half_v6)); netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1); netlink_done(&nlmsg); netlink_done(&nlmsg); netlink_done(&nlmsg); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_c, 32); netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_c_v6, sizeof(endpoint_c_v6)); netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, &persistent_keepalives[1], 2); netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2); netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v4, sizeof(second_half_v4)); netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1); netlink_done(&nlmsg); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2); netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v6, sizeof(second_half_v6)); netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1); netlink_done(&nlmsg); netlink_done(&nlmsg); netlink_done(&nlmsg); netlink_done(&nlmsg); err = netlink_send(&nlmsg, sock); if (err < 0) { } netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr)); netlink_attr(&nlmsg, WGDEVICE_A_IFNAME, ifname_b, strlen(ifname_b) + 1); netlink_attr(&nlmsg, WGDEVICE_A_PRIVATE_KEY, private_b, 32); netlink_attr(&nlmsg, WGDEVICE_A_LISTEN_PORT, &listen_b, 2); netlink_nest(&nlmsg, NLA_F_NESTED | WGDEVICE_A_PEERS); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_a, 32); netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_a_v6, sizeof(endpoint_a_v6)); netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, &persistent_keepalives[2], 2); netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2); netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v4, sizeof(first_half_v4)); netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1); netlink_done(&nlmsg); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2); netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v6, sizeof(first_half_v6)); netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1); netlink_done(&nlmsg); netlink_done(&nlmsg); netlink_done(&nlmsg); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_c, 32); netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_c_v4, sizeof(endpoint_c_v4)); netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, &persistent_keepalives[3], 2); netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2); netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v4, sizeof(second_half_v4)); netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1); netlink_done(&nlmsg); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2); netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v6, sizeof(second_half_v6)); netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1); netlink_done(&nlmsg); netlink_done(&nlmsg); netlink_done(&nlmsg); netlink_done(&nlmsg); err = netlink_send(&nlmsg, sock); if (err < 0) { } netlink_init(&nlmsg, id, 0, &genlhdr, sizeof(genlhdr)); netlink_attr(&nlmsg, WGDEVICE_A_IFNAME, ifname_c, strlen(ifname_c) + 1); netlink_attr(&nlmsg, WGDEVICE_A_PRIVATE_KEY, private_c, 32); netlink_attr(&nlmsg, WGDEVICE_A_LISTEN_PORT, &listen_c, 2); netlink_nest(&nlmsg, NLA_F_NESTED | WGDEVICE_A_PEERS); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_a, 32); netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_a_v6, sizeof(endpoint_a_v6)); netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, &persistent_keepalives[4], 2); netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2); netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v4, sizeof(first_half_v4)); netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1); netlink_done(&nlmsg); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2); netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &first_half_v6, sizeof(first_half_v6)); netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1); netlink_done(&nlmsg); netlink_done(&nlmsg); netlink_done(&nlmsg); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGPEER_A_PUBLIC_KEY, public_b, 32); netlink_attr(&nlmsg, WGPEER_A_ENDPOINT, &endpoint_b_v4, sizeof(endpoint_b_v4)); netlink_attr(&nlmsg, WGPEER_A_PERSISTENT_KEEPALIVE_INTERVAL, &persistent_keepalives[5], 2); netlink_nest(&nlmsg, NLA_F_NESTED | WGPEER_A_ALLOWEDIPS); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet, 2); netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v4, sizeof(second_half_v4)); netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1); netlink_done(&nlmsg); netlink_nest(&nlmsg, NLA_F_NESTED | 0); netlink_attr(&nlmsg, WGALLOWEDIP_A_FAMILY, &af_inet6, 2); netlink_attr(&nlmsg, WGALLOWEDIP_A_IPADDR, &second_half_v6, sizeof(second_half_v6)); netlink_attr(&nlmsg, WGALLOWEDIP_A_CIDR_MASK, &half_cidr, 1); netlink_done(&nlmsg); netlink_done(&nlmsg); netlink_done(&nlmsg); netlink_done(&nlmsg); err = netlink_send(&nlmsg, sock); if (err < 0) { } error: close(sock); } static void initialize_netdevices(void) { char netdevsim[16]; sprintf(netdevsim, "netdevsim%d", (int)procid); struct { const char* type; const char* dev; } devtypes[] = { {"ip6gretap", "ip6gretap0"}, {"bridge", "bridge0"}, {"vcan", "vcan0"}, {"bond", "bond0"}, {"team", "team0"}, {"dummy", "dummy0"}, {"nlmon", "nlmon0"}, {"caif", "caif0"}, {"batadv", "batadv0"}, {"vxcan", "vxcan1"}, {"veth", 0}, {"wireguard", "wg0"}, {"wireguard", "wg1"}, {"wireguard", "wg2"}, }; const char* devmasters[] = {"bridge", "bond", "team", "batadv"}; struct { const char* name; int macsize; bool noipv6; } devices[] = { {"lo", ETH_ALEN}, {"sit0", 0}, {"bridge0", ETH_ALEN}, {"vcan0", 0, true}, {"tunl0", 0}, {"gre0", 0}, {"gretap0", ETH_ALEN}, {"ip_vti0", 0}, {"ip6_vti0", 0}, {"ip6tnl0", 0}, {"ip6gre0", 0}, {"ip6gretap0", ETH_ALEN}, {"erspan0", ETH_ALEN}, {"bond0", ETH_ALEN}, {"veth0", ETH_ALEN}, {"veth1", ETH_ALEN}, {"team0", ETH_ALEN}, {"veth0_to_bridge", ETH_ALEN}, {"veth1_to_bridge", ETH_ALEN}, {"veth0_to_bond", ETH_ALEN}, {"veth1_to_bond", ETH_ALEN}, {"veth0_to_team", ETH_ALEN}, {"veth1_to_team", ETH_ALEN}, {"veth0_to_hsr", ETH_ALEN}, {"veth1_to_hsr", ETH_ALEN}, {"hsr0", 0}, {"dummy0", ETH_ALEN}, {"nlmon0", 0}, {"vxcan0", 0, true}, {"vxcan1", 0, true}, {"caif0", ETH_ALEN}, {"batadv0", ETH_ALEN}, {netdevsim, ETH_ALEN}, {"xfrm0", ETH_ALEN}, {"veth0_virt_wifi", ETH_ALEN}, {"veth1_virt_wifi", ETH_ALEN}, {"virt_wifi0", ETH_ALEN}, {"veth0_vlan", ETH_ALEN}, {"veth1_vlan", ETH_ALEN}, {"vlan0", ETH_ALEN}, {"vlan1", ETH_ALEN}, {"macvlan0", ETH_ALEN}, {"macvlan1", ETH_ALEN}, {"ipvlan0", ETH_ALEN}, {"ipvlan1", ETH_ALEN}, {"veth0_macvtap", ETH_ALEN}, {"veth1_macvtap", ETH_ALEN}, {"macvtap0", ETH_ALEN}, {"macsec0", ETH_ALEN}, {"veth0_to_batadv", ETH_ALEN}, {"veth1_to_batadv", ETH_ALEN}, {"batadv_slave_0", ETH_ALEN}, {"batadv_slave_1", ETH_ALEN}, {"geneve0", ETH_ALEN}, {"geneve1", ETH_ALEN}, {"wg0", 0}, {"wg1", 0}, {"wg2", 0}, }; int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (sock == -1) exit(1); unsigned i; for (i = 0; i < sizeof(devtypes) / sizeof(devtypes[0]); i++) netlink_add_device(&nlmsg, sock, devtypes[i].type, devtypes[i].dev); for (i = 0; i < sizeof(devmasters) / (sizeof(devmasters[0])); i++) { char master[32], slave0[32], veth0[32], slave1[32], veth1[32]; sprintf(slave0, "%s_slave_0", devmasters[i]); sprintf(veth0, "veth0_to_%s", devmasters[i]); netlink_add_veth(&nlmsg, sock, slave0, veth0); sprintf(slave1, "%s_slave_1", devmasters[i]); sprintf(veth1, "veth1_to_%s", devmasters[i]); netlink_add_veth(&nlmsg, sock, slave1, veth1); sprintf(master, "%s0", devmasters[i]); netlink_device_change(&nlmsg, sock, slave0, false, master, 0, 0, NULL); netlink_device_change(&nlmsg, sock, slave1, false, master, 0, 0, NULL); } netlink_add_xfrm(&nlmsg, sock, "xfrm0"); netlink_device_change(&nlmsg, sock, "bridge_slave_0", true, 0, 0, 0, NULL); netlink_device_change(&nlmsg, sock, "bridge_slave_1", true, 0, 0, 0, NULL); netlink_add_veth(&nlmsg, sock, "hsr_slave_0", "veth0_to_hsr"); netlink_add_veth(&nlmsg, sock, "hsr_slave_1", "veth1_to_hsr"); netlink_add_hsr(&nlmsg, sock, "hsr0", "hsr_slave_0", "hsr_slave_1"); netlink_device_change(&nlmsg, sock, "hsr_slave_0", true, 0, 0, 0, NULL); netlink_device_change(&nlmsg, sock, "hsr_slave_1", true, 0, 0, 0, NULL); netlink_add_veth(&nlmsg, sock, "veth0_virt_wifi", "veth1_virt_wifi"); netlink_add_linked(&nlmsg, sock, "virt_wifi", "virt_wifi0", "veth1_virt_wifi"); netlink_add_veth(&nlmsg, sock, "veth0_vlan", "veth1_vlan"); netlink_add_vlan(&nlmsg, sock, "vlan0", "veth0_vlan", 0, htons(ETH_P_8021Q)); netlink_add_vlan(&nlmsg, sock, "vlan1", "veth0_vlan", 1, htons(ETH_P_8021AD)); netlink_add_macvlan(&nlmsg, sock, "macvlan0", "veth1_vlan"); netlink_add_macvlan(&nlmsg, sock, "macvlan1", "veth1_vlan"); netlink_add_ipvlan(&nlmsg, sock, "ipvlan0", "veth0_vlan", IPVLAN_MODE_L2, 0); netlink_add_ipvlan(&nlmsg, sock, "ipvlan1", "veth0_vlan", IPVLAN_MODE_L3S, IPVLAN_F_VEPA); netlink_add_veth(&nlmsg, sock, "veth0_macvtap", "veth1_macvtap"); netlink_add_linked(&nlmsg, sock, "macvtap", "macvtap0", "veth0_macvtap"); netlink_add_linked(&nlmsg, sock, "macsec", "macsec0", "veth1_macvtap"); char addr[32]; sprintf(addr, DEV_IPV4, 14 + 10); struct in_addr geneve_addr4; if (inet_pton(AF_INET, addr, &geneve_addr4) <= 0) exit(1); struct in6_addr geneve_addr6; if (inet_pton(AF_INET6, "fc00::01", &geneve_addr6) <= 0) exit(1); netlink_add_geneve(&nlmsg, sock, "geneve0", 0, &geneve_addr4, 0); netlink_add_geneve(&nlmsg, sock, "geneve1", 1, 0, &geneve_addr6); netdevsim_add((int)procid, 4); netlink_wireguard_setup(); for (i = 0; i < sizeof(devices) / (sizeof(devices[0])); i++) { char addr[32]; sprintf(addr, DEV_IPV4, i + 10); netlink_add_addr4(&nlmsg, sock, devices[i].name, addr); if (!devices[i].noipv6) { sprintf(addr, DEV_IPV6, i + 10); netlink_add_addr6(&nlmsg, sock, devices[i].name, addr); } uint64_t macaddr = DEV_MAC + ((i + 10ull) << 40); netlink_device_change(&nlmsg, sock, devices[i].name, true, 0, &macaddr, devices[i].macsize, NULL); } close(sock); } static void initialize_netdevices_init(void) { int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (sock == -1) exit(1); struct { const char* type; int macsize; bool noipv6; bool noup; } devtypes[] = { {"nr", 7, true}, {"rose", 5, true, true}, }; unsigned i; for (i = 0; i < sizeof(devtypes) / sizeof(devtypes[0]); i++) { char dev[32], addr[32]; sprintf(dev, "%s%d", devtypes[i].type, (int)procid); sprintf(addr, "172.30.%d.%d", i, (int)procid + 1); netlink_add_addr4(&nlmsg, sock, dev, addr); if (!devtypes[i].noipv6) { sprintf(addr, "fe88::%02x:%02x", i, (int)procid + 1); netlink_add_addr6(&nlmsg, sock, dev, addr); } int macsize = devtypes[i].macsize; uint64_t macaddr = 0xbbbbbb + ((unsigned long long)i << (8 * (macsize - 2))) + (procid << (8 * (macsize - 1))); netlink_device_change(&nlmsg, sock, dev, !devtypes[i].noup, 0, &macaddr, macsize, NULL); } close(sock); } #define MAX_FDS 30 static void mount_cgroups(const char* dir, const char** controllers, int count) { if (mkdir(dir, 0777)) { return; } char enabled[128] = {0}; int i = 0; for (; i < count; i++) { if (mount("none", dir, "cgroup", 0, controllers[i])) { continue; } umount(dir); strcat(enabled, ","); strcat(enabled, controllers[i]); } if (enabled[0] == 0) { if (rmdir(dir) && errno != EBUSY) exit(1); return; } if (mount("none", dir, "cgroup", 0, enabled + 1)) { if (rmdir(dir) && errno != EBUSY) exit(1); } if (chmod(dir, 0777)) { } } static void mount_cgroups2(const char** controllers, int count) { if (mkdir("/syzcgroup/unified", 0777)) { return; } if (mount("none", "/syzcgroup/unified", "cgroup2", 0, NULL)) { if (rmdir("/syzcgroup/unified") && errno != EBUSY) exit(1); return; } if (chmod("/syzcgroup/unified", 0777)) { } int control = open("/syzcgroup/unified/cgroup.subtree_control", O_WRONLY); if (control == -1) return; int i; for (i = 0; i < count; i++) if (write(control, controllers[i], strlen(controllers[i])) < 0) { } close(control); } static void setup_cgroups() { const char* unified_controllers[] = {"+cpu", "+io", "+pids"}; const char* net_controllers[] = {"net", "net_prio", "devices", "blkio", "freezer"}; const char* cpu_controllers[] = {"cpuset", "cpuacct", "hugetlb", "rlimit", "memory"}; if (mkdir("/syzcgroup", 0777)) { return; } mount_cgroups2(unified_controllers, sizeof(unified_controllers) / sizeof(unified_controllers[0])); mount_cgroups("/syzcgroup/net", net_controllers, sizeof(net_controllers) / sizeof(net_controllers[0])); mount_cgroups("/syzcgroup/cpu", cpu_controllers, sizeof(cpu_controllers) / sizeof(cpu_controllers[0])); write_file("/syzcgroup/cpu/cgroup.clone_children", "1"); write_file("/syzcgroup/cpu/cpuset.memory_pressure_enabled", "1"); } static void setup_cgroups_loop() { int pid = getpid(); char file[128]; char cgroupdir[64]; snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/unified/syz%llu", procid); if (mkdir(cgroupdir, 0777)) { } snprintf(file, sizeof(file), "%s/pids.max", cgroupdir); write_file(file, "32"); snprintf(file, sizeof(file), "%s/cgroup.procs", cgroupdir); write_file(file, "%d", pid); snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/cpu/syz%llu", procid); if (mkdir(cgroupdir, 0777)) { } snprintf(file, sizeof(file), "%s/cgroup.procs", cgroupdir); write_file(file, "%d", pid); snprintf(file, sizeof(file), "%s/memory.soft_limit_in_bytes", cgroupdir); write_file(file, "%d", 299 << 20); snprintf(file, sizeof(file), "%s/memory.limit_in_bytes", cgroupdir); write_file(file, "%d", 300 << 20); snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/net/syz%llu", procid); if (mkdir(cgroupdir, 0777)) { } snprintf(file, sizeof(file), "%s/cgroup.procs", cgroupdir); write_file(file, "%d", pid); } static void setup_cgroups_test() { char cgroupdir[64]; snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/unified/syz%llu", procid); if (symlink(cgroupdir, "./cgroup")) { } snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/cpu/syz%llu", procid); if (symlink(cgroupdir, "./cgroup.cpu")) { } snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/net/syz%llu", procid); if (symlink(cgroupdir, "./cgroup.net")) { } } static void setup_common() { if (mount(0, "/sys/fs/fuse/connections", "fusectl", 0, 0)) { } } static void setup_binderfs() { if (mkdir("/dev/binderfs", 0777)) { } if (mount("binder", "/dev/binderfs", "binder", 0, NULL)) { } } static void loop(); static void sandbox_common() { prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); setsid(); struct rlimit rlim; rlim.rlim_cur = rlim.rlim_max = (200 << 20); setrlimit(RLIMIT_AS, &rlim); rlim.rlim_cur = rlim.rlim_max = 32 << 20; setrlimit(RLIMIT_MEMLOCK, &rlim); rlim.rlim_cur = rlim.rlim_max = 136 << 20; setrlimit(RLIMIT_FSIZE, &rlim); rlim.rlim_cur = rlim.rlim_max = 1 << 20; setrlimit(RLIMIT_STACK, &rlim); rlim.rlim_cur = rlim.rlim_max = 128 << 20; setrlimit(RLIMIT_CORE, &rlim); rlim.rlim_cur = rlim.rlim_max = 256; setrlimit(RLIMIT_NOFILE, &rlim); if (unshare(CLONE_NEWNS)) { } if (mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL)) { } if (unshare(CLONE_NEWIPC)) { } if (unshare(0x02000000)) { } if (unshare(CLONE_NEWUTS)) { } if (unshare(CLONE_SYSVSEM)) { } typedef struct { const char* name; const char* value; } sysctl_t; static const sysctl_t sysctls[] = { {"/proc/sys/kernel/shmmax", "16777216"}, {"/proc/sys/kernel/shmall", "536870912"}, {"/proc/sys/kernel/shmmni", "1024"}, {"/proc/sys/kernel/msgmax", "8192"}, {"/proc/sys/kernel/msgmni", "1024"}, {"/proc/sys/kernel/msgmnb", "1024"}, {"/proc/sys/kernel/sem", "1024 1048576 500 1024"}, }; unsigned i; for (i = 0; i < sizeof(sysctls) / sizeof(sysctls[0]); i++) write_file(sysctls[i].name, sysctls[i].value); } static int wait_for_loop(int pid) { if (pid < 0) exit(1); int status = 0; while (waitpid(-1, &status, __WALL) != pid) { } return WEXITSTATUS(status); } static void drop_caps(void) { struct __user_cap_header_struct cap_hdr = {}; struct __user_cap_data_struct cap_data[2] = {}; cap_hdr.version = _LINUX_CAPABILITY_VERSION_3; cap_hdr.pid = getpid(); if (syscall(SYS_capget, &cap_hdr, &cap_data)) exit(1); const int drop = (1 << CAP_SYS_PTRACE) | (1 << CAP_SYS_NICE); cap_data[0].effective &= ~drop; cap_data[0].permitted &= ~drop; cap_data[0].inheritable &= ~drop; if (syscall(SYS_capset, &cap_hdr, &cap_data)) exit(1); } static int do_sandbox_none(void) { if (unshare(CLONE_NEWPID)) { } int pid = fork(); if (pid != 0) return wait_for_loop(pid); setup_common(); sandbox_common(); drop_caps(); initialize_netdevices_init(); if (unshare(CLONE_NEWNET)) { } write_file("/proc/sys/net/ipv4/ping_group_range", "0 65535"); initialize_netdevices(); initialize_wifi_devices(); setup_binderfs(); loop(); exit(1); } #define FS_IOC_SETFLAGS _IOW('f', 2, long) static void remove_dir(const char* dir) { int iter = 0; DIR* dp = 0; retry: while (umount2(dir, MNT_DETACH | UMOUNT_NOFOLLOW) == 0) { } dp = opendir(dir); if (dp == NULL) { if (errno == EMFILE) { exit(1); } exit(1); } struct dirent* ep = 0; while ((ep = readdir(dp))) { if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0) continue; char filename[FILENAME_MAX]; snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name); while (umount2(filename, MNT_DETACH | UMOUNT_NOFOLLOW) == 0) { } struct stat st; if (lstat(filename, &st)) exit(1); if (S_ISDIR(st.st_mode)) { remove_dir(filename); continue; } int i; for (i = 0;; i++) { if (unlink(filename) == 0) break; if (errno == EPERM) { int fd = open(filename, O_RDONLY); if (fd != -1) { long flags = 0; if (ioctl(fd, FS_IOC_SETFLAGS, &flags) == 0) { } close(fd); continue; } } if (errno == EROFS) { break; } if (errno != EBUSY || i > 100) exit(1); if (umount2(filename, MNT_DETACH | UMOUNT_NOFOLLOW)) exit(1); } } closedir(dp); for (int i = 0;; i++) { if (rmdir(dir) == 0) break; if (i < 100) { if (errno == EPERM) { int fd = open(dir, O_RDONLY); if (fd != -1) { long flags = 0; if (ioctl(fd, FS_IOC_SETFLAGS, &flags) == 0) { } close(fd); continue; } } if (errno == EROFS) { break; } if (errno == EBUSY) { if (umount2(dir, MNT_DETACH | UMOUNT_NOFOLLOW)) exit(1); continue; } if (errno == ENOTEMPTY) { if (iter < 100) { iter++; goto retry; } } } exit(1); } } static void kill_and_wait(int pid, int* status) { kill(-pid, SIGKILL); kill(pid, SIGKILL); for (int i = 0; i < 100; i++) { if (waitpid(-1, status, WNOHANG | __WALL) == pid) return; usleep(1000); } DIR* dir = opendir("/sys/fs/fuse/connections"); if (dir) { for (;;) { struct dirent* ent = readdir(dir); if (!ent) break; if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) continue; char abort[300]; snprintf(abort, sizeof(abort), "/sys/fs/fuse/connections/%s/abort", ent->d_name); int fd = open(abort, O_WRONLY); if (fd == -1) { continue; } if (write(fd, abort, 1) < 0) { } close(fd); } closedir(dir); } else { } while (waitpid(-1, status, __WALL) != pid) { } } static void setup_loop() { setup_cgroups_loop(); } static void setup_test() { prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); setpgrp(); setup_cgroups_test(); write_file("/proc/self/oom_score_adj", "1000"); if (symlink("/dev/binderfs", "./binderfs")) { } } static void close_fds() { for (int fd = 3; fd < MAX_FDS; fd++) close(fd); } static void setup_sysctl() { char mypid[32]; snprintf(mypid, sizeof(mypid), "%d", getpid()); struct { const char* name; const char* data; } files[] = { {"/sys/kernel/debug/x86/nmi_longest_ns", "10000000000"}, {"/proc/sys/kernel/hung_task_check_interval_secs", "20"}, {"/proc/sys/net/core/bpf_jit_kallsyms", "1"}, {"/proc/sys/net/core/bpf_jit_harden", "0"}, {"/proc/sys/kernel/kptr_restrict", "0"}, {"/proc/sys/kernel/softlockup_all_cpu_backtrace", "1"}, {"/proc/sys/fs/mount-max", "100"}, {"/proc/sys/vm/oom_dump_tasks", "0"}, {"/proc/sys/debug/exception-trace", "0"}, {"/proc/sys/kernel/printk", "7 4 1 3"}, {"/proc/sys/kernel/keys/gc_delay", "1"}, {"/proc/sys/vm/oom_kill_allocating_task", "1"}, {"/proc/sys/kernel/ctrl-alt-del", "0"}, {"/proc/sys/kernel/cad_pid", mypid}, }; for (size_t i = 0; i < sizeof(files) / sizeof(files[0]); i++) { if (!write_file(files[i].name, files[i].data)) printf("write to %s failed: %s\n", files[i].name, strerror(errno)); } } #define SWAP_FILE "./swap-file" #define SWAP_FILE_SIZE (128 * 1000 * 1000) static void setup_swap() { swapoff(SWAP_FILE); unlink(SWAP_FILE); int fd = open(SWAP_FILE, O_CREAT | O_WRONLY | O_CLOEXEC, 0600); if (fd == -1) { exit(1); return; } fallocate(fd, FALLOC_FL_ZERO_RANGE, 0, SWAP_FILE_SIZE); close(fd); char cmdline[64]; sprintf(cmdline, "mkswap %s", SWAP_FILE); if (runcmdline(cmdline)) { exit(1); return; } if (swapon(SWAP_FILE, SWAP_FLAG_PREFER) == 1) { exit(1); return; } } static void execute_one(void); #define WAIT_FLAGS __WALL static void loop(void) { setup_loop(); int iter = 0; for (;; iter++) { char cwdbuf[32]; sprintf(cwdbuf, "./%d", iter); if (mkdir(cwdbuf, 0777)) exit(1); int pid = fork(); if (pid < 0) exit(1); if (pid == 0) { if (chdir(cwdbuf)) exit(1); setup_test(); execute_one(); close_fds(); exit(0); } int status = 0; uint64_t start = current_time_ms(); for (;;) { if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid) break; sleep_ms(1); if (current_time_ms() - start < 5000) continue; kill_and_wait(pid, &status); break; } remove_dir(cwdbuf); } } uint64_t r[9] = {0xffffffffffffffff, 0x0, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0}; void execute_one(void) { intptr_t res = 0; res = syscall(__NR_socket, /*domain=*/1ul, /*type=*/2ul, /*proto=*/0); if (res != -1) r[0] = res; memcpy((void*)0x20000100, "vcan0\000\000\000\000\000\000\000\000\000\000\000", 16); res = syscall(__NR_ioctl, /*fd=*/r[0], /*cmd=*/0x8933, /*arg=*/0x20000100ul); if (res != -1) r[1] = *(uint32_t*)0x20000110; res = syscall(__NR_socket, /*domain=*/0x1dul, /*type=*/2ul, /*proto=*/2); if (res != -1) r[2] = res; *(uint16_t*)0x20000000 = 0x1d; *(uint32_t*)0x20000004 = 0; *(uint32_t*)0x20000008 = 0; *(uint32_t*)0x2000000c = 0; syscall(__NR_connect, /*fd=*/r[2], /*addr=*/0x20000000ul, /*len=*/0x10ul); *(uint64_t*)0x20000480 = 0x20000340; *(uint16_t*)0x20000340 = 0x1d; *(uint32_t*)0x20000344 = r[1]; *(uint32_t*)0x20000348 = 0x3f420f00; *(uint32_t*)0x2000034c = 0; *(uint32_t*)0x20000488 = 0x10; *(uint64_t*)0x20000490 = 0x20000040; *(uint64_t*)0x20000040 = 0x20000580; memcpy((void*)0x20000580, "\x01\x00\x00\x00\xd7\xfe\x68\xca\x00\x00\x00\x00\x00\x00\x00\x00", 16); *(uint64_t*)0x20000590 = 0; *(uint64_t*)0x20000598 = 0; *(uint64_t*)0x200005a0 = 0; *(uint64_t*)0x200005a8 = r[0]; memcpy((void*)0x200005b0, "\x3b\xe9\x1b\xb9\xf6", 5); *(uint64_t*)0x20000048 = 0x20000600; *(uint64_t*)0x20000498 = 1; *(uint64_t*)0x200004a0 = 0; *(uint64_t*)0x200004a8 = 0; *(uint32_t*)0x200004b0 = 0x8007; syscall(__NR_sendmsg, /*fd=*/r[2], /*msg=*/0x20000480ul, /*f=*/0x20040011ul); res = syscall(__NR_socket, /*domain=*/2ul, /*type=*/2ul, /*proto=*/0); if (res != -1) r[3] = res; *(uint32_t*)0x20000180 = 2; *(uint16_t*)0x20000188 = 2; *(uint16_t*)0x2000018a = htobe16(0); *(uint8_t*)0x2000018c = 0xac; *(uint8_t*)0x2000018d = 0x14; *(uint8_t*)0x2000018e = 0x14; *(uint8_t*)0x2000018f = 0xaa; syscall(__NR_setsockopt, /*fd=*/r[3], /*level=*/0, /*optname=*/0x2a, /*optval=*/0x20000180ul, /*optlen=*/0x88ul); { int i; for (i = 0; i < 32; i++) { syscall(__NR_setsockopt, /*fd=*/r[3], /*level=*/0, /*optname=*/0x2a, /*optval=*/0x20000180ul, /*optlen=*/0x88ul); } } res = syscall(__NR_socket, /*domain=*/0xaul, /*type=*/3ul, /*proto=*/2); { int i; for (i = 0; i < 32; i++) { syscall(__NR_socket, /*domain=*/0xaul, /*type=*/3ul, /*proto=*/2); } } if (res != -1) r[4] = res; res = syscall(__NR_socket, /*domain=*/0x10ul, /*type=*/3ul, /*proto=*/0xc); if (res != -1) r[5] = res; syscall(__NR_sendmsg, /*fd=*/r[5], /*msg=*/0ul, /*f=*/0ul); { int i; for (i = 0; i < 32; i++) { syscall(__NR_sendmsg, /*fd=*/r[5], /*msg=*/0ul, /*f=*/0ul); } } *(uint64_t*)0x20000380 = 0; *(uint32_t*)0x20000388 = 0; *(uint64_t*)0x20000390 = 0x20000300; *(uint64_t*)0x20000300 = 0x200035c0; memcpy( (void*)0x200035c0, "\x8c\x11\x00\x00\x04\x04\x01\x02\x28\xbd\x70\x00\xfd\xdb\xdf\x25\x02\x00" "\x00\x09\x04\x10\x12\x80\x27\xf0\x82\x50\x52\x44\x53\x8f\x13\x3b\x6e\xb4" "\x9d\xc2\x3f\xed\xe6\xb9\x76\x6f\xdc\xdf\x8b\xd8\x5b\x43\xf6\x83\xfe\x09" "\x51\x3d\x55\x5f\xcc\xbd\x0b\x0d\x3d\x53\x04\x60\x24\x86\x24\x9e\x3b\xdf" "\x32\x55\x61\x44\x97\x75\x88\x3e\xee\xd2\x7b\xc2\xe2\x9b\x4f\x85\x5b\xe0" "\xd0\x96\xc2\x0e\x08\x91\xe2\x3b\xc6\xea\xf7\x14\x6a\x58\x51\x9b\x8e\x91" "\x20\xb9\x3d\x67\xba\xa7\x76\x22\xfc\x23\x93\x01\x70\xe5\x8d\x67\xca\xd0" "\x67\x6c\x17\x36\xef\x83\xa0\x04\x16\x8f\xdc\xa7\x38\x0b\x5e\x52\xb6\x81" "\x7c\xe5\xd5\xee\x6c\x23\xb5\x26\xa6\x3e\xf8\x14\xf7\xd5\x39\x54\x8c\xff" "\x0a\x89\x28\x0d\x2f\x02\xa7\xc4\x9e\x50\x21\xa3\x93\xde\x8c\xc1\x27\x53" "\xb4\xa2\x8f\x1a\xac\xc2\x21\xfd\x0a\x59\x65\x1b\xf9\x96\x98\x43\x18\x04" "\xb7\x54\x39\x2d\x29\xf1\x8a\xa0\x46\x62\x8d\x93\x3e\x52\x9d\xd9\x7e\x19" "\xb5\xb4\xa8\xf8\x79\x1f\x35\x8f\x7b\x9b\xe5\xf2\x82\xfd\x18\x29\xc1\x07" "\x01\x1c\x82\x70\xbe\xa1\x54\x76\x02\x1b\x53\xe6\x5d\xfe\xc3\x24\x10\x0b" "\x00\xbf\xcf\x97\xe0\xf7\xbd\x46\xc5\x2f\x07\x23\xea\x7d\xfb\xc7\x85\xd4" "\x5f\x43\xa4\x30\x45\xb7\xea\x23\x1b\xe2\x58\x3e\x61\x31\xe7\x33\x5e\x3a" "\xe1\xd3\xb9\xfd\xf3\x46\x10\xf4\xba\x88\xc9\x2b\x86\x11\xc0\x5b\x6e\x3f" "\x56\x22\x2c\x37\xb9\x23\x59\xfe\x6a\xe8\x2e\x98\x3f\xbe\xc2\x9a\xb7\xd2" "\xf5\x27\xca\x7e\xc5\xae\xf4\xa4\x7c\xc8\x52\x7f\x42\x4e\xab\x64\xcc\x59" "\xcb\x91\xc1\x5c\xfa\xc7\x7e\xb4\xde\x89\xa4\xa6\x84\x00\x56\x87\x79\x31" "\xa3\xae\xbb\x5d\x29\x18\x4e\x1d\x96\x85\x53\x67\x2a\x17\xba\xad\x14\x07" "\x73\x8d\x2e\x5f\x07\x02\x67\xad\xd5\x24\x7c\x4b\x34\x83\x47\x51\xab\x84" "\x3b\x86\x60\x87\x2d\x0b\x74\x5d\xed\x23\x35\xfb\xc8\x78\xf3\x4c\x14\xee" "\x87\xc3\x06\xf7\x0e\x55\x3b\xa4\xb7\x1a\xad\x87\x69\x11\x37\x4e\x62\xf5" "\x74\x29\x24\x26\x87\x6c\xc8\x69\x62\x62\x0e\x38\xf2\xcc\xa3\xb8\x60\x26" "\x64\x2b\xd2\xe0\x73\x63\x92\x30\xc8\x2d\x50\xac\x33\x43\x17\x36\xe1\x8a" "\xf5\xbf\x98\xed\xe4\xc3\xee\x43\x10\x9b\x52\x22\xe4\x74\xcd\x8f\x84\x61" "\xad\xcd\x0e\x79\xd5\x2a\x63\x51\x71\x5a\xeb\x85\x8c\x08\xc6\xa2\xb3\xd3" "\x9e\xcf\xf4\x21\x58\x34\x85\x16\x34\x0b\x9f\x23\xf2\xdc\xac\x00\xe9\x6d" "\xf3\x81\xb5\x25\xb7\x6e\x02\x74\x26\xa4\x2f\x04\xb2\x98\x28\x31\x02\xd6" "\x64\x5d\x37\xe4\xed\x5c\xb9\x2e\x62\x59\xfe\x87\x3f\x41\x3c\x24\xc3\x96" "\xcd\x91\x4f\x85\x14\xcd\xd0\xb2\x72\x15\x8c\x1f\xf0\x2f\x71\xed\xe3\x34" "\x37\x32\xc9\x44\xa4\x77\x1c\x7e\xee\xde\xd5\x63\xdb\x2d\x2a\x47\x24\x9f" "\xee\x8a\xbd\xa4\xdd\xd5\xc3\x78\x2d\xf0\xe1\xf2\xb8\xf9\x70\x78\x7c\xa9" "\x22\x67\x3f\xaa\x88\xb0\xa7\x5c\x4b\x2f\xdd\xf0\xff\xb3\xce\x29\x2b\x73" "\x2d\xa1\x21\x25\xfe\x0e\xa2\x7c\xa7\x61\x58\x05\x3a\xf1\x29\x6a\x04\xa1" "\x67\x8a\x76\x4f\x6d\xba\x37\x62\x45\x5d\x30\xd4\x2e\xcd\x88\x8a\xe2\x13" "\x0f\xb6\x91\x78\xda\x64\xe8\x52\x92\x98\xfc\x28\x02\x68\x50\x29\xbd\x8a" "\xc2\x9d\x2d\x76\x95\x81\xba\xf0\xf0\x8a\x2a\x13\xfb\x7d\x1d\x2c\x1f\x40" "\xe0\x45\x31\x3a\x13\x1b\x3a\xf2\xc4\x1a\x05\xf0\xf3\x2f\xf1\x30\x34\x5d" "\x60\xd6\x48\x61\x4e\x65\xe1\xe3\x49\x20\x98\x93\xfd\xb8\x19\x4b\x79\x07" "\xba\x81\x8f\x0c\x4f\x75\x95\x1d\xcf\x4d\x95\xc7\x1d\xce\x08\xba\x62\x39" "\xb3\x39\x88\x54\x0b\x06\x8d\xcc\xff\x9c\xa5\xfe\x59\xf6\x0e\xb4\x16\xf5" "\xa5\x5b\x98\x3d\x1f\x16\xc5\xeb\x12\x12\xd8\x5c\x5e\x54\xc5\x81\xf7\x59" "\xc3\x0a\x6a\xfd\xda\x1b\x41\xb0\x05\x9b\xb8\x3f\xa8\xe6\x59\xec\xc6\x52" "\x22\x8c\x76\xaa\xbf\xc5\x77\x2c\xae\x56\x08\xe1\x73\xb4\x3c\xe7\x3a\xb6" "\x43\xf9\x26\x49\x2d\x35\x78\x97\xca\xe8\xdc\x33\x1c\x8d\x3c\x73\x9f\x2f" "\x8e\x37\xaa\x3a\x4e\x1d\x2b\x02\x75\xe0\xa2\xff\xea\xd5\x23\xab\xc4\x0a" "\x3f\xe2\xe6\xb4\xb9\xc5\xc7\xc7\x53\xbe\x3f\xb2\xc4\x41\x35\x5d\x29\xb5" "\x2f\x67\xcd\x3e\x4a\x98\xe9\xe9\xe1\x8e\x8f\xa9\x69\xbe\xc3\xb9\xb1\xc2" "\x70\x3c\x67\xe7\x2a\xeb\x50\x85\x1f\x63\xd7\x16\xa0\xaf\x27\x66\x28\xe2" "\x8d\x5e\x9f\xd1\x73\xa5\xe8\xac\x79\xfa\xfd\xfd\x30\x25\xfb\xf9\x4c\x4e" "\x38\xd7\xb7\x8b\x7f\xe4\xf7\x1d\xb3\x93\xb6\x5e\xf2\xc7\xba\xc3\xc4\x4b" "\xf0\x3b\x3e\xa1\x27\xd2\x1c\x1a\x82\x11\x78\x6a\xbb\xcd\xc2\xb6\xdb\x47" "\x44\x6e\x5d\x76\xca\x85\xa1\x3e\x33\xf5\x9f\xd9\x22\x78\x7e\x22\x8e\xf9" "\x32\x9b\x0b\x35\xfb\xc5\xac\x83\xe8\x28\x35\xf4\xa4\xd3\x1a\x5e\x3f\x46" "\x56\xed\x65\xa8\xa5\xc5\x07\x17\xee\x88\x6a\xe3\x3b\x1d\x8a\x23\xc6\x16" "\x0f\x9d\xde\x6b\x53\x35\xdb\x75\x18\xc5\x1a\x62\x92\x1a\x27\x7d\x1c\x95" "\x21\xdf\x5f\x08\xbd\xa6\x75\x11\xe2\x68\xa4\x73\x39\x3d\x87\x31\x34\x38" "\xe5\x8a\x8a\x8c\x38\xbb\xa9\x0e\x5f\x59\xe7\xe6\x25\xae\xff\x41\xd3\x3d" "\xaf\xb4\x95\x33\x27\xc8\xcd\xa4\x39\x45\xbc\x32\xb8\xb5\xae\x81\x2d\x11" "\x11\x9d\x07\xb5\x53\x12\xce\xb9\x3e\x3f\x3a\x7e\xbc\x7b\x02\x10\xaf\x94" "\xa7\x25\x46\xc2\x43\x4a\x5d\x40\xfa\xd8\x03\x5e\x4d\x95\x80\xa0\xfb\xda" "\x19\xc7\x7f\x65\x86\x15\xb8\x6c\x5d\xef\xf8\x55\x95\xa4\x10\xfc\x25\x23" "\xb9\xe2\xe4\x92\xc1\xcc\xc5\x89\xda\x26\x0e\xa4\x25\x5d\x3b\xb9\x44\xd8" "\x86\x81\x75\xe2\x51\xf4\x07\x1b\x1a\xc2\x72\x02\x97\x0f\x49\x6a\xf4\xcc" "\xdd\x44\x61\x7c\x3c\x74\x34\x4f\xd2\x12\xf4\x9d\x9a\xec\x87\xee\xca\xd9" "\xce\x0f\xc7\x66\xc7\x99\x7e\x37\xdd\x68\x95\x30\x3d\xd9\xc6\x32\x72\x42" "\x74\x6b\xa8\x3b\x6a\x1c\x91\x27\x85\xeb\x43\xad\x84\xa5\x0c\xdd\xf2\xc1" "\xc4\x7d\xc3\xec\xcf\xb6\x7b\x04\x76\xcb\xa8\x37\x97\x06\x64\x99\xc8\xeb" "\xdc\xc6\x5b\x77\xf9\x3b\x09\x29\x93\x35\x0d\xcb\x3c\x44\xab\x36\x4c\xf4" "\xc3\x28\x99\xe9\x86\x61\xd0\xa7\x2d\x57\x40\xab\x12\x2c\x81\x69\x93\x20" "\xa5\x80\x07\x00\x27\x08\x7f\x4e\xb3\xf9\xa1\x38\x05\xfa\xa7\xc3\x54\x3b" "\x99\x57\x87\xe6\xf9\x64\xf9\xb1\xd5\x67\x42\x17\xc6\x04\x49\x82\x9e\xd6" "\x97\x16\x1c\x2e\xaa\x22\x1f\x36\x74\xc2\x59\xd8\x60\xa1\x68\xb5\xba\x4e" "\xb6\x69\x5b\x7e\x01\x2b\xfb\x45\x97\xd6\x5e\x9b\x7e\x6f\x6c\x41\x09\xba" "\x88\xbb\xdd\x11\x39\xad\xb3\xac\x08\xdc\x6e\x55\x35\xe0\xd9\x55\xb8\x21" "\x27\x75\x80\xba\x37\x1f\x1f\xa2\x9e\x23\xc1\xf1\x31\xc7\x69\xb8\x93\x5a" "\xbb\x3c\x8b\x1e\x62\x37\xa5\x2f\xfc\x11\x58\x24\x42\x1b\xe1\x0c\x4f\xd0" "\xc1\x9d\x4f\x68\x39\xec\x74\x34\x80\x02\x71\x14\xdc\x51\x9e\x4b\xa7\x69" "\xee\xbd\x70\x51\x69\x51\x15\x6e\x82\x43\x8e\xba\xf2\x00\x39\x42\x4a\x97" "\x87\x1f\xce\x52\x24\x04\x7b\x27\x4a\x58\xfa\x97\x1c\x33\x80\x80\xa0\x40" "\xb3\x91\xa0\x21\xce\x07\x19\x8c\xda\xb3\x95\x07\x1e\xc5\x97\x0b\x17\x11" "\xca\x5b\x2c\x55\xf9\x38\xe5\xd4\xdb\x54\xe0\x36\xad\xb4\xea\xec\x8d\x36" "\xc8\x43\x46\xe3\xe0\x9b\x02\x70\x66\xa3\x6a\x9e\xae\x36\x95\x36\xd8\xd7" "\x3e\xb0\x98\x55\xc0\x59\x75\x2a\x61\x05\x23\xdf\x83\x45\xa3\xf4\xd0\x2a" "\x1a\x44\x12\x76\xbb\x4f\x48\x78\x29\x8b\x6b\xf1\xa3\x30\xe7\x51\xcd\xa8" "\x3b\xaf\x3a\x27\x92\x80\x6a\xe2\xd6\x41\x04\x8e\x40\xe6\xa6\x63\x71\x72" "\x48\xf6\x7a\xcc\x4c\x27\xbf\x1c\xdc\x77\xd3\x64\x60\x74\xb3\xd2\x39\x45" "\x48\x4a\x59\x80\x3e\x51\x22\x4e\xf6\x39\x94\xb4\x09\xb0\xc6\xc6\x4a\x0d" "\x7a\xc1\x65\xa4\xf1\xc5\x62\x3d\x48\x86\x68\x5d\xec\x6d\x39\x5d\xda\xbf" "\x77\xe5\x2f\xa1\x81\xf8\x74\xcb\xc7\xdb\x29\x24\x72\x8f\x34\x94\xe8\x97" "\xfc\x2d\x33\x0a\xde\x24\x2d\x71\x5c\xa6\xd3\xd3\x5b\xa7\x7c\xbb\x53\xa1" "\x74\x3c\x69\x1a\x96\x72\x05\x88\xe6\xa5\x70\xd0\x4f\x08\xd8\xd7\x4f\x09" "\xd5\x1c\x75\xfb\xe2\x0b\x9b\xf2\xa2\x22\xb5\xae\x13\x83\xb1\xe3\x06\xf1" "\x5d\x75\x22\x2d\xfc\xab\xd0\x26\xcc\x18\x7f\x31\xd8\x36\xdf\x39\xc3\x7d" "\x8d\xa8\xd7\x82\xf7\xd1\xb1\x72\x9a\xfb\xc7\x46\x33\x13\x5e\x9c\x99\x06" "\x96\x58\xad\x11\x81\x99\x76\x64\xab\x29\x88\x00\xd6\x4f\xe9\x02\x58\x58" "\xd7\xdd\x9a\xa5\x81\x3a\xfa\x1f\x96\x21\x8d\x1f\x2d\x67\xb8\x22\x96\x3c" "\xe0\x95\x51\xe3\x05\xb8\xe5\x77\xab\x4c\xdb\x5a\x70\x48\xe2\x10\xb2\xd2" "\xab\x0c\x26\x10\xc2\x8c\xf3\x5a\x45\xfc\x19\x2b\xde\xf1\xef\x4b\xab\x6b" "\x8d\x4e\x62\xf7\xac\xa7\xa7\xf9\x28\x0f\xaa\x9b\xcd\xdf\x5d\x4b\x6c\x51" "\x6d\x5f\xd0\xc0\x9b\x7e\xd5\x16\x25\x77\xbf\xc8\x02\xc8\x0b\x04\xd3\x76" "\x1a\xec\x76\xbe\xc2\x23\x04\xe3\x2d\x23\xb5\xa4\x63\xaf\x2a\xbc\xec\xad" "\x0d\x43\x6f\xdb\x7f\x66\x4c\x7b\x96\xcd\x85\x43\x2e\x57\xdc\xa2\x9a\x4c" "\x27\x1a\xb5\xa8\x19\xa6\x4f\x03\xf2\xe4\xa6\xdb\xa6\x0e\xde\xf4\x6d\x60" "\x66\x5a\x0e\x2a\xde\xd1\xd9\x87\xf2\x1b\x8f\x1c\x17\xc3\x7b\xf9\x76\x2e" "\xf8\xe2\x48\xd2\x95\x76\x21\xa5\x28\x77\xf3\xfa\x7d\x6b\xe9\x78\xd5\x26" "\xde\x73\xd7\xe8\xff\xc2\xf3\xf7\x14\x6e\x3d\xa0\xf4\x26\x39\xaa\x86\xda" "\x02\x4a\x4e\x6c\xf2\xd3\x97\x61\x7b\x07\x33\xac\xdc\x3e\x6a\xf0\x95\xeb" "\x91\xba\x9d\x65\x52\x91\x82\x31\x8b\xa9\x7b\x85\x3a\xa6\xa7\x58\xf1\x16" "\x58\xe2\x1f\x2b\xcb\x99\x73\x29\x98\x1a\x2b\x2d\x56\x82\x83\xbe\x32\xc0" "\xd3\x3e\x36\x92\x6a\x05\x35\xc3\xb5\x58\x70\xfa\xfa\x4a\x9e\x26\xb7\x23" "\xef\xcc\x8c\x58\xdf\x0c\xb9\x5e\x8c\x98\x6a\x3d\x8a\x7c\xdc\x9d\xb9\x22" "\x74\xac\xaa\x62\xd9\xe0\x9d\xf8\xb9\x1f\xba\xf6\xe3\x63\x7a\x3e\x9a\x07" "\x14\x2e\xf9\xf6\x65\x20\xa8\xdf\xc0\x73\xdb\xe6\x3d\xcd\xbc\x7e\x13\xbd" "\x52\xc4\xf7\x68\x01\xf7\xff\xca\x6d\x3e\x04\x40\x20\x75\xf7\xfa\x35\x56" "\x83\x52\x26\x49\xb3\xb1\xf7\x48\x32\xbf\x03\xb3\xad\x88\x0b\x49\xac\xec" "\xa0\xd5\xe7\x80\x90\xe1\x5d\x70\x59\x99\x1a\x05\xfa\xf3\x54\xfb\x05\xeb" "\x15\x61\xd7\x6f\x48\x92\xbb\x03\xac\xef\x6f\x66\xf8\x9f\x87\x40\xce\x98" "\xf2\xe2\xc4\x51\xa6\x21\x99\xbc\xd7\x36\x55\xc0\x8c\xe2\x8b\xe0\x36\x70" "\x74\xd8\x43\x3c\x9b\x12\xb8\x1e\xb7\x80\xea\x64\x8d\xd8\x13\x91\x8f\xc8" "\x21\x35\x4a\xd5\x59\x1b\x36\xf6\xea\xd5\x77\x62\xbd\x3b\x44\xd6\xeb\x28" "\xca\xf8\x75\xd5\xad\x6b\x9c\x08\x73\xb9\xbd\x5e\x7c\xb8\x61\x59\xca\x2a" "\x70\xe9\x18\x4b\xd0\xb7\xc9\xdf\x41\xd0\xbf\x56\xc7\xaa\x92\x0c\xdf\xeb" "\xe8\x09\xb7\x59\x96\xc7\x8a\xc4\x21\xb7\xc5\x74\x41\x78\xb3\x6e\xb0\x85" "\x7d\x1e\x87\xb4\x89\xf3\xff\x27\x41\xef\xe5\xec\xbb\x9f\x6a\xbf\x9d\x19" "\x30\x38\x49\xba\xe4\xa6\x62\xb9\x0d\x0e\x9a\x04\x61\x45\x16\x6f\x45\x80" "\x32\x53\x15\x92\xee\x42\x07\xf2\x8f\x6b\x42\x93\x89\xc8\xb2\xad\xaa\xd9" "\x48\x89\x48\x41\xc5\x29\x94\xb1\x17\x7d\x31\x7c\x9c\x47\x9e\xbb\xe5\x71" "\x10\x4c\x7a\xaf\x29\xc0\x3c\x98\x34\x06\x7b\x59\x7a\x71\x3e\xea\xde\x3e" "\x18\x8a\x21\xfd\xee\x80\x69\xd8\x46\xe8\xcd\xc5\x97\xdc\x1d\xbb\x1a\x79" "\x35\x30\x76\x19\x73\xb3\x68\xe0\x19\xaf\x6b\xc9\xfc\xe4\x48\xff\x6c\x10" "\x02\x91\x64\x4c\x21\xc2\xda\x00\x29\x40\x81\x0c\x6c\xc5\x12\x21\x04\x17" "\x88\xf8\x45\x5b\x5e\xf0\x9a\x27\x84\xab\x4e\x57\x5a\xfd\xb4\x5a\x97\x34" "\xe8\x75\x91\x1a\xf2\x6f\xed\x74\x01\xf7\x08\x43\x88\xc2\x1f\x5d\xa3\x26" "\x5f\x0b\x87\x9a\x4f\x03\x04\x9e\xdb\xc3\x23\x8a\xf7\x04\x50\x04\x97\xd5" "\xb5\x93\xab\x4e\x59\x00\x7a\xbd\xcb\x61\xb2\xd7\x82\x85\xa6\x2c\x17\xc3" "\x3d\x37\xa4\x60\xc6\xfa\x18\xdb\xc3\x79\xab\x0d\x05\xe5\x79\x31\x60\x7b" "\x00\x1a\x2e\x63\xcd\xbf\x26\x77\xc5\xa7\xd4\xaf\x31\x25\xb0\xd5\xd4\x70" "\xdd\xb9\x72\xdb\x25\x46\x76\xad\x8a\x05\xbe\x97\xe6\xbe\x56\x89\x4a\x48" "\xe4\xd2\x2a\xa6\x96\x7b\xaf\x06\x5e\xe8\x9f\x16\x16\xc4\x5f\x92\x88\x69" "\x82\x90\x10\x45\xa6\x86\x5a\xd8\xcd\x9b\x64\x94\xe9\x9d\x4e\xaf\xb2\x09" "\x43\xdd\xe2\xad\x5b\x49\x3e\xcb\x81\x71\xe3\x25\x56\xd3\x4e\x27\x2d\x05" "\x3e\x2d\x0a\xd3\x33\xc4\xc6\xff\xd0\x3b\x0a\x08\x94\x89\x5f\xbc\x73\x69" "\x55\x58\x9b\xa9\x66\xa5\xdd\x80\x43\xbf\x57\x67\xc7\x4f\x98\xb0\x04\xa8" "\xf0\x14\x01\xcd\xe2\x92\xf7\xe9\xca\x07\xff\xfe\x0c\xbd\x91\x24\x34\xfc" "\xc7\xd3\xd7\xc1\xc8\xe0\x56\xfd\x30\x45\x7e\xd2\xd1\xe0\x76\xa6\x47\x22" "\xe0\x0a\x09\xbb\xb0\x1e\x42\x05\x25\x54\x3f\xc4\x48\x96\x3a\x66\xbc\x78" "\x42\xad\xf6\x48\x6c\x21\x41\x9b\xbd\x57\xa5\x98\x68\xa0\x1c\x52\x66\xb6" "\x51\x96\xff\x55\xb4\x96\x5a\x12\xe4\xe4\x6e\x37\x4e\x8c\x95\xae\x0b\xd3" "\x0e\x9a\x6f\x91\xcb\x8a\x4e\xfd\x8c\x10\xe8\x87\xb0\xc3\x60\xde\x85\xe1" "\xe6\xf4\x46\x0e\x2d\xc6\x54\x54\xf4\xcf\xb8\xd0\x4c\xc8\x39\x59\xf4\xee" "\xbf\xd2\xc7\xe9\x27\x13\xc7\xbe\x9a\xa0\x1c\x91\x11\x9d\xf0\xca\x36\x1f" "\x53\xfa\x37\xd7\x51\x83\x24\x5a\xa1\xb2\x58\xfb\x18\x48\x87\x75\x61\x4c" "\xe8\x8d\x8f\x94\x39\x5c\x40\xb3\x1f\x89\x3f\x19\xcd\xdf\xcc\x31\x94\xb0" "\xa5\x80\x3f\xcf\xa7\xa1\x08\x53\xb6\xf3\xdd\x4a\x11\x6a\x0f\x8c\x9a\x0c" "\xfe\x24\x72\xf5\x4a\xce\xa3\x22\x3e\xbc\x32\x98\xc6\xd5\x7d\x01\xe8\x1f" "\x66\x7c\xe9\x84\xad\xa1\x03\x22\xf4\xd1\xd7\x60\x5c\xcc\x2e\x0e\x2d\xe4" "\xee\xb8\xca\x5f\xe4\xd0\x48\x74\x3c\x79\x6d\x80\xc1\x87\x27\x1b\x3e\xe8" "\xaf\x72\x90\x96\x48\x81\x96\x21\x45\x47\x40\xe1\xd9\x88\x9f\x10\x09\x7c" "\x57\x66\x62\xfd\x23\x9c\xd1\x44\xd8\x0e\x58\x10\x88\x31\x51\x22\x4f\x80" "\x67\x3b\xef\x57\x3e\x1a\x54\x52\xa8\x09\xab\xda\x1e\xc6\x5c\x1a\x21\x3b" "\xd0\xdb\xd3\xf7\x87\x3a\x38\x4d\x66\xe0\xc0\x0a\xc6\x4f\x10\xc2\x45\x64" "\x26\xf8\x10\x77\xb3\x71\xa2\xe6\x92\x80\x86\x9c\x95\xbe\x23\x8a\x9e\x0b" "\xd2\xcf\x8f\x98\x7f\xcd\x1a\x4b\x73\x78\xcd\xff\x5e\xa3\x67\xc4\xa5\x09" "\x62\x74\xb4\x27\x4a\xdb\x5a\xc7\x6e\x96\xfd\xf9\x21\xea\x19\x14\x0f\x82" "\xa1\x5f\xe1\x0f\x34\xc8\x1b\x99\x8c\x67\x75\xf9\xe6\x41\xc9\x92\x24\x97" "\x4a\x8f\x15\x44\x7d\x15\x40\x81\x11\x7b\x19\x32\xd5\x05\x07\xa3\xb8\xe2" "\x39\x23\x93\x55\xf1\x3f\x1b\xd9\x45\x44\xb7\x44\xd9\xb7\x07\x9f\xe3\xd7" "\x79\x66\xeb\xc4\x51\xb2\x1f\x31\x61\x90\xb7\xb6\x5f\xf4\xad\x79\x2e\x26" "\x31\x0f\x6d\x71\xe2\xf2\xa6\x29\x26\xae\x80\xce\xb7\x1a\x81\xb5\xca\xd5" "\x86\xb3\xe8\xc2\x9d\x1e\x03\x50\xb3\x1c\x54\x9f\x37\x32\xb3\xf4\x39\x4b" "\xc1\x0f\x97\x2c\x24\xbd\x33\xdf\xc6\xb3\xf7\xc9\x41\xb4\x1a\xce\xa8\x53" "\x55\xa3\x92\x79\xbd\x88\xf7\xcb\x8f\x9f\xfe\x86\xc2\x52\x53\xeb\x2d\xbd" "\x97\xed\xef\x0e\x5b\x2f\xad\x5f\x45\xf5\xb4\xcd\xb1\xc2\x72\xea\xcd\x45" "\x96\x63\x54\x25\x02\xc7\x92\x0d\x39\x20\xf3\x8a\x18\x9c\xed\x6a\xde\xac" "\x6b\x8e\x4b\xe8\xad\xd2\x7c\x95\xed\xa2\x79\xd6\x0e\xe9\x07\x29\x9a\x90" "\xde\xe8\x3a\xa0\x17\xde\x00\x1b\xc4\x97\x09\xd9\x49\x16\x63\x62\xf9\x76" "\x68\x22\xe5\x6a\xb8\x68\xdf\x7a\xc0\x3a\x97\x96\x29\x76\xb1\x96\x8b\x06" "\x1d\x96\xf4\x9d\xd6\x8e\x96\x8b\x8a\xac\x70\xa8\x74\x95\xd2\x36\x64\x30" "\xa4\xfc\x07\x92\xba\x32\xfa\x1b\xbb\xd0\x6e\xb5\xb8\xdd\x03\x2a\xa6\xca" "\x32\x51\x87\xc6\xb4\x20\xd4\x7c\x5e\x56\xff\x48\xdf\xb8\xa6\xdc\x8a\x35" "\xb3\x65\x33\x07\xe6\xbb\xdd\xe6\xb6\x5d\xd4\x77\x32\x6a\xc8\xd4\x5a\xbb" "\x3a\x13\xf4\x1d\x08\x01\x8c\x3f\xcc\xb0\x88\x51\x18\xc5\xdf\x49\x49\xd3" "\x29\x31\xd5\x05\x76\xd3\x4c\x01\x75\x7f\x10\xe6\x72\x9d\xaa\xa6\x03\xda" "\x40\x83\x7a\x26\xde\x26\x41\x2e\xbb\xe0\x83\x1b\x9d\x40\xa1\x7e\x03\xa8" "\xc9\x92\x94\x21\x53\x05\x53\xaf\xbb\xf3\x1a\xe9\x3c\xa7\x9a\x6f\x09\x04" "\x77\x5d\xa5\x62\xc2\xef\x27\x3c\x06\xbb\x55\x28\xff\xe0\x56\xd0\x49\x54" "\x2b\xe8\x07\x74\x2d\xd2\x92\x8b\x68\xc4\xfc\x23\x50\xa4\x07\x01\x21\xfa" "\x8c\x36\x11\x4e\xe1\xcc\x58\x6d\x9a\xbd\xeb\xdf\x02\xb2\xf2\x24\xb8\xbc" "\xb8\x70\x67\xd5\x20\x86\xbe\xc8\x9c\x0f\x0e\x22\x40\x5a\x06\x01\x20\x9b" "\x0c\xe2\xcf\x60\x5f\x23\x49\x09\x9e\xab\xa3\x1a\x87\x68\x8f\xd8\x49\xec" "\xf9\xe3\x05\x1a\x62\xa8\x21\xd9\x66\x27\x37\x03\x80\xb9\x4c\xd9\xac\xac" "\xe3\x8f\x98\xae\x6a\x25\x4b\x92\xf0\x7e\x8a\xc9\xb7\xef\xfd\x8b\x74\xd5" "\x33\x5d\x4a\xf5\xa5\x4d\xae\x5e\xc0\xe7\xad\xd9\x2c\xd7\xe4\x64\xed\x11" "\x50\xb9\x82\x4d\x06\xb2\x6c\xd9\xf9\x56\x35\xdd\x0c\x3e\x91\x8c\xd5\x8b" "\x64\xde\x18\x98\x31\x48\xd1\x7a\x70\xe4\x3f\xa3\xbb\x26\x41\xf0\x2f\x59" "\x4e\x2c\x1c\x46\xe6\xba\xa4\x7c\x7a\x00\x71\x54\x68\xa7\x46\xc1\x02\x48" "\xa1\x75\x07\xad\x8b\xc2\x1d\x67\xa5\xf3\x03\x71\xba\xeb\xc6\xcc\xec\x29" "\x24\xa4\x9b\x98\xc8\xd2\xff\x97\xbe\x65\x15\x84\x02\xb1\x46\x53\xad\xde" "\x6e\x1f\x73\xcc\xea\xf0\x1f\xc5\x68\x0b\xc0\xdf\x77\xcd\xaa\xb3\x84\x1e" "\x94\x44\x2a\xda\x0d\xad\x53\x28\x0a\x5b\x52\x74\xd5\x53\x0d\xcf\xfd\x8b" "\xaf\x24\xde\xbd\xa1\x5c\xa7\x9b\xa7\x2f\xdb\xe9\x93\xce\x8e\xeb\xa4\xa8" "\x82\x68\x85\x8d\x79\xbe\x2a\x8c\xc6\x3f\x05\x97\xea\x2e\x32\xbd\x15\xe9" "\xf4\xc8\x23\xb3\xe5\x91\x1c\x99\xe6\xd9\x22\x64\x92\x72\x92\xea\x74\x90" "\x42\xbc\x0c\x6b\x8d\xbb\x75\x58\xb9\x71\xbd\xd6\x5a\xd0\x31\xd7\x86\x2b" "\xbf\x54\x7b\xd3\x95\xc6\x29\xa1\xd8\x63\xd8\x47\xff\xf8\xbd\x19\xe1\x4c" "\x61\x40\xb7\x88\x82\x04\xa1\x24\xfb\x74\xc4\x93\xe4\xcf\xf0\x6f\xc7\xa8" "\x09\x5a\x0b\x28\x85\x4c\x7c\x1b\xe8\xbe\x7c\xbd\xc4\x21\x2d\x0b\x14\x00" "\x53\x06\xe2\x6c\x7e\x3e\x80\xbd\xe9\x9c\xc9\x9f\x94\x19\x68\x78\xc0\x91" "\x36\x69\xa7\x3e\x5c\xfc\x24\x15\x9b\x74\x02\x93\xe7\x14\xc5\x47\xdf\xa9" "\x6a\xd5\xa7\x29\x76\x21\x72\x7b\x5e\x35\xdd\x69\x5b\xa8\xc6\xa0\x90\xfa" "\x58\x0e\xd4\x0e\x67\xb3\xdc\x0f\x30\x55\x12\x05\x06\x8f\xea\x5c\x44\x1d" "\x50\x98\xd4\x2b\x21\x77\x55\x00\x58\xef\x9d\x0a\x23\xa8\x6e\xc1\x7d\x81" "\xff\xe6\x45\xe0\x75\x09\x4e\x81\xb0\x03\xc1\x64\x2f\x48\xd6\x8a\x78\xfb" "\x74\x81\x5b\xcd\x75\x72\x15\xca\xa8\xc5\xa2\xf2\x40\x74\x45\xab\xd5\x90" "\x6f\x61\x05\x4a\xa1\xff\x52\x40\x18\x1c\xfd\x64\x16\x8c\x87\xca\x71\x15" "\xd1\x89\xcb\x7b\xd5\x67\x0f\xba\x22\x86\xe5\xf1\x02\x04\x1a\x68\xd4\x04" "\xbe\xf0\xa9\xf8\xe8\x95\x74\xeb\x5c\xd4\x33\xca\x1a\x46\x1a\x64\x54\x11" "\xe4\x56\x18\xaf\xa8\xa7\xce\x83\xd1\xbd\x18\xe9\x82\xeb\xf7\x27\x93\xe6" "\xef\xc8\x3f\xfd\xaf\x27\x55\xc9\x63\x0f\xc7\xc2\x75\x34\x33\x00\x32\xf4" "\xc7\xae\x67\xc5\x10\xd0\xfb\x95\xa7\x80\x71\x21\xb7\x03\x2f\x06\x6c\xeb" "\xeb\x74\xd8\xca\x04\xb3\xac\xd2\xa8\xa9\x26\x1c\x6e\x51\xca\xf5\x1d\xd2" "\x3c\x1f\x15\xa3\x17\xf7\x08\x87\xff\x6e\x3f\xa1\x7a\x35\x2e\x2b\xf7\x4e" "\x92\xd2\xc8\xef\x16\xf0\x8f\xbe\x98\x87\xbf\x0a\x37\xd5\x81\x63\x79\xc8" "\x9b\x09\x9a\xd5\x15\x4a\x58\xe4\x65\xb3\xee\xe5\x60\xfc\x76\xec\x2f\x28" "\xef\x00\x82\xd1\xfc\xde\x2c\xf6\xdb\xbe\x55\x0b\xe1\xc0\xf9\xf4\x56\x30" "\xc5\xdc\x8c\x48\x8d\x5f\xd8\x1e\xa2\xda\x9b\xa4\x2a\x46\x63\x50\x80\x81" "\x05\x4d\x4f\x39\x64\x45\x01\xee\xc4\xa6\xf6\x75\x73\xea\x7b\xbd\x81\x48" "\xdf\x0d\x85\x8e\x26\x00\x00\x00\x00\x00\x00\x00\x56\xba\xd8\x1f\xf0\x1f" "\x5c\xba\x2b\x65\x79\x0c\xe9\x61\x77\x9f\x09\xa6\x98\x01\x1b\x64\xa2\xc1" "\x54\x1c\xef\x13\x15\xd1\x61\x70\x7f\x51\xad\x0b\x53\x49\xed\xee\x9f\x43" "\xbe\x06\xe3\xb4\x3f\x2b\x28\x35\x9e\xda\x1e\x39\x08\x00\x5b\x00\x00\x00" "\x00\x00\x69\x00\x6a\x80\x0c\x00\x27\x00\x3f\x00\x00\x00\x00\x00\x00\x00" "\x14\x00\x2a\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" "\x00\x01\x08\x00\x26\x00\xac\x14\x14\xaa\x91\xa8\xc4\x96\x77\xb2\xb4\xde" "\x62\xef\xe2\xde\x90\xbd\x92\x1b\xe5\x92\x04\xb0\x87\x39\x6c\x22\xf9\x37" "\x08\xaa\x69\x9b\x71\x74\xff\x82\x5d\x87\xa0\xbc\xe7\x6d\xa6\x4b\x43\x85" "\xc5\x71\xc1\xc0\x96\x1f\xb2\x7f\x5f\xb3\xa9\x17\x2a\xa3\x69\x73\x6d\x00" "\x00\x00\xa7\x00\x18\x80\x08\x00\x3c\x00\xac\x14\x14\x35\x04\x00\x15\x00" "\x05\x4e\x93\x8e\x45\xaf\x15\x9b\x6e\xc6\x10\xca\x9b\xae\xa8\x2c\x20\xa3" "\x1a\x8a\x0f\x5e\x5d\x8c\x24\x8f\x83\xc8\x27\x89\x78\x5a\x35\x4f\xba\x69" "\x53\x82\x31\x7f\x53\x4e\xc2\x43\x37\xd1\x2a\x50\x13\xe7\xf4\xff\x87\x10" "\x97\x3a\x96\xcf\x1f\xef\x68\x06\x8a\x66\xeb\xb5\x52\xb3\x38\xca\xfb\x95" "\x8f\x14\xe5\x7e\x1a\x81\xa1\x77\x5c\x51\xd0\x56\x86\xf5\xf4\xe9\x0a\xa7" "\xeb\x63\xeb\xd6\x5d\xe1\x86\x07\x53\x75\xbf\xb6\xb2\x8b\x0f\x6f\x60\x00" "\x27\xd0\xfd\x39\x78\x3f\xa2\x4d\xd3\xcb\x4a\x09\xa5\xb8\xe2\xf7\xcf\xad" "\x18\x45\xed\x03\x0c\x5e\x3a\x1f\xf9\x50\xed\x78\x6b\xea\x66\xf2\xbd\x08" "\x00\x83\x00", 4485); *(uint32_t*)0x20004745 = -1; memcpy((void*)0x20004749, "\x00\x8c\xd4", 3); *(uint64_t*)0x20000308 = 0x118c; *(uint64_t*)0x20000398 = 1; *(uint64_t*)0x200003a0 = 0; *(uint64_t*)0x200003a8 = 0; *(uint32_t*)0x200003b0 = 0x11; syscall(__NR_sendmsg, /*fd=*/r[4], /*msg=*/0x20000380ul, /*f=*/0x80ul); { int i; for (i = 0; i < 64; i++) { syscall(__NR_sendmsg, /*fd=*/r[4], /*msg=*/0x20000380ul, /*f=*/0x80ul); } } sprintf((char*)0x20000200, "0x%016llx", (long long)0); syscall(__NR_write, /*fd=*/-1, /*buf=*/0x20000200ul, /*len=*/0xf000ul); res = syscall(__NR_socket, /*domain=*/0x10ul, /*type=*/3ul, /*proto=*/0); if (res != -1) r[6] = res; res = syscall(__NR_socket, /*domain=*/0x10ul, /*type=*/3ul, /*proto=*/0); if (res != -1) r[7] = res; memcpy((void*)0x200001c0, "batadv_slave_1\000\000", 16); res = syscall(__NR_ioctl, /*fd=*/r[7], /*cmd=*/0x8933, /*arg=*/0x200001c0ul); if (res != -1) r[8] = *(uint32_t*)0x200001d0; *(uint64_t*)0x20000280 = 0; *(uint32_t*)0x20000288 = 0; *(uint64_t*)0x20000290 = 0x20000140; *(uint64_t*)0x20000140 = 0x200005c0; *(uint32_t*)0x200005c0 = 0x80; *(uint16_t*)0x200005c4 = 0x10; *(uint16_t*)0x200005c6 = 0x421; *(uint32_t*)0x200005c8 = 0; *(uint32_t*)0x200005cc = 0x25dfdbfe; *(uint8_t*)0x200005d0 = 0; *(uint8_t*)0x200005d1 = 0; *(uint16_t*)0x200005d2 = 0; *(uint32_t*)0x200005d4 = 0; *(uint32_t*)0x200005d8 = 0x88a8ffad; *(uint32_t*)0x200005dc = 0x60e1; *(uint16_t*)0x200005e0 = 0x30; STORE_BY_BITMASK(uint16_t, , 0x200005e2, 0x12, 0, 14); STORE_BY_BITMASK(uint16_t, , 0x200005e3, 0, 6, 1); STORE_BY_BITMASK(uint16_t, , 0x200005e3, 1, 7, 1); *(uint16_t*)0x200005e4 = 8; *(uint16_t*)0x200005e6 = 1; memcpy((void*)0x200005e8, "gre\000", 4); *(uint16_t*)0x200005ec = 0x24; STORE_BY_BITMASK(uint16_t, , 0x200005ee, 2, 0, 14); STORE_BY_BITMASK(uint16_t, , 0x200005ef, 0, 6, 1); STORE_BY_BITMASK(uint16_t, , 0x200005ef, 1, 7, 1); *(uint16_t*)0x200005f0 = 5; *(uint16_t*)0x200005f2 = 0x16; *(uint8_t*)0x200005f4 = 2; *(uint16_t*)0x200005f8 = 5; *(uint16_t*)0x200005fa = 8; *(uint8_t*)0x200005fc = 0x3f; *(uint16_t*)0x20000600 = 8; *(uint16_t*)0x20000602 = 0x14; *(uint32_t*)0x20000604 = 0x7d; *(uint16_t*)0x20000608 = 4; *(uint16_t*)0x2000060a = 0x12; *(uint16_t*)0x2000060c = 4; *(uint16_t*)0x2000060e = 0x12; *(uint16_t*)0x20000610 = 8; *(uint16_t*)0x20000612 = 5; *(uint32_t*)0x20000614 = 0; *(uint16_t*)0x20000618 = 8; *(uint16_t*)0x2000061a = 0xa; *(uint32_t*)0x2000061c = r[8]; *(uint16_t*)0x20000620 = 0xa; *(uint16_t*)0x20000622 = 1; memcpy((void*)0x20000624, "\x6e\x47\x12\x9f\xa9\xb9", 6); *(uint16_t*)0x2000062c = 8; *(uint16_t*)0x2000062e = 0x1b; *(uint32_t*)0x20000630 = 0x7fff; *(uint16_t*)0x20000634 = 0xa; *(uint16_t*)0x20000636 = 1; memset((void*)0x20000638, 170, 5); *(uint8_t*)0x2000063d = 0xbb; *(uint64_t*)0x20000148 = 0x80; *(uint64_t*)0x20000298 = 1; *(uint64_t*)0x200002a0 = 0; *(uint64_t*)0x200002a8 = 0; *(uint32_t*)0x200002b0 = 0x404c841; syscall(__NR_sendmsg, /*fd=*/r[6], /*msg=*/0x20000280ul, /*f=*/0x8002ul); } int main(void) { syscall(__NR_mmap, /*addr=*/0x1ffff000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=*/0x32ul, /*fd=*/-1, /*offset=*/0ul); syscall(__NR_mmap, /*addr=*/0x20000000ul, /*len=*/0x1000000ul, /*prot=*/7ul, /*flags=*/0x32ul, /*fd=*/-1, /*offset=*/0ul); syscall(__NR_mmap, /*addr=*/0x21000000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=*/0x32ul, /*fd=*/-1, /*offset=*/0ul); setup_sysctl(); setup_cgroups(); setup_swap(); for (procid = 0; procid < 6; procid++) { if (fork() == 0) { use_temporary_dir(); do_sandbox_none(); } } sleep(1000000); return 0; }