-
-
Save xrivendell7/080e44fad03c27df3152ff3bcc8a8385 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
================================================================== | |
BUG: KASAN: slab-use-after-free in compare_netdev_and_ip drivers/infiniband/core/cma.c:473 [inline] | |
BUG: KASAN: slab-use-after-free in cma_add_id_to_tree drivers/infiniband/core/cma.c:513 [inline] | |
BUG: KASAN: slab-use-after-free in rdma_resolve_route+0x2524/0x32a0 drivers/infiniband/core/cma.c:3379 | |
Read of size 4 at addr ffff88803bec8184 by task syz-executor.0/20220 | |
CPU: 3 PID: 20220 Comm: syz-executor.0 Not tainted 6.8.0-rc4-next-20240214 #1 | |
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 | |
Call Trace: | |
<TASK> | |
__dump_stack lib/dump_stack.c:88 [inline] | |
dump_stack_lvl+0x250/0x380 lib/dump_stack.c:114 | |
print_address_description mm/kasan/report.c:377 [inline] | |
print_report+0x169/0x550 mm/kasan/report.c:488 | |
kasan_report+0x143/0x180 mm/kasan/report.c:601 | |
compare_netdev_and_ip drivers/infiniband/core/cma.c:473 [inline] | |
cma_add_id_to_tree drivers/infiniband/core/cma.c:513 [inline] | |
rdma_resolve_route+0x2524/0x32a0 drivers/infiniband/core/cma.c:3379 | |
ucma_resolve_route+0x1c3/0x330 drivers/infiniband/core/ucma.c:745 | |
ucma_write+0x2f0/0x440 drivers/infiniband/core/ucma.c:1743 | |
vfs_write+0x2b3/0xcf0 fs/read_write.c:588 | |
ksys_write+0x18e/0x2d0 fs/read_write.c:643 | |
do_syscall_64+0xfb/0x240 | |
entry_SYSCALL_64_after_hwframe+0x6d/0x75 | |
RIP: 0033:0x7fe6e4e7dde9 | |
Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 20 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48 | |
RSP: 002b:00007fe6e5bc40c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 | |
RAX: ffffffffffffffda RBX: 00007fe6e4fabf80 RCX: 00007fe6e4e7dde9 | |
RDX: 0000000000000010 RSI: 0000000020000440 RDI: 0000000000000003 | |
RBP: 00007fe6e4eca47a R08: 0000000000000000 R09: 0000000000000000 | |
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000 | |
R13: 000000000000000b R14: 00007fe6e4fabf80 R15: 00007ffcf1ec8948 | |
</TASK> | |
Allocated by task 20217: | |
kasan_save_stack mm/kasan/common.c:47 [inline] | |
kasan_save_track+0x3f/0x80 mm/kasan/common.c:68 | |
poison_kmalloc_redzone mm/kasan/common.c:370 [inline] | |
__kasan_kmalloc+0x98/0xb0 mm/kasan/common.c:387 | |
kasan_kmalloc include/linux/kasan.h:211 [inline] | |
kmalloc_trace+0x1d9/0x360 mm/slub.c:4013 | |
kmalloc include/linux/slab.h:590 [inline] | |
kzalloc include/linux/slab.h:711 [inline] | |
__rdma_create_id+0x6a/0x5a0 drivers/infiniband/core/cma.c:993 | |
rdma_create_user_id+0x88/0xd0 drivers/infiniband/core/cma.c:1049 | |
ucma_create_id+0x2e1/0x520 drivers/infiniband/core/ucma.c:463 | |
ucma_write+0x2f0/0x440 drivers/infiniband/core/ucma.c:1743 | |
vfs_write+0x2b3/0xcf0 fs/read_write.c:588 | |
ksys_write+0x18e/0x2d0 fs/read_write.c:643 | |
do_syscall_64+0xfb/0x240 | |
entry_SYSCALL_64_after_hwframe+0x6d/0x75 | |
Freed by task 20216: | |
kasan_save_stack mm/kasan/common.c:47 [inline] | |
kasan_save_track+0x3f/0x80 mm/kasan/common.c:68 | |
kasan_save_free_info+0x40/0x50 mm/kasan/generic.c:586 | |
poison_slab_object+0xa6/0xe0 mm/kasan/common.c:240 | |
__kasan_slab_free+0x37/0x60 mm/kasan/common.c:256 | |
kasan_slab_free include/linux/kasan.h:184 [inline] | |
slab_free_hook mm/slub.c:2122 [inline] | |
slab_free mm/slub.c:4296 [inline] | |
kfree+0x14a/0x380 mm/slub.c:4406 | |
ucma_close_id drivers/infiniband/core/ucma.c:186 [inline] | |
ucma_destroy_private_ctx+0x162/0xc70 drivers/infiniband/core/ucma.c:578 | |
ucma_close+0x103/0x180 drivers/infiniband/core/ucma.c:1808 | |
__fput+0x442/0x8d0 fs/file_table.c:411 | |
__do_sys_close fs/open.c:1557 [inline] | |
__se_sys_close fs/open.c:1542 [inline] | |
__x64_sys_close+0x84/0x120 fs/open.c:1542 | |
do_syscall_64+0xfb/0x240 | |
entry_SYSCALL_64_after_hwframe+0x6d/0x75 | |
The buggy address belongs to the object at ffff88803bec8000 | |
which belongs to the cache kmalloc-2k of size 2048 | |
The buggy address is located 388 bytes inside of | |
freed 2048-byte region [ffff88803bec8000, ffff88803bec8800) | |
The buggy address belongs to the physical page: | |
page:ffffea0000efb200 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x3bec8 | |
head:ffffea0000efb200 order:3 entire_mapcount:0 nr_pages_mapped:0 pincount:0 | |
flags: 0xfff80000000840(slab|head|node=0|zone=1|lastcpupid=0xfff) | |
page_type: 0xffffffff() | |
raw: 00fff80000000840 ffff888015042f00 ffffea00006ae600 dead000000000002 | |
raw: 0000000000000000 0000000080080008 00000001ffffffff 0000000000000000 | |
page dumped because: kasan: bad access detected | |
page_owner tracks the page as allocated | |
page last allocated via order 3, migratetype Unmovable, gfp_mask 0xd2820(GFP_ATOMIC|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC), pid 8202, tgid 8202 (syz-executor.2), ts 163667417341, free_ts 0 | |
set_page_owner include/linux/page_owner.h:31 [inline] | |
post_alloc_hook+0x1ea/0x210 mm/page_alloc.c:1533 | |
prep_new_page mm/page_alloc.c:1540 [inline] | |
get_page_from_freelist+0x33ea/0x3580 mm/page_alloc.c:3311 | |
__alloc_pages+0x256/0x6a0 mm/page_alloc.c:4567 | |
__alloc_pages_node include/linux/gfp.h:238 [inline] | |
alloc_pages_node include/linux/gfp.h:261 [inline] | |
alloc_slab_page+0x5f/0x160 mm/slub.c:2191 | |
allocate_slab mm/slub.c:2354 [inline] | |
new_slab+0x84/0x2f0 mm/slub.c:2407 | |
___slab_alloc+0xc73/0x1260 mm/slub.c:3541 | |
__slab_alloc mm/slub.c:3626 [inline] | |
__slab_alloc_node mm/slub.c:3679 [inline] | |
slab_alloc_node mm/slub.c:3851 [inline] | |
__do_kmalloc_node mm/slub.c:3981 [inline] | |
__kmalloc_node_track_caller+0x2d4/0x4e0 mm/slub.c:4002 | |
kmalloc_reserve+0xfd/0x250 net/core/skbuff.c:582 | |
pskb_expand_head+0x209/0x13a0 net/core/skbuff.c:2136 | |
netlink_trim+0x192/0x230 net/netlink/af_netlink.c:1323 | |
netlink_broadcast_filtered+0x7b/0x1300 net/netlink/af_netlink.c:1529 | |
nlmsg_multicast_filtered include/net/netlink.h:1111 [inline] | |
nlmsg_multicast include/net/netlink.h:1130 [inline] | |
nlmsg_notify+0x104/0x1d0 net/netlink/af_netlink.c:2586 | |
__dev_notify_flags+0xfe/0x410 net/core/dev.c:8720 | |
dev_change_flags+0xf7/0x1a0 net/core/dev.c:8762 | |
do_setlink+0xd12/0x43f0 net/core/rtnetlink.c:2897 | |
__rtnl_newlink net/core/rtnetlink.c:3695 [inline] | |
rtnl_newlink+0x18bc/0x2170 net/core/rtnetlink.c:3742 | |
page_owner free stack trace missing | |
Memory state around the buggy address: | |
ffff88803bec8080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb | |
ffff88803bec8100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb | |
>ffff88803bec8180: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb | |
^ | |
ffff88803bec8200: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb | |
ffff88803bec8280: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb | |
================================================================== |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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/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 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 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 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 void netlink_add_neigh(struct nlmsg* nlmsg, | |
int sock, | |
const char* name, | |
const void* addr, | |
int addrsize, | |
const void* mac, | |
int macsize) { | |
struct ndmsg hdr; | |
memset(&hdr, 0, sizeof(hdr)); | |
hdr.ndm_family = addrsize == 4 ? AF_INET : AF_INET6; | |
hdr.ndm_ifindex = if_nametoindex(name); | |
hdr.ndm_state = NUD_PERMANENT; | |
netlink_init(nlmsg, RTM_NEWNEIGH, NLM_F_EXCL | NLM_F_CREATE, &hdr, | |
sizeof(hdr)); | |
netlink_attr(nlmsg, NDA_DST, addr, addrsize); | |
netlink_attr(nlmsg, NDA_LLADDR, mac, macsize); | |
int err = netlink_send(nlmsg, sock); | |
if (err < 0) { | |
} | |
} | |
static struct nlmsg nlmsg; | |
static int tunfd = -1; | |
#define TUN_IFACE "syz_tun" | |
#define LOCAL_MAC 0xaaaaaaaaaaaa | |
#define REMOTE_MAC 0xaaaaaaaaaabb | |
#define LOCAL_IPV4 "172.20.20.170" | |
#define REMOTE_IPV4 "172.20.20.187" | |
#define LOCAL_IPV6 "fe80::aa" | |
#define REMOTE_IPV6 "fe80::bb" | |
#define IFF_NAPI 0x0010 | |
static void initialize_tun(void) { | |
tunfd = open("/dev/net/tun", O_RDWR | O_NONBLOCK); | |
if (tunfd == -1) { | |
printf("tun: can't open /dev/net/tun: please enable CONFIG_TUN=y\n"); | |
printf("otherwise fuzzing or reproducing might not work as intended\n"); | |
return; | |
} | |
const int kTunFd = 200; | |
if (dup2(tunfd, kTunFd) < 0) | |
exit(1); | |
close(tunfd); | |
tunfd = kTunFd; | |
struct ifreq ifr; | |
memset(&ifr, 0, sizeof(ifr)); | |
strncpy(ifr.ifr_name, TUN_IFACE, IFNAMSIZ); | |
ifr.ifr_flags = IFF_TAP | IFF_NO_PI; | |
if (ioctl(tunfd, TUNSETIFF, (void*)&ifr) < 0) { | |
exit(1); | |
} | |
char sysctl[64]; | |
sprintf(sysctl, "/proc/sys/net/ipv6/conf/%s/accept_dad", TUN_IFACE); | |
write_file(sysctl, "0"); | |
sprintf(sysctl, "/proc/sys/net/ipv6/conf/%s/router_solicitations", TUN_IFACE); | |
write_file(sysctl, "0"); | |
int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); | |
if (sock == -1) | |
exit(1); | |
netlink_add_addr4(&nlmsg, sock, TUN_IFACE, LOCAL_IPV4); | |
netlink_add_addr6(&nlmsg, sock, TUN_IFACE, LOCAL_IPV6); | |
uint64_t macaddr = REMOTE_MAC; | |
struct in_addr in_addr; | |
inet_pton(AF_INET, REMOTE_IPV4, &in_addr); | |
netlink_add_neigh(&nlmsg, sock, TUN_IFACE, &in_addr, sizeof(in_addr), | |
&macaddr, ETH_ALEN); | |
struct in6_addr in6_addr; | |
inet_pton(AF_INET6, REMOTE_IPV6, &in6_addr); | |
netlink_add_neigh(&nlmsg, sock, TUN_IFACE, &in6_addr, sizeof(in6_addr), | |
&macaddr, ETH_ALEN); | |
macaddr = LOCAL_MAC; | |
netlink_device_change(&nlmsg, sock, TUN_IFACE, true, 0, &macaddr, ETH_ALEN, | |
NULL); | |
close(sock); | |
} | |
static int read_tun(char* data, int size) { | |
if (tunfd < 0) | |
return -1; | |
int rv = read(tunfd, data, size); | |
if (rv < 0) { | |
if (errno == EAGAIN || errno == EBADFD) | |
return -1; | |
exit(1); | |
} | |
return rv; | |
} | |
static void flush_tun() { | |
char data[1000]; | |
while (read_tun(&data[0], sizeof(data)) != -1) { | |
} | |
} | |
#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 = 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(); | |
if (unshare(CLONE_NEWNET)) { | |
} | |
write_file("/proc/sys/net/ipv4/ping_group_range", "0 65535"); | |
initialize_tun(); | |
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"); | |
flush_tun(); | |
} | |
static void close_fds() { | |
for (int fd = 3; fd < MAX_FDS; fd++) | |
close(fd); | |
} | |
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; | |
} | |
} | |
} | |
uint64_t r[3] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff}; | |
void execute_one(void) { | |
intptr_t res = 0; | |
res = syscall(__NR_socket, /*domain=*/0x10ul, /*type=*/3ul, /*proto=*/0x14); | |
if (res != -1) | |
r[0] = res; | |
*(uint64_t*)0x20000180 = 0; | |
*(uint32_t*)0x20000188 = 0; | |
*(uint64_t*)0x20000190 = 0x20000140; | |
*(uint64_t*)0x20000140 = 0x20000080; | |
*(uint32_t*)0x20000080 = 0x38; | |
*(uint16_t*)0x20000084 = 0x1403; | |
*(uint16_t*)0x20000086 = 1; | |
*(uint32_t*)0x20000088 = 0; | |
*(uint32_t*)0x2000008c = 0; | |
*(uint16_t*)0x20000090 = 9; | |
*(uint16_t*)0x20000092 = 2; | |
memcpy((void*)0x20000094, "syz1\000", 5); | |
*(uint16_t*)0x2000009c = 8; | |
*(uint16_t*)0x2000009e = 0x41; | |
memcpy((void*)0x200000a0, "rxe\000", 4); | |
*(uint16_t*)0x200000a4 = 0x14; | |
*(uint16_t*)0x200000a6 = 0x33; | |
memcpy((void*)0x200000a8, "syz_tun\000\000\000\000\000\000\000\000\000", 16); | |
*(uint64_t*)0x20000148 = 0x38; | |
*(uint64_t*)0x20000198 = 1; | |
*(uint64_t*)0x200001a0 = 0; | |
*(uint64_t*)0x200001a8 = 0; | |
*(uint32_t*)0x200001b0 = 0; | |
syscall(__NR_sendmsg, /*fd=*/r[0], /*msg=*/0x20000180ul, /*f=*/0ul); | |
memcpy((void*)0x20000100, "/dev/infiniband/rdma_cm\000", 24); | |
res = syscall(__NR_openat, /*fd=*/0xffffffffffffff9cul, /*file=*/0x20000100ul, | |
/*flags=*/2ul, /*mode=*/0ul); | |
if (res != -1) | |
r[1] = res; | |
*(uint32_t*)0x20000080 = 0; | |
*(uint16_t*)0x20000084 = 0x18; | |
*(uint16_t*)0x20000086 = 0xfa00; | |
*(uint64_t*)0x20000088 = 0; | |
*(uint64_t*)0x20000090 = 0x200000c0; | |
*(uint16_t*)0x20000098 = 0x106; | |
*(uint8_t*)0x2000009a = 0; | |
memset((void*)0x2000009b, 0, 5); | |
res = syscall(__NR_write, /*fd=*/r[1], /*data=*/0x20000080ul, /*len=*/0x20ul); | |
if (res != -1) | |
r[2] = *(uint32_t*)0x200000c0; | |
*(uint32_t*)0x200003c0 = 3; | |
*(uint16_t*)0x200003c4 = 0x40; | |
*(uint16_t*)0x200003c6 = 0xfa00; | |
*(uint16_t*)0x200003c8 = 0xa; | |
*(uint16_t*)0x200003ca = htobe16(0x4e24); | |
*(uint32_t*)0x200003cc = htobe32(1); | |
*(uint8_t*)0x200003d0 = -1; | |
*(uint8_t*)0x200003d1 = 2; | |
memset((void*)0x200003d2, 0, 13); | |
*(uint8_t*)0x200003df = 1; | |
*(uint32_t*)0x200003e0 = 9; | |
*(uint16_t*)0x200003e4 = 0xa; | |
*(uint16_t*)0x200003e6 = htobe16(0); | |
*(uint32_t*)0x200003e8 = htobe32(6); | |
*(uint8_t*)0x200003ec = 0xfe; | |
*(uint8_t*)0x200003ed = 0x80; | |
memset((void*)0x200003ee, 0, 13); | |
*(uint8_t*)0x200003fb = 0xbb; | |
*(uint32_t*)0x200003fc = 0xfffff000; | |
*(uint32_t*)0x20000400 = r[2]; | |
*(uint32_t*)0x20000404 = 2; | |
syscall(__NR_write, /*fd=*/r[1], /*data=*/0x200003c0ul, /*len=*/0x48ul); | |
*(uint32_t*)0x20000140 = 0x15; | |
*(uint16_t*)0x20000144 = 0x110; | |
*(uint16_t*)0x20000146 = 0xfa00; | |
*(uint32_t*)0x20000148 = r[2]; | |
*(uint32_t*)0x2000014c = 0; | |
*(uint16_t*)0x20000150 = 0; | |
*(uint16_t*)0x20000152 = 0x30; | |
*(uint32_t*)0x20000154 = 0; | |
*(uint16_t*)0x20000158 = 0x1b; | |
*(uint16_t*)0x2000015a = htobe16(0); | |
*(uint32_t*)0x2000015c = htobe32(0); | |
memset((void*)0x20000160, 0, 16); | |
*(uint32_t*)0x20000170 = 0; | |
*(uint16_t*)0x200001d8 = 0x1b; | |
*(uint16_t*)0x200001da = htobe16(0); | |
*(uint32_t*)0x200001dc = htobe32(0); | |
memset((void*)0x200001e0, 0, 16); | |
*(uint64_t*)0x200001f0 = htobe64(0); | |
*(uint64_t*)0x200001f8 = htobe64(0); | |
*(uint64_t*)0x20000200 = 0; | |
syscall(__NR_write, /*fd=*/r[1], /*data=*/0x20000140ul, /*len=*/0x118ul); | |
*(uint32_t*)0x20000440 = 4; | |
*(uint16_t*)0x20000444 = 8; | |
*(uint16_t*)0x20000446 = 0xfa00; | |
*(uint32_t*)0x20000448 = r[2]; | |
*(uint32_t*)0x2000044c = 0xffff741a; | |
syscall(__NR_write, /*fd=*/r[1], /*data=*/0x20000440ul, /*len=*/0x10ul); | |
} | |
int main(void) { | |
syscall(__NR_mmap, /*addr=*/0x1ffff000ul, /*len=*/0x1000ul, /*prot=*/0ul, | |
/*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1, | |
/*offset=*/0ul); | |
syscall(__NR_mmap, /*addr=*/0x20000000ul, /*len=*/0x1000000ul, | |
/*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul, | |
/*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1, | |
/*offset=*/0ul); | |
syscall(__NR_mmap, /*addr=*/0x21000000ul, /*len=*/0x1000ul, /*prot=*/0ul, | |
/*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x32ul, /*fd=*/-1, | |
/*offset=*/0ul); | |
do_sandbox_none(); | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
r0 = socket$nl_rdma(0x10, 0x3, 0x14) | |
sendmsg$RDMA_NLDEV_CMD_NEWLINK(r0, &(0x7f0000000180)={0x0, 0x0, &(0x7f0000000140)={&(0x7f0000000080)={0x38, 0x1403, 0x1, 0x0, 0x0, "", [{{0x9, 0x2, 'syz1\x00'}, {0x8, 0x41, 'rxe\x00'}, {0x14, 0x33, 'syz_tun\x00'}}]}, 0x38}}, 0x0) | |
r1 = openat$rdma_cm(0xffffffffffffff9c, &(0x7f0000000100), 0x2, 0x0) | |
write$RDMA_USER_CM_CMD_CREATE_ID(r1, &(0x7f0000000080)={0x0, 0x18, 0xfa00, {0x0, &(0x7f00000000c0)={<r2=>0xffffffffffffffff}, 0x106}}, 0x20) | |
write$RDMA_USER_CM_CMD_RESOLVE_IP(r1, &(0x7f00000003c0)={0x3, 0x40, 0xfa00, {{0xa, 0x4e24, 0x1, @mcast2, 0x9}, {0xa, 0x0, 0x6, @remote, 0xfffff000}, r2, 0x2}}, 0x48) | |
write$RDMA_USER_CM_CMD_RESOLVE_ADDR(r1, &(0x7f0000000140)={0x15, 0x110, 0xfa00, {r2, 0x0, 0x0, 0x30, 0x0, @in6={0x1b, 0x0, 0x0, @empty}, @ib}}, 0x118) | |
write$RDMA_USER_CM_CMD_RESOLVE_ROUTE(r1, &(0x7f0000000440)={0x4, 0x8, 0xfa00, {r2, 0xffff741a}}, 0x10) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment