|
// autogenerated by syzkaller (https://github.com/google/syzkaller)
|
|
|
|
#define _GNU_SOURCE
|
|
|
|
#include <arpa/inet.h>
|
|
#include <dirent.h>
|
|
#include <endian.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <net/if.h>
|
|
#include <net/if_arp.h>
|
|
#include <netinet/in.h>
|
|
#include <sched.h>
|
|
#include <signal.h>
|
|
#include <stdarg.h>
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/mount.h>
|
|
#include <sys/prctl.h>
|
|
#include <sys/resource.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/syscall.h>
|
|
#include <sys/time.h>
|
|
#include <sys/types.h>
|
|
#include <sys/uio.h>
|
|
#include <sys/wait.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
|
|
#include <linux/capability.h>
|
|
#include <linux/genetlink.h>
|
|
#include <linux/if_addr.h>
|
|
#include <linux/if_ether.h>
|
|
#include <linux/if_link.h>
|
|
#include <linux/if_tun.h>
|
|
#include <linux/in6.h>
|
|
#include <linux/ip.h>
|
|
#include <linux/neighbour.h>
|
|
#include <linux/net.h>
|
|
#include <linux/netlink.h>
|
|
#include <linux/rtnetlink.h>
|
|
#include <linux/tcp.h>
|
|
#include <linux/veth.h>
|
|
|
|
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 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)
|
|
{
|
|
struct ifinfomsg hdr;
|
|
memset(&hdr, 0, sizeof(hdr));
|
|
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);
|
|
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);
|
|
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_hsr(struct nlmsg* nlmsg, int sock, const char* name,
|
|
const char* slave1, const char* slave2)
|
|
{
|
|
netlink_add_device_impl(nlmsg, "hsr", name);
|
|
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);
|
|
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);
|
|
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);
|
|
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);
|
|
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);
|
|
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 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)
|
|
{
|
|
char buf[16];
|
|
sprintf(buf, "%u %u", addr, port_count);
|
|
if (write_file("/sys/bus/netdevsim/new_device", buf)) {
|
|
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"},
|
|
{"netdevsim", netdevsim}, {"veth", 0},
|
|
{"xfrm", "xfrm0"}, {"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_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 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)) {
|
|
}
|
|
if (symlink("/dev/binderfs", "./binderfs")) {
|
|
}
|
|
}
|
|
|
|
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 = 0;
|
|
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)) {
|
|
}
|
|
initialize_netdevices();
|
|
setup_binderfs();
|
|
loop();
|
|
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_test()
|
|
{
|
|
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
|
|
setpgrp();
|
|
write_file("/proc/self/oom_score_adj", "1000");
|
|
}
|
|
|
|
static void close_fds()
|
|
{
|
|
for (int fd = 3; fd < MAX_FDS; fd++)
|
|
close(fd);
|
|
}
|
|
|
|
#define KMEMLEAK_FILE "/sys/kernel/debug/kmemleak"
|
|
|
|
static void setup_leak()
|
|
{
|
|
if (!write_file(KMEMLEAK_FILE, "scan"))
|
|
exit(1);
|
|
sleep(5);
|
|
if (!write_file(KMEMLEAK_FILE, "scan"))
|
|
exit(1);
|
|
if (!write_file(KMEMLEAK_FILE, "clear"))
|
|
exit(1);
|
|
}
|
|
|
|
static void check_leaks(void)
|
|
{
|
|
int fd = open(KMEMLEAK_FILE, O_RDWR);
|
|
if (fd == -1)
|
|
exit(1);
|
|
uint64_t start = current_time_ms();
|
|
if (write(fd, "scan", 4) != 4)
|
|
exit(1);
|
|
sleep(1);
|
|
while (current_time_ms() - start < 4 * 1000)
|
|
sleep(1);
|
|
if (write(fd, "scan", 4) != 4)
|
|
exit(1);
|
|
static char buf[128 << 10];
|
|
ssize_t n = read(fd, buf, sizeof(buf) - 1);
|
|
if (n < 0)
|
|
exit(1);
|
|
int nleaks = 0;
|
|
if (n != 0) {
|
|
sleep(1);
|
|
if (write(fd, "scan", 4) != 4)
|
|
exit(1);
|
|
if (lseek(fd, 0, SEEK_SET) < 0)
|
|
exit(1);
|
|
n = read(fd, buf, sizeof(buf) - 1);
|
|
if (n < 0)
|
|
exit(1);
|
|
buf[n] = 0;
|
|
char* pos = buf;
|
|
char* end = buf + n;
|
|
while (pos < end) {
|
|
char* next = strstr(pos + 1, "unreferenced object");
|
|
if (!next)
|
|
next = end;
|
|
char prev = *next;
|
|
*next = 0;
|
|
fprintf(stderr, "BUG: memory leak\n%s\n", pos);
|
|
*next = prev;
|
|
pos = next;
|
|
nleaks++;
|
|
}
|
|
}
|
|
if (write(fd, "clear", 5) != 5)
|
|
exit(1);
|
|
close(fd);
|
|
if (nleaks)
|
|
exit(1);
|
|
}
|
|
|
|
static void execute_one(void);
|
|
|
|
#define WAIT_FLAGS __WALL
|
|
|
|
static void loop(void)
|
|
{
|
|
int iter = 0;
|
|
for (;; iter++) {
|
|
int pid = fork();
|
|
if (pid < 0)
|
|
exit(1);
|
|
if (pid == 0) {
|
|
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;
|
|
}
|
|
check_leaks();
|
|
}
|
|
}
|
|
|
|
uint64_t r[2] = {0xffffffffffffffff, 0x0};
|
|
|
|
void execute_one(void)
|
|
{
|
|
intptr_t res = 0;
|
|
res = syscall(__NR_socket, 0x1dul, 2ul, 7);
|
|
if (res != -1)
|
|
r[0] = res;
|
|
memcpy((void*)0x200000c0, "vxcan1\000\000\000\000\000\000\000\000\000\000",
|
|
16);
|
|
res = syscall(__NR_ioctl, r[0], 0x8933, 0x200000c0ul);
|
|
if (res != -1)
|
|
r[1] = *(uint32_t*)0x200000d0;
|
|
*(uint16_t*)0x20000540 = 0x1d;
|
|
*(uint32_t*)0x20000544 = r[1];
|
|
*(uint64_t*)0x20000548 = 0;
|
|
*(uint8_t*)0x20000550 = 0;
|
|
*(uint8_t*)0x20000551 = 0;
|
|
*(uint8_t*)0x20000552 = 0;
|
|
*(uint8_t*)0x20000553 = 0;
|
|
*(uint8_t*)0x20000554 = 0;
|
|
syscall(__NR_bind, r[0], 0x20000540ul, 0x18ul);
|
|
*(uint64_t*)0x20000340 = 0x20000280;
|
|
*(uint16_t*)0x20000280 = 0x1d;
|
|
*(uint32_t*)0x20000284 = 0;
|
|
*(uint64_t*)0x20000288 = 0;
|
|
*(uint8_t*)0x20000290 = 1;
|
|
*(uint8_t*)0x20000291 = 0xf0;
|
|
*(uint8_t*)0x20000292 = 0;
|
|
*(uint8_t*)0x20000293 = 0;
|
|
*(uint8_t*)0x20000294 = 2;
|
|
*(uint32_t*)0x20000348 = 0x18;
|
|
*(uint64_t*)0x20000350 = 0x200002c0;
|
|
*(uint64_t*)0x200002c0 = 0x20000780;
|
|
memcpy(
|
|
(void*)0x20000780,
|
|
"\x82\x52\x0a\x10\x6d\xcc\x25\xc3\xac\xaf\x41\x93\x86\x37\x2a\xbe\x57\x63"
|
|
"\x28\x06\x92\x03\xdb\xde\x06\x19\x24\xbc\x07\x0f\x00\x1c\xa5\x4a\xfa\x76"
|
|
"\x48\x0d\xc3\xb6\x5d\xd8\xdc\x6c\x3b\x58\x7d\x38\x00\x0b\xa8\xfe\xa0\x12"
|
|
"\xa5\x95\xa3\xe1\x5b\x78\xb0\xc9\x0a\xeb\x49\xb5\xd4\xbb\xf1\x64\x6c\xb6"
|
|
"\xc5\x37\x4c\x43\x76\x1e\xdb\x72\x56\x50\x99\xfe\x34\x75\xe2\xce\xd8\x24"
|
|
"\xc5\xb0\x3a\x7c\xa5\xb1\x40\x4e\xce\xcd\xb5\x08\xfe\x52\x10\x4e\x3f\xf7"
|
|
"\x12\x42\xb6\x80\x79\x56\xba\x84\x0d\x2e\x4d\x4d\x06\xb7\xec\x41\xad\x49"
|
|
"\x26\xfd\x44\x6f\x3c\x0e\x1a\x07\x27\xd8\x85\x74\x78\xf1\x61\x2d\x94\x6d"
|
|
"\xe5\x10\xb9\x86\x22\x1d\x13\xc5\xaa\xab\x6f\xab\x72\x73\xba\xad\x36\xdf"
|
|
"\x93\x0f\x40\x7f\xd7\x48\x6b\xd5\x1e\x37\x61\x8b\xe9\x59\x04\x2d\x17\x02"
|
|
"\x37\x03\x3f\xe2\x05\xaa\xca\xd4\xc8\x9f\x38\x21\xe0\xc0\xf4\x85\xe7\x6a"
|
|
"\x75\x86\x89\xd1\x85\x65\x45\xa2\x0d\xaf\x18\x46\x61\xdd\xd3\x2d\x2e\xab"
|
|
"\x2f\x51\xd6\x34\x46\x56\x5d\x63\x34\x12\xfd\xc3\xa1\xe2\x2a\x3d\x4e\xd4"
|
|
"\x5e\xa3\x2d\x1e\x69\xe6\x61\xb6\x2d\xbe\xe1\x3f\xda\x23\x31\x26\x56\xf0"
|
|
"\xb5\x12\x31\xd1\xc9\xd4\x8e\x77\x74\x66\x22\x3e\xd2\xea\xbd\x09\xd0\x41"
|
|
"\x14\x24\x00\x20\x4e\xf1\xc0\xd0\x82\x8d\xf5\x38\xae\x02\x9a\xa8\xe4\x18"
|
|
"\x52\x9c\x6a\x1a\x90\x5d\xe3\x8a\x14\xfd\xf6\xf0\x63\xe9\x31\x60\x1f\x73"
|
|
"\x8e\x7f\x69\x06\xc0\xd1\x87\xad\x6e\x58\xb8\x32\x7d\x05\x15\xf5\x7d\x12"
|
|
"\xc2\x61\x98\x85\xe4\x04\xef\xe3\x3d\x9e\x48\x3b\x70\x24\xb7\xa9\xf9\x90"
|
|
"\x4d\x67\xa6\x1a\xf0\xd2\xe3\xe9\x2d\x4b\xd2\x8b\x7f\xaf\x0d\x87\x45\xab"
|
|
"\xe9\x22\x3d\x01\x99\xa8\x5d\xd9\xca\xaa\xcb\x6f\x1d\x1c\x79\x52\x8c\xf5"
|
|
"\x2e\x9a\xe6\x5e\xd5\xc9\x36\x66\xf7\x94\xdb\xbf\x69\x23\x2a\x64\x82\x8f"
|
|
"\x4c\xdc\xed\xcf\xd7\x88\x05\x6d\x85\x4b\x60\x5b\xfe\xea\x68\xe1\xc2\x50"
|
|
"\x1f\xda\xf0\xa1\x2c\x27\x09\x4f\x20\xa7\xe2\x9e\x6f\x1c\x2d\x52\x5c\x7a"
|
|
"\x7b\x82\x3f\x81\x1a\x31\x98\x6a\x8e\xa7\xcd\x4c\x2b\x83\x01\x3f\xb9\x10"
|
|
"\xff\xdf\x32\x8a\x27\xb3\x9e\xe1\x3a\x1e\x68\x56\x44\xa8\x70\xaa\x80\xdc"
|
|
"\xd4\x96\x82\xed\x27\x99\xc3\xf9\xef\x41\xf3\xea\xc0\x2a\x64\x48\xe5\x47"
|
|
"\x71\xbe\xb8\x67\xec\xbc\x04\x2d\x5f\xdc\x47\x2e\x88\x31\x9b\xbb\x40\x5f"
|
|
"\xfa\x7d\x15\x84\x66\x32\x09\x64\x5b\xa0\xdd\x0b\xc6\xa9\xcc\xe1\x78\xd2"
|
|
"\x2c\x2b\xf9\x99\xa7\x4b\xf7\x1a\x41\xec\x48\xea\x10\x68\xe7\x4e\x08\xd4"
|
|
"\x1d\x41\x40\x10\xa5\xb2\xb8\xfb\x7a\xe4\x71\x4d\xa6\xee\xdb\xef\xd4\xd3"
|
|
"\x52\xce\xd9\x7a\xf4\x50\x97\x7c\x99\x7a\x5d\x1a\x4d\x62\x00\x93\x72\xa9"
|
|
"\x52\xea\x31\xa6\x31\x06\x01\xaf\x54\x28\xb3\xd7\x45\xbe\xe0\x80\x7b\x30"
|
|
"\xb6\x64\x06\x63\x39\x93\x54\x25\xe3\x37\x42\x01\x34\xca\x8d\x7b\x34\x25"
|
|
"\x76\x1e\x53\xfa\x17\xe7\xad\x76\x09\x0e\xa7\x85\xae\xfa\x91\x11\xb3\xe9"
|
|
"\x66\x4c\xc4\x0d\xdf\x45\x11\x9a\xc4\x03\x24\xc5\x20\x13\x7d\xe0\xd2\xd6"
|
|
"\x2a\x69\x62\x6a\xf3\x63\x96\xd6\xd4\xdf\x65\x97\xa6\x80\x55\x0c\x05\x86"
|
|
"\xdc\x33\x59\x57\xc7\x36\x85\xab\x43\xf7\xd2\xf2\x01\x25\x93\x4b\x2e\xdf"
|
|
"\x00\x9d\xc2\x76\x2b\x8a\x9f\x61\x9c\xec\x1e\xf8\xcc\xa8\x4e\xaa\x99\xd2"
|
|
"\x03\x9d\xc8\x4a\x4f\xf4\x89\x18\x84\xa8\xb8\xcd\x9f\xe0\x8f\xe2\x04\x7b"
|
|
"\x96\x73\x94\x0d\x0e\x7f\xd8\x2d\x6b\x8b\x23\xe7\x68\x8f\x54\x88\x17\xad"
|
|
"\xb9\x9b\xe3\xfc\x6f\x08\x62\x9f\x8b\x24\x26\x83\xaf\xd9\xfa\x7a\xb0\x87"
|
|
"\x65\xf8\x0d\x1b\x69\x27\x12\x5f\x30\xbe\xda\x96\xbb\xdb\x3e\xc9\xb1\x73"
|
|
"\x04\xac\x35\x19\xb4\x76\x10\x4f\x8b\x0e\x92\x72\xa3\x14\x0e\x05\x8b\xd1"
|
|
"\x8c\x43\xa7\xf5\xcb\x31\xbb\x88\x0b\xeb\x9f\x28\x57\xbe\x70\x99\x3a\x6d"
|
|
"\xb3\x4d\x77\x2b\xf1\x59\x57\x06\x8f\x8c\x29\xa9\x8f\xa0\x9f\x7d\x22\x22"
|
|
"\x46\x32\x37\x87\xe1\xd6\x3d\x96\x32\xc1\xb9\xe8\x4f\xbc\xbe\x7b\x81\x69"
|
|
"\x7a\xd4\x5f\x7f\xa9\x12\xe6\x0b\x2a\x33\xd6\xab\x19\x69\xe9\x77\x8f\xa9"
|
|
"\x54\x0a\xa8\x2a\xcb\x29\xa1\x0b\x7e\x11\x2f\xb3\x78\x56\x25\x35\xea\xdc"
|
|
"\x6d\xf4\xf5\xf8\xab\x49\x33\xc5\xe9\x47\x1e\xed\x27\xf9\x21\x19\x15\x22"
|
|
"\x6f\x97\x74\x7a\x49\xbb\xfe\x42\x2e\x42\xfb\xe3\x77\xb3\x44\x8a\x19\x3e"
|
|
"\xb1\x59\x84\x98\xc2\x1a\x9c\x70\x69\xac\xcb\x52\xf1\x28\xf9\x3e\x06\x39"
|
|
"\x11\xf4\x69\x1a\xd1\xa1\x93\x37\x5b\x3c\x55\x3c\x87\x20\x59\xa8\x3f\x84"
|
|
"\x1d\x12\xc8\x2d\xe9\x95\x01\xaa\x3a\xad\xe9\xe2\x97\x08\x1a\x0a\xaa\xe8"
|
|
"\x52\xf7\xac\xcd\x47\x94\xba\x6c\x11\x02\x6a\x11\x9d\xe6\x68\x85\x3e\x65"
|
|
"\xac\x3a\xe1\x8d\x07\x70\xcc\x77\xa2\x02\x91\xed\x1b\x70\xc3\x55\x5f\x2b"
|
|
"\x10\x1d\x1b\x3e\xe6\x43\x58\x6e\xf3\xca\x81\x4d\x75\x46\x5e\xa0\x7a\x27"
|
|
"\xa2\xba\xd7\x86\xa0\xef\xba\xd9\x44\x3f\xb1\x8c\x38\x55\x18\xfb\x5c\x58"
|
|
"\xfa\x4a\xdd\x92\x54\x02\x66\xdf\xfa\x12\x8f\x45\x1e\x92\x52\xd5\x9f\x35"
|
|
"\xb9\x2a\xb3\xc6\x62\x10\x4c\x0f\xd9\x2c\x32\x8c\xc7\x74\xbf\xda\xab\x97"
|
|
"\x33\xfd\x66\xa3\x8f\x6a\x15\xb2\x83\xbc\x4e\x74\xd4\x9a\x68\x47\x07\x8b"
|
|
"\x3a\x27\x4f\xa6\x0e\x7f\xb6\x69\x08\xd9\x51\x73\x21\xb4\x65\x64\x41\x24"
|
|
"\xad\x8b\xce\xd5\x74\x3c\x8a\x6f\xbb\xb2\xec\xa3\x06\x03\xd7\x12\x02\x91"
|
|
"\xc2\x86\xc3\x96\xf7\xf1\x15\xdb\x92\x88\x5a\x86\xe6\x4c\xf5\xb9\x67\xca"
|
|
"\xe7\xa3\xd8\xe8\xd9\x67\x46\x52\x37\x0f\xb5\xbe\x1b\x71\xbc\x00\x74\x16"
|
|
"\x69\xac\x9e\x09\x12\xd2\x95\x97\x1d\xff\xd6\xa1\xeb\x4d\xce\xa8\x59\x76"
|
|
"\x91\x1b\xee\x06\x82\x38\x70\x07\xd9\x7d\xf1\xe4\xdc\x82\xb7\xf7\x8b\x33"
|
|
"\xd1\x5a\x5e\xf4\x2c\xac\x1b\x06\x6b\x20\xb3\x8f\x61\xcb\x5a\xda\x1a\x70"
|
|
"\x8f\xed\xfb\x26\x20\x70\xb3\x97\x90\x93\xbc\xed\x97\x4f\x2e\x5c\x16\xf9"
|
|
"\x4f\xbb\x83\x16\xfb\xd0\x92\x68\xa8\x37\x4d\xe3\xd9\x95\x7a\xff\x51\x5b"
|
|
"\xe8\xd5\x3b\x81\x1a\x46\x25\xae\xf0\x21\x83\xa7\x88\x6e\x21\x74\xc8\x8b"
|
|
"\x8c\xe4\xd7\x53\x14\xee\x30\xe8\x69\xec\xb9\x21\xaa\x81\xeb\x37\xbc\x8a"
|
|
"\x2a\x1a\x88\x3e\xa6\xf6\x7f\x6c\x98\x08\x83\xde\x12\xb4\x2a\x01\xa0\x68"
|
|
"\xef\xe5\x71\x7f\xf2\x96\x5f\xf3\xe3\xf5\xc2\xff\x8d\x25\xb8\xb3\x9f\x60"
|
|
"\x54\x77\x63\x24\xb5\xd6\xae\xcb\x9f\xa0\x97\xf1\xda\xeb\x27\xab\x71\x2e"
|
|
"\xe3\x0d\x37\xbe\x22\x8c\x27\x3f\x44\x10\x2d\x33\x44\xb4\x6d\xe1\xb6\xd1"
|
|
"\x6f\x19\xeb\x6a\xe6\x29\x3c\xca\x5a\xf5\x32\xb9\x4c\x56\x20\x56\xcd\x19"
|
|
"\xdb\x52\x74\x39\x99\x60\x48\x17\x51\x98\x74\x47\x83\x79\xe7\xad\xf8\xa2"
|
|
"\x44\xbe\x19\xce\x72\x63\xbf\x4e\xaf\x85\x75\xcc\xf5\x0e\xd3\x5d\x78\xe7"
|
|
"\x12\xbf\xd1\x77\x2f\x01\x91\x69\x07\xe5\xd0\x5a\x31\xfb\xf1\x53\xf9\x9d"
|
|
"\xd7\xb2\xac\x9c\x6e\x57\xf1\x61\x8f\x53\x12\x9f\x68\x50\x75\x4a\xcc\x77"
|
|
"\xba\x40\x81\xbb\x4f\xc4\xb1\x9b\xa1\x59\x7e\x68\x26\x46\xef\x85\xad\x83"
|
|
"\x21\x2c\x3f\x4f\x6c\x8d\xa7\xa4\x02\x41\x3c\x56\xfd\x20\x84\x57\xc4\x06"
|
|
"\x24\x4e\x35\x79\x35\x1a\x14\x47\x6a\xd5\xb0\xa5\xb5\x2b\x85\x0b\xca\x78"
|
|
"\x17\x14\x3c\x7d\xfd\x7e\xfa\x72\x84\xd7\xf2\xc2\x76\xff\x3d\x5d\x2e\x3c"
|
|
"\x1a\xed\xcc\x52\x81\x07\xd3\x0b\x6e\x1e\xec\xf7\x5b\x94\x9c\xf2\x88\xf2"
|
|
"\x15\x5b\xc3\xe7\x21\x2c\x90\x9b\x0e\x8a\x90\xa9\x70\xd6\x33\x72\xaf\xd4"
|
|
"\xcd\xbe\x34\x64\xc7\x71\x21\x3e\xfe\x9a\x76\x43\xf1\xd5\xd6\xbe\x82\x72"
|
|
"\x96\x5a\xd5\x00\xe8\xdb\x90\x90\x7d\xc8\x78\x22\x5a\x6e\x3a\x6e\xb3\xc0"
|
|
"\x24\x6c\xd7\xf7\x79\xf5\x12\xd0\x47\x72\x20\xfe\xcb\xa8\x0e\xf6\x2a\x0d"
|
|
"\xef\xc9\x9c\xd6\xd8\xb8\x0b\x97\xd3\x86\xdf\xbf\x38\xcf\xed\x1b\x3a\x0e"
|
|
"\xd1\x70\xab\xb4\x59\x9c\xf7\x1f\x7f\x55\xc5\xb7\x4d\x2d\x03\x2a\xe8\x74"
|
|
"\x59\x33\xf9\xd6\x64\x03\x7e\xb7\xf2\x9a\xec\xf0\xcd\x2e\x72\x37\x40\x49"
|
|
"\xbd\x45\xb2\x1e\xeb\x4b\x5a\x3a\xd8\x7e\x29\x5b\x1d\xa8\xc9\x5b\xb1\x63"
|
|
"\xc8\x8e\x99\x95\x7b\x1f\xec\x03\x9c\xf9\xb1\x0f\x71\x0a\x82\x81\xa1\x00"
|
|
"\xd3\xaf\x06\xdf\x8b\xfe\x0f\x8f\x0b\x57\xc6\xd1\x78\xbf\x2a\x37\x26\xea"
|
|
"\x87\x57\xe6\x76\xf3\x6e\x5f\x55\xc7\x88\xae\xa4\xeb\x41\xef\xea\xdc\xe6"
|
|
"\x76\xc3\x5e\xb3\xb4\x99\xd5\x53\xda\x9d\x5e\x6a\x0c\x24\xf9\xd5\x08\x5e"
|
|
"\xbe\x0a\x58\x5c\x5d\xeb\x37\x51\x8b\xd0\x48\xde\xeb\x19\x52\x53\x34\x97"
|
|
"\xde\x5f\x0f\x35\x14\x12\x1f\xe9\xcb\xc8\x1a\xde\x4d\x83\xde\x65\x06\xc0"
|
|
"\x96\x9e\x44\xf4\x6a\xbd\x36\x5e\x8a\x8b\x03\xf9\x52\xbd\x52\xba\x88\xc8"
|
|
"\x9e\xa4\xf9\x81\x7c\x76\x77\x83\xf8\xea\x76\x29\xfb\x1f\x96\x6b\xfd\x53"
|
|
"\xe2\x62\x6c\x5d\x51\xf0\x52\x5f\xc1\x50\x9b\x14\x93\xc5\xfe\x74\xec\xd1"
|
|
"\x8f\x15\xda\x3e\x92\x23\xe4\xc1\x71\x0b\x90\xce\x23\x61\xf8\x96\xef\x54"
|
|
"\xb5\xd8\x6e\x15\x8d\x5b\x9f\x02\x63\x33\x45\x0f\xfd\xad\xe3\xa2\xfb\x23"
|
|
"\xe4\x5a\xf6\x58\xb5\x55\xf7\x82\x39\xf7\xcf\x8f\x10\x09\xd9\xc1\x0e\x94"
|
|
"\x11\xb9\x7a\x69\x79\x2e\x92\x6b\x51\x21\x21\x1f\xbe\xb5\x9d\xbf\xad\xf6"
|
|
"\xc1\x47\x68\x3c\x28\xbb\xd5\xf1\x28\x36\x6b\x92\xfb\x41\x68\x31\x52\x27"
|
|
"\x0d\xee\x14\x5d\xe5\x49\x0f\xc6\x37\x82\xe5\x49\xac\x0c\x69\x55\x67\xeb"
|
|
"\xe8\xd9\xa2\x0c\x9f\xc7\xc9\xc0\xd4\x59\xe4\x52\xcb\x20\x29\x5c\x74\x68"
|
|
"\xab\xde\xca\x2d\xa4\x39\x99\xd8\x54\x30\xe5\xd8\x71\xa2\x23\xec\xf8\xc3"
|
|
"\x98\x6e\x01\xd9\xf0\x5b\xbd\x77\xe7\x46\x03\xc0\x2b\xf2\x63\x04\x0f\x62"
|
|
"\x4e\x9c\x34\x26\x48\xd4\x7f\xa9\xa8\xa9\xb0\x52\x84\x70\x29\xdd\x9b\x29"
|
|
"\xd7\x99\xc7\xc6\xf0\x28\xb6\x8f\xe6\x29\xa4\x84\x6d\x1f\x90\x98\xb6\xc0"
|
|
"\xab\x26\xf9\x6d\xb3\x21\xd5\x7c\x63\x94\x33\x98\x40\xd5\x1e\xcf\x3f\x2d"
|
|
"\x29\xb7\x5b\x37\xf7\xc2\x5d\x91\x04\x26\xe3\x38\x0e\x24\x25\x91\x0d\xbe"
|
|
"\x48\x30\x6d\xa1\xe6\x36\xd8\x79\x96\xfc\xda\xbc\xf1\x9b\x78\x31\x98\xcc"
|
|
"\x85\x11\x9b\x4c\x37\x1c\x03\x07\x1c\xd7\x6a\x8b\xc8\xb2\x29\xd0\x43\xfc"
|
|
"\xf2\xe6\x44\x13\xec\xcd\x01\x08\x22\x22\x1f\x9f\x47\xab\xbc\xf0\xb3\x79"
|
|
"\x9e\xc3\x60\x24\xf7\x5a\x0c\xe9\xef\x3b\xf4\xec\x26\x5b\x6a\xc1\x95\x04"
|
|
"\xcf\x8b\xbf\xf3\xe5\x86\x02\x26\x2c\x2b\xf5\xe8\xcb\x9c\x4d\x44\x6d\xa1"
|
|
"\x33\x30\xd2\x0f\x53\xf1\xad\x6a\x04\x69\x2a\xd3\x93\xb7\x7a\x93\xb6\x85"
|
|
"\x9b\x3d\x87\x3e\x10\xe1\x5f\x83\x29\x10\x60\xdb\xf7\x90\xfe\xd2\x38\xe1"
|
|
"\x26\x65\xf8\x54\x61\x35\x5c\xb0\xf1\x1e\xbc\x61\x90\xd5\x13\x49\xe2\x41"
|
|
"\x0d\x73\x83\xbb\x5f\x81\xcb\xd7\x96\xb7\xdb\x0e\x67\xb6\xc3\x76\xd5\x82"
|
|
"\xf9\x6b\x88\x2a\x33\x90\xe5\xf2\x67\x9d\x02\x3c\xa5\x3e\x0c\x6a\x79\x87"
|
|
"\xef\x76\x7b\x8a\x08\xee\xc9\xbe\x89\x2f\xae\x27\x90\xc1\x05\xdd\x10\x4e"
|
|
"\x50\x6a\x9c\x26\x1a\x5e\x82\x66\x7c\x49\x05\x5a\x0c\x79\xe1\x1e\x05\xa5"
|
|
"\xfd\x87\x2c\x73\x92\x78\xd5\x62\x33\x39\x10\x88\x29\x77\x34\x74\xff\x1c"
|
|
"\x96\xc6\x4f\xb7\x7e\xc0\x3e\x2b\xe1\x00\xb4\x89\x7e\xbb\xef\x26\x4b\x11"
|
|
"\x3d\x9f\x83\xf1\x40\x09\xdc\xe3\x03\x4c\x7c\xe0\x0c\x5a\xfb\x6d\xd8\xda"
|
|
"\x2b\xe3\x12\x22\xcd\xcc\x0b\xf2\x5a\xd2\x4f\x9e\x5a\x99\xc6\x49\xf7\xd5"
|
|
"\x1c\xd0\x1d\x11\xe1\xe3\x2b\x23\x36\x55\x5b\x51\x6f\x49\xeb\xd8\xe8\x3d"
|
|
"\xe3\x63\xe5\xbe\xaf\x5f\xf1\x3a\x51\xdf\x6d\x28\xe2\xb6\x3d\x8c\xa0\x27"
|
|
"\xad\xea\xd7\x29\x4e\x63\x1d\x49\x18\x5e\xa3\x78\x04\x93\x90\x1f\xdc\xe6"
|
|
"\x37\x0c\x87\xc7\x76\x36\x1d\xe0\xa6\x99\x91\x29\x7f\xd7\x4b\x37\xfa\x9f"
|
|
"\x35\xbf\x00\xf5\x80\x6d\x24\xe7\xb7\xab\xdf\xf0\x3b\xb9\xe8\x6e\xf6\x0c"
|
|
"\xb7\x9b\x47\x0c\x49\x18\x0d\x33\x43\x57\x19\x18\x64\x15\xb4\x66\xa5\x8c"
|
|
"\x2e\xd7\xe4\x89\x98\x3e\x64\x5e\xe3\x3f\x53\xed\x42\xa1\xbb\x86\x2d\xc9"
|
|
"\x9e\xda\xc4\x47\x6a\x52\x4a\x6f\x8a\xa5\x99\xa4\x4b\xed\xc8\xe2\x20\x3d"
|
|
"\xa5\x68\xee\x4a\x8d\xa9\x4a\xf1\x45\x82\xb1\x14\x93\xc3\x84\x0d\x7b\x34"
|
|
"\x25\x4f\x78\x18\xad\xe7\x1c\x04\x2f\x32\xef\xdc\x57\xbc\x16\xa5\x1e\xeb"
|
|
"\x27\x20\x14\x87\xed\x81\x70\xc7\x6a\xeb\xbb\xe4\x35\xed\x33\xaf\x85\x80"
|
|
"\xe5\xcf\x65\xd1\xe1\x11\xc6\x5e\x99\xff\xbf\xa8\xa2\xbb\x66\xf3\xa5\xd8"
|
|
"\xad\x99\xf4\xeb\xf6\x35\x90\xef\x63\x61\x17\xda\xc4\x4c\xf7\x80\x94\xe0"
|
|
"\x82\x09\x89\x25\xe5\x87\xb2\x6b\xfc\x3f\xe8\x13\xae\xca\x7d\x41\x81\x44"
|
|
"\x41\x57\x84\xd3\x8c\xc2\x75\x52\x3c\x35\xd0\xf6\xfb\x27\x38\x22\x5f\xb7"
|
|
"\x72\xae\x64\x03\xf9\xc2\x95\x4e\x03\xbc\xbb\xec\x16\x06\x78\x69\xb6\x9e"
|
|
"\xfa\xbe\xba\x47\xf7\x18\x56\xef\x34\x10\x09\x91\x0d\x97\xe0\x3e\xed\x35"
|
|
"\x4e\xfd\xb9\xb1\x11\xbb\x61\x5d\x88\x43\xda\x25\x1d\xeb\xa9\x72\x35\x77"
|
|
"\x55\xb4\x60\xce\x09\x62\x83\x67\xd1\x96\x11\x3e\x65\x16\x3a\x1a\x24\x82"
|
|
"\x54\xfd\xa6\x52\x97\x6b\x80\x49\x20\x4d\xb8\xfb\xa7\xd2\xd7\x7f\xcd\xd5"
|
|
"\x3c\xf7\x15\xd9\xbd\x67\xab\x90\xc4\xc9\x23\xf7\xd1\xb8\xdb\xc4\x39\xab"
|
|
"\xc0\xb1\x75\x1d\x13\xd9\x76\xbf\x99\xce\x20\x78\x43\x22\x79\x01\x95\xa1"
|
|
"\x0d\x30\xef\xca\x05\xb9\x30\x35\xee\x98\xb4\xf8\x46\xcc\xd4\x1e\xfd\x1c"
|
|
"\xd4\xcd\xa8\xa9\xd1\x18\x1e\x20\x61\xc4\x85\xfb\x08\x4c\x52\x1b\x02\x94"
|
|
"\xef\xdb\xb7\x4f\x5f\xd8\xf3\xa5\x77\x1b\xd6\x68\x13\x15\x42\x50\x11\x77"
|
|
"\xda\x7a\x9b\x19\x3e\xd1\xe9\x7d\x56\x83\x10\x4c\x2d\xc9\x57\xb8\xa8\x92"
|
|
"\x30\x51\x57\x7c\x86\x41\xe0\x49\xc7\x8a\xd4\x6f\x81\xb8\x13\x2a\xe6\x9a"
|
|
"\x84\x8b\xca\x15\x36\xf6\x27\x9b\x74\x9c\x59\xdc\xe9\x06\x51\x40\xd7\x00"
|
|
"\x6f\x5e\x9e\x0c\x39\x37\x4d\x76\x48\xb8\x49\x0c\x8d\x38\x7d\x4b\xf0\x97"
|
|
"\x9f\x03\xab\xbe\xa1\x89\x2d\x99\x3c\x56\x70\x42\xda\xce\x7e\x27\x9a\xcb"
|
|
"\x9b\x35\x19\xa5\xe7\x75\x8b\x23\x3a\xca\xc2\x03\xd8\x51\xb2\x66\xbe\xf6"
|
|
"\x29\xf5\xc9\xdb\xbe\x6e\xd0\x76\xd4\x46\x16\x80\x22\x46\x30\x90\x89\x21"
|
|
"\x47\xc9\x18\x52\x4a\x35\x92\x1d\x15\x5d\xca\x61\x1e\x05\x09\x2f\x0e\x76"
|
|
"\x3e\x40\x69\xb0\x86\xaf\x6c\x63\xfb\x4a\xb1\xc8\x6b\x2e\x0f\x83\x27\x1b"
|
|
"\xfe\x50\xa6\x8a\x53\x01\xa3\x07\xb4\x6c\x21\x09\x8a\x9b\x5e\x8c\x91\x86"
|
|
"\xde\xbf\x0f\x8d\xd6\x83\x02\xa0\x1d\xe9\x1c\x64\xf1\xd1\xe2\xa8\xe1\x2a"
|
|
"\x28\x57\xf5\xd9\x10\x18\x96\x17\x6c\x06\xde\x75\xb5\x57\x85\xcb\xe9\xef"
|
|
"\x38\xb3\x81\xb3\xc9\x80\xf4\x84\x91\x7b\x6d\xe8\x38\xe9\xb8\x47\xc1\x55"
|
|
"\x8c\x21\x04\x8b\x78\x87\x99\x0c\xd2\x06\x8e\x57\xd1\x3c\x97\x50\x58\x9b"
|
|
"\x33\x0f\xc8\x32\x32\xd1\x67\xc3\xee\xa8\x0b\x1c\xa7\x05\x3f\xf7\x9f\xda"
|
|
"\x8e\x75\xd6\xbd\xba\xee\x06\x80\x72\xa5\x04\x84\x4c\xaf\x26\xf2\x10\xc1"
|
|
"\x0a\xf3\x01\xbb\xf6\xf1\x20\xd2\x2e\xa8\x2b\xe7\xc7\x7a\xd7\x70\x03\xa1"
|
|
"\xd4\x31\x8c\xc9\x0e\x7c\x29\xca\xba\xac\xa9\xf0\xd1\x7f\x2c\x61\x1e\xff"
|
|
"\x27\xf4\x04\x9f\x90\x8e\xe8\x91\xf3\x63\x1b\x67\xa3\x70\x2c\xa2\xc0\x6b"
|
|
"\xcc\x60\x5f\x09\xef\x66\xa2\xd6\x76\x60\x48\xc1\xd7\x56\x11\x3f\x9f\x5f"
|
|
"\x39\x61\x29\x35\x34\xd8\x4d\x89\x31\xf2\x16\xe0\xa2\x70\x9c\xcc\x3c\xa9"
|
|
"\x9c\x4f\xe5\x8d\x57\xe0\xb6\x82\xbb\xc8\xf7\x69\x26\x98\x89\xab\x6c\x16"
|
|
"\x18\x3c\x8d\x43\x09\x00\x65\xf9\xff\x0f\x5e\x96\xa1\x0c\xb9\xa2\xd9\x95"
|
|
"\xf2\x83\xc9\x7b\x76\x3a\xa6\x82\xd6\xa5\x86\x5b\x01\x23\x77\xd0\x31\x08"
|
|
"\x45\xbd\x6a\x01\x0c\x61\x77\x6a\x08\x1b\x70\x6b\x0a\x1c\xc7\x44\xe2\x56"
|
|
"\xa5\xe7\x76\x13\xcf\x18\x1f\xe3\x1b\xe3\xde\x0b\x1e\x6b\x61\xaa\x83\xf3"
|
|
"\x64\x43\x87\xb1\x9b\xcf\xff\x2e\x04\x3f\x8a\xa2\x7d\x34\x2a\x15\x25\x8e"
|
|
"\x2d\x6d\x57\x09\x49\x93\xf1\x2e\x97\x2e\x9e\xb5\xfe\xc1\xe6\xdf\x3c\x4f"
|
|
"\xb2\x42\x9e\xac\x6e\xbc\x87\x20\x5a\x71\x8c\xa0\xdb\xcb\x4f\xe6\x16\x55"
|
|
"\xb7\x04\x2c\xf7\xd9\xec\x29\x04\x8a\x43\x88\x27\x53\xcc\xce\x1c\x22\x52"
|
|
"\xd1\x15\x99\x28\x43\xf6\x36\xfd\x11\x80\x82\x08\x46\x11\xb4\x3b\x7a\x2b"
|
|
"\xab\x41\xf7\xf8\x8c\xb5\xb3\x3d\xbd\xf5\xf0\x2b\xc5\xff\xb5\x6f\x23\xa9"
|
|
"\x89\x21\xc1\x36\xf6\x12\xc5\x17\xc8\x7c\xe5\xbc\x41\x98\xcc\x89\xce\x8b"
|
|
"\x3a\x12\xa4\x9f\x0f\xdb\x07\xa4\xa3\x2a\xe2\x04\xdb\xf6\xe2\x3f\x89\x6b"
|
|
"\x74\xa9\xe8\x23\xe4\x6f\x56\x1d\x30\xfa\x8e\x1e\xf3\x78\x13\x2f\xd2\x98"
|
|
"\x80\x80\xa8\x01\xeb\xfe\xa4\xb6\x91\x61\xb4\x18\x8d\x9a\x6b\x6d\x85\xd2"
|
|
"\xc3\x64\x44\x10\xeb\x3e\x69\x40\xe6\x08\xc3\x92\xc8\x66\xc7\xc5\xa4\xc3"
|
|
"\xe2\xba\x8c\x61\xf5\xd6\x50\x97\x39\xe3\x44\xf0\xa7\xfe\x9a\x4c\xcb\x5a"
|
|
"\x2b\x06\x2f\x2f\xda\x39\xbd\x50\x09\x25\xaa\x71\x70\x21\x90\x1a\xc9\x5e"
|
|
"\x45\xbc\x2b\x7f\x87\x2d\x04\xe4\xb3\x2a\xd0\xc7\x11\x99\x60\xd4\xf8\x86"
|
|
"\xb3\xb3\xcc\x7a\x2e\x8c\x93\xf2\x5f\x50\x74\xa4\x04\x26\xd5\x37\xbe\xab"
|
|
"\xdf\x16\x10\x7a\xa0\x52\x12\xba\xd5\x08\x5e\x12\xb6\xc8\xe3\xe7\xe5\xb1"
|
|
"\xc5\x92\xf2\x28\xb7\x08\xd2\xb4\xc1\x01\xb2\xbf\x4a\x9c\x06\xa4\x4c\x39"
|
|
"\xe0\xdf\x56\x67\xae\xc0\xb6\xf8\x58\xe5\xad\xeb\xf8\x6a\x5f\xeb\x58\x25"
|
|
"\x6a\x19\xf5\xd5\xed\x49\x5b\xca\xbe\x0b\xad\x6b\x6d\xb1\x7f\x48\xa5\xdf"
|
|
"\x35\xb9\x6a\x3d\x1c\x78\x9e\xf8\x4e\xbb\xc8\xfa\x70\xba\xbb\xc7\xc4\x7e"
|
|
"\xbc\x6e\xb0\x3c\xbd\x65\xe1\xc4\x9f\x6b\x84\x7e\x4b\x7c\x4c\xc9\x8b\x2d"
|
|
"\xf7\xbd\xb5\x5c\x28\x50\x8e\xc8\x4e\x5c\x67\x21\x17\x18\xcc\x09\xcb\xfe"
|
|
"\x5b\x35\x4f\x28\xba\xaf\xbc\xb7\xe0\x47\x9c\x43\x05\x71\x7a\xb1\xb4\x9c"
|
|
"\x2e\x90\xeb\xe7\x4f\xec\xa8\x30\x1e\x7d\x0f\x41\xbc\x98\x12\xf4\x34\x0a"
|
|
"\x20\xf3\x6a\xaf\x28\xd4\xe9\xb3\x78\x7b\x26\x94\x02\x89\x49\x19\x64\x79"
|
|
"\xea\xaf\x9c\x7d\x10\xee\x01\xbd\xbd\x96\xa1\x05\x07\xea\x86\xcd\x05\x58"
|
|
"\x53\x8d\x55\xd6\x1d\xa8\xc8\x98\x47\x7c\x3a\xfa\x4e\x11\x51\x06\x08\x89"
|
|
"\xb3\x6e\x30\xa2\x67\x77\xf1\xb1\x90\xcf\x90\xa8\x85\xe3\xd3\x9a\x56\xc5"
|
|
"\xf3\x17\xe8\x76\xaf\x42\x5f\x2a\x9d\xa0\xb0\xef\xd4\x6c\x16\xf7\x26\xb7"
|
|
"\xb4\xae\x09\x6e\x7b\xc3\xe3\x54\x25\x1d\x9d\xcc\x66\x8c\xe1\x91\x6a\xde"
|
|
"\x38\x24\xa4\xdf\x26\x6f\x11\x42\x5f\xcb\x5c\xae\x9e\x51\x96\x7f\x43\x59"
|
|
"\x22\x8c\x33\x9c\x38\x78\x83\xb9\x2c\x49\x84\xf2\x0a\xf7\x7d\xb5\x9e\x12"
|
|
"\x06\xc4\xa3\xe9\xfb\xc7\xd2\xb9\xdc\x7e\x3d\x3b\x3c\x52\xd2\x6e\x7d\x2f"
|
|
"\x03\x78\x09\x85\xfc\xd4\xe0\x0b\xb4\xbd\x74\x41\xff\x11\xaf\xf5\x62\x1b"
|
|
"\x18\xa5\x0d\x39\xf8\xf4\xe0\x9a\xad\xc8\x0e\x73\x49\xf6\x68\xc7\xc4\x05"
|
|
"\x5b\xb6\xad\x54\x9d\x4e\xf2\xbb\x27\xc7\xa3\xdb\xbb\x37\xc1\xea\x29\xba"
|
|
"\x86\x12\x4e\x51\x2e\x41\xfc\x04\x1b\xdd\xae\x65\xb1\x1f\x25\x43\x10\xa5"
|
|
"\xf5\xf5\x03\xe5\x79\xd7\x4f\x0e\x7c\x8b\xd4\x03\x99\x6d\x59\x9f\x99\xbe"
|
|
"\xa8\xea\x9a\x3f\x10\x6e\xef\x95\xfe\x5c\x6c\x99\xa9\xba\x82\xb3\x91\x9e"
|
|
"\xaa\xe7\x47\xdd\xe8\x5b\xda\xed\xd4\x9e\x23\x9c\x24\xb0\xb5\xc4\xbf\x40"
|
|
"\x2b\x29\x90\xb2\x2b\x81\x3a\x51\x87\xcd\x46\x8c\x21\xdc\x17\xab\x8a\x96"
|
|
"\xa9\x0d\xfd\xf7\xb8\x37\xdb\xf9\x9e\xab\xd8\xd1\xe8\xae\xa4\x37\x34\x35"
|
|
"\x76\x5e\xa6\xe3\x68\xbf\xc1\x5a\xf0\x04\xe1\x62\x67\x11\x29\x2d\xe4\xbf"
|
|
"\x98\xfb\x7c\x84\x79\x9d\x8e\x3c\xdd\xcb\x98\x23\x73\x73\x54\x19\x7d\x02"
|
|
"\x35\x90\xf8\x9b\xb6\xcc\x00\x44\x2a\xab",
|
|
4096);
|
|
*(uint64_t*)0x200002c8 = 0x1000;
|
|
*(uint64_t*)0x20000358 = 1;
|
|
*(uint64_t*)0x20000360 = 0;
|
|
*(uint64_t*)0x20000368 = 0;
|
|
*(uint32_t*)0x20000370 = 0x240400c1;
|
|
syscall(__NR_sendmsg, r[0], 0x20000340ul, 0x8000ul);
|
|
}
|
|
int main(void)
|
|
{
|
|
syscall(__NR_mmap, 0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
|
|
syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
|
|
syscall(__NR_mmap, 0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
|
|
setup_leak();
|
|
do_sandbox_none();
|
|
return 0;
|
|
}
|
|
|