/ 详情

【kernel fuzz】【syzkaller】20.03 LTS 内核fuzz use-after-free Bug

Backlog
Bug
Opened this issue  
2021-01-18 19:09

kernel fuzz 测试跑出多个与virtio gpu相关use after free bug,相应日志和测试C代码如下:

Syzkaller hit 'KASAN: use-after-free Read in virtio_gpu_object_attach' bug.

Free swap = 8072128kB
Total swap = 8318912kB
129472 pages RAM
0 pages HighMem/MovableOnly

BUG: KASAN: use-after-free in virtio_gpu_object_attach+0x120/0x2b8 [virtio_gpu]
Read of size 4 at addr ffffd7aa2020998c by task syz-executor842/2286

Syzkaller reproducer:

{Threaded:false Collide:false Repeat:true RepeatTimes:0 Procs:4 Slowdown:1 Sandbox: Fault:false FaultCall:-1 FaultNth:0 Leak:false NetInjection:false NetDevices:false NetReset:false Cgroups:false BinfmtMisc:false CloseFDs:false KCSAN:false DevlinkPCI:false USB:false VhciInjection:false Wifi:false Sysctl:false UseTmpDir:false HandleSegv:false Repro:false Trace:false}

r0 = syz_open_dev$dri(&(0x7f0000000040)='/dev/dri/card#\x00', 0x0, 0x0)
ioctl$DRM_IOCTL_MODE_CREATE_DUMB(0xffffffffffffffff, 0xc02064b2, 0x0)
ioctl$DRM_IOCTL_MODE_DESTROY_DUMB(r0, 0xc00464b4, 0x0)
openat(0xffffffffffffffff, 0x0, 0x10000, 0x29)
ioctl$DRM_IOCTL_MODE_CREATE_DUMB(r0, 0xc02064b2, &(0x7f0000000100)={0x5dd, 0x100, 0xffff})

C reproducer:
// autogenerated by syzkaller (https://github.com/google/syzkaller)

#define _GNU_SOURCE

#include <dirent.h>
#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.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;
}

static long syz_open_dev(volatile long a0, volatile long a1, volatile long a2)
{
if (a0 == 0xc || a0 == 0xb) {
char buf[128];
sprintf(buf, "/dev/%s/%d:%d", a0 == 0xc ? "char" : "block", (uint8_t)a1, (uint8_t)a2);
return open(buf, O_RDWR, 0);
} else {
char buf[1024];
char* hash;
strncpy(buf, (char*)a0, sizeof(buf) - 1);
buf[sizeof(buf) - 1] = 0;
while ((hash = strchr(buf, '#'))) {
*hash = '0' + (char)(a1 % 10);
a1 /= 10;
}
return open(buf, a2, 0);
}
}

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 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();
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;
}
}
}

#ifndef __NR_ioctl
#define __NR_ioctl 29
#endif
#ifndef __NR_mmap
#define __NR_mmap 222
#endif
#ifndef __NR_openat
#define __NR_openat 56
#endif

uint64_t r[1] = {0xffffffffffffffff};

void execute_one(void)
{
intptr_t res = 0;
memcpy((void*)0x20000040, "/dev/dri/card#\000", 15);
res = -1;
res = syz_open_dev(0x20000040, 0, 0);
if (res != -1)
r[0] = res;
syscall(__NR_ioctl, -1, 0xc02064b2, 0ul);
syscall(__NR_ioctl, r[0], 0xc00464b4, 0ul);
syscall(__NR_openat, -1, 0ul, 0x10000ul, 0x29ul);
(uint32_t)0x20000100 = 0x5dd;
(uint32_t)0x20000104 = 0x100;
(uint32_t)0x20000108 = 0xffff;
(uint32_t)0x2000010c = 0;
syscall(__NR_ioctl, r[0], 0xc02064b2, 0x20000100ul);

}
int main(void)
{
syscall(__NR_mmap, 0x1fff0000ul, 0x10000ul, 0ul, 0x32ul, -1, 0ul);
syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
syscall(__NR_mmap, 0x21000000ul, 0x10000ul, 0ul, 0x32ul, -1, 0ul);
for (procid = 0; procid < 4; procid++) {
if (fork() == 0) {
loop();
}
}
sleep(1000000);
return 0;
}

Attachments

Comments (1)

heruxiao created缺陷
heruxiao set assignee to XieXiuQi
heruxiao set branch to openEuler-1.0-LTS
heruxiao set related repository to openEuler/kernel
展开全部操作日志

其他类似的bug日志如下,从调用栈看都是virtio_gpu_object_attach这个函数出现的bug

[TTM] Illegal buffer object size

BUG: KASAN: use-after-free in virtio_gpu_object_attach+0xc4/0x2b8 [virtio_gpu]
Read of size 8 at addr ffff82f0aea30000 by task syz-executor.0/205860

CPU: 1 PID: 205860 Comm: syz-executor.0 Kdump: loaded Not tainted 4.19.90 #1
Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015
Call trace:
dump_backtrace+0x0/0x2b8
show_stack+0x28/0x38
dump_stack+0xd4/0x12c
print_address_description+0x6c/0x264
kasan_report+0x198/0x330
__asan_load8+0x84/0xa8
virtio_gpu_object_attach+0xc4/0x2b8 [virtio_gpu]
virtio_gpu_mode_dumb_create+0x1c4/0x1f8 [virtio_gpu]
drm_mode_create_dumb+0x114/0x148
drm_mode_create_dumb_ioctl+0x38/0x48
drm_ioctl_kernel+0x164/0x1c0
drm_ioctl+0x3d8/0x680
do_vfs_ioctl+0x5e8/0xb70
ksys_ioctl+0x98/0xd8
__arm64_sys_ioctl+0x50/0xc8
el0_svc_common+0xb4/0x1d0
el0_svc_handler+0x50/0xa0
el0_svc+0x8/0x1b0

The buggy address belongs to the page:
page:ffff7fe0bc2ba8c0 count:0 mapcount:0 mapping:0000000000000000 index:0x0
flags: 0x3ffff0000000000()
raw: 03ffff0000000000 ffff82f1b5ba8d68 ffff7fe0bc2ba908 0000000000000000
raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
ffff82f0aea2ff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff82f0aea2ff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

ffff82f0aea30000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
^
ffff82f0aea30080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
ffff82f0aea30100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
==================================================================
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
Mem abort info:
ESR = 0x96000007
Exception class = DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000007
CM = 0, WnR = 0
user pgtable: 64k pages, 48-bit VAs, pgdp = 00000000b39413f6
[0000000000000008] pgd=000000016a080003, pud=000000016a080003, pmd=00000001a5d40003, pte=0000000000000000
Internal error: Oops: 96000007 [#1] SMP
Modules linked in: vhost_net nfnetlink_queue twofish_generic twofish_common camellia_generic serpent_generic blowfish_generic blowfish_common cast5_generic cast_common des_generic rmd160 sha512_generic scsi_transport_iscsi vhost_vsock vmw_vsock_virtio_transport_common vhost vsock dlci nfnetlink_acct nf_conntrack_netlink nfnetlink_log crypto_user l2tp_ip6 l2tp_ppp nf_tables devlink can_raw af_key atm l2tp_netlink pppoe cuse fuse can_bcm can l2tp_ip l2tp_core pptp pppox ppp_generic slhc cfg80211 uhid loop uinput ip6_vti ip_vti ip_gre ipip sit tunnel4 ip_tunnel geneve ip6_udp_tunnel udp_tunnel macsec macvtap tap ipvlan macvlan 8021q garp mrp veth nlmon dummy team bonding vcan ip6_gre ip6_tunnel tunnel6 gre tun binfmt_misc ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4
xt_conntrack ebtable_filter ebtable_nat ebtable_broute bridge stp llc ebtables ip6table_nat nf_nat_ipv6 ip6table_mangle ip6table_raw ip6table_security iptable_nat nf_nat_ipv4 nf_nat iptable_mangle iptable_raw iptable_security nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 libcrc32c rfkill ip_set nfnetlink ip6table_filter ip6_tables iptable_filter vfat fat aes_ce_blk crypto_simd cryptd aes_ce_cipher ghash_ce sha2_ce sha256_arm64 sha1_ce sch_fq_codel ip_tables ext4 mbcache jbd2 virtio_gpu virtio_net virtio_blk net_failover failover virtio_pci virtio_mmio dm_mirror dm_region_hash dm_log dm_mod virtio_rng virtio_ring virtio
Process syz-executor.0 (pid: 205860, stack limit = 0x00000000b064e870)
CPU: 1 PID: 205860 Comm: syz-executor.0 Kdump: loaded Tainted: G B 4.19.90 #1
Hardware name: QEMU KVM Virtual Machine, BIOS 0.0.0 02/06/2015
pstate: 40400005 (nZcv daif +PAN -UAO)
pc : virtio_gpu_object_attach+0x15c/0x2b8 [virtio_gpu]
lr : virtio_gpu_object_attach+0x15c/0x2b8 [virtio_gpu]
sp : ffff82f1613f7810
x29: ffff82f1613f7810 x28: 0000000000000001
x27: 0000000020000000 x26: 0000000040000000
x25: ffff82f0aea30008 x24: ffff82f166801bf8
x23: ffff82f166801b00 x22: ffff2000611bc110
x21: ffff82f0aeb80000 x20: 0000000000000000
x19: ffff82f0aea30020 x18: 0000000000000000
x17: 0000000000000000 x16: ffff200060072990
x15: 0000000000000000 x14: 1ffff05e2c27edea
x13: 0000000041b58ab3 x12: 1ffff05e2c27ee44
x11: ffff105e2c27ee44 x10: dfff200000000000
x9 : ffff105e2c27ee45 x8 : 0000efa1d3d811c5
x7 : 000000000000000a x6 : ffff82f1613f7227
x5 : 0000000000000001 x4 : 0000000000000000
x3 : ffff20000370616c x2 : ffff20006231c000
x1 : 6cb21e789a15c100 x0 : 0000000000000000
Call trace:
virtio_gpu_object_attach+0x15c/0x2b8 [virtio_gpu]
virtio_gpu_mode_dumb_create+0x1c4/0x1f8 [virtio_gpu]
drm_mode_create_dumb+0x114/0x148
drm_mode_create_dumb_ioctl+0x38/0x48
drm_ioctl_kernel+0x164/0x1c0
drm_ioctl+0x3d8/0x680
do_vfs_ioctl+0x5e8/0xb70
ksys_ioctl+0x98/0xd8
__arm64_sys_ioctl+0x50/0xc8
el0_svc_common+0xb4/0x1d0
el0_svc_handler+0x50/0xa0
el0_svc+0x8/0x1b0
Code: 9400150d f9407ef4 91002280 940014fe (b9400a94)
SMP: stopping secondary CPUs
Starting crashdump kernel...
Bye!

heruxiao changed title
heruxiao changed description

Sign in to comment

状态
Assignees
Projects
Milestones
Pull Requests
关联的 Pull Requests 被合并后可能会关闭此 issue
Branches
Planed to start   -   Planed to end
-
Top level
Priority
Duration (hours)
确定
参与者(1)