summary refs log tree commit diff stats
path: root/results/classifier/zero-shot/118/none/845
blob: 1e5921bf36a1f60ce60fb5a1247f9bd0fa23aa89 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
assembly: 0.658
ppc: 0.656
performance: 0.654
device: 0.648
architecture: 0.647
graphic: 0.626
permissions: 0.619
arm: 0.605
hypervisor: 0.604
PID: 0.592
TCG: 0.592
user-level: 0.587
peripherals: 0.583
virtual: 0.568
semantic: 0.553
register: 0.551
risc-v: 0.543
debug: 0.530
boot: 0.527
VMM: 0.503
vnc: 0.500
x86: 0.493
KVM: 0.480
network: 0.462
files: 0.461
kernel: 0.457
mistranslation: 0.449
i386: 0.426
socket: 0.425

Heap-use-after-free in remote_object_finalize
Description of problem:
While I was working with `QIOChannel` in my downstream QEMU fork, I looked at `hw/remote/remote-obj.c` as a usage example.

I did the same thing to `remote_object_finalize` function in order to free the QIOChannel when the connection closed:

```c
    if (o->ioc) {
        qio_channel_shutdown(o->ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
        qio_channel_close(o->ioc, NULL);
    }

    object_unref(OBJECT(o->ioc));
```

After the connection is closed for a while, my program SIGSEGV:

```
Thread 2 Crashed:
0   qemu-system-aarch64           	0x000000010164513c qemu_coroutine_get_aio_context + 12 (qemu-coroutine.c:203)
1   qemu-system-aarch64           	0x000000010145ad82 qio_channel_restart_read + 50
2   qemu-system-aarch64           	0x0000000101614c8a aio_dispatch_handler + 378 (aio-posix.c:332)
3   qemu-system-aarch64           	0x0000000101613fad aio_dispatch_handlers + 125 (aio-posix.c:372)
4   qemu-system-aarch64           	0x0000000101613ef3 aio_dispatch + 51 (aio-posix.c:383)
5   qemu-system-aarch64           	0x0000000101631e18 aio_ctx_dispatch + 104 (async.c:307)
6   libglib-2.0.0.dylib           	0x000000010284b90c g_main_context_dispatch + 364
7   qemu-system-aarch64           	0x0000000101644728 glib_pollfds_poll + 88 (main-loop.c:233)
8   qemu-system-aarch64           	0x0000000101644170 os_host_main_loop_wait + 128 (main-loop.c:256)
9   qemu-system-aarch64           	0x000000010164403c main_loop_wait + 188 (main-loop.c:530)
10  qemu-system-aarch64           	0x00000001012f3014 qemu_main_loop + 36 (runstate.c:721)
11  qemu-system-aarch64           	0x0000000100c25e38 qemu_main + 40 (main.c:51)
12  qemu-system-aarch64           	0x0000000100c7b1f4 call_qemu_main + 52 (cocoa.m:1746)
13  qemu-system-aarch64           	0x000000010161a459 qemu_thread_start + 185 (qemu-thread-posix.c:521)
14  libsystem_pthread.dylib       	0x00007fff6a6e2109 _pthread_start + 148
15  libsystem_pthread.dylib       	0x00007fff6a6ddb8b thread_start + 15
```

So apparently, there is a dangling pointer of the QIOChannel in AIOContext.

And indeed, that caused by the fact that when the fd read/write is blocked, it sets the fd handlers to the AIO context before yielding the coroutine (https://gitlab.com/qemu-project/qemu/-/blob/master/io/channel.c#L544).

So after the fd is closed, the AIO still dispatches the fd readable event when the main loop dispatches again, using the dangling QIOChannel pointer (When the fd is reused I think).

I suggest adding a `qio_channel_detach_aio_context()` call before the channel is shutdown in `remote-obj.c`, or before the fd is closed in `qio_channel_close()` in `io/channel.c`

```c

    if (o->ioc) {
        qio_channel_detach_aio_context(o->ioc);
        qio_channel_shutdown(o->ioc, QIO_CHANNEL_SHUTDOWN_BOTH, NULL);
        qio_channel_close(o->ioc, NULL);
    }

    object_unref(OBJECT(o->ioc));
```

This bug might have slipped through the cracks because `mpqemu_remote_msg_loop_co` issues a shutdown request immediately after an I/O error occured on the QIOChannel.
Additional information: