summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmmar Faizi <ammar.faizi@students.amikom.ac.id>2021-10-10 13:39:03 +0700
committerJens Axboe <axboe@kernel.dk>2021-10-10 05:11:06 -0600
commitf6c1b4d7034f79b51cdacccfa2b5f33e9d0cf41c (patch)
tree993161f5e68d05a0b10ccd0c999f214e556b8230
parentabd495348b5e0efee0a87b9206174a232932c21e (diff)
downloadliburing-f6c1b4d7034f79b51cdacccfa2b5f33e9d0cf41c.tar.gz
liburing-f6c1b4d7034f79b51cdacccfa2b5f33e9d0cf41c.tar.bz2
test/thread-exit: Fix use after free bug
When I add support for nolibc x86-64, I find this test failed. Long story short, we provide our own `free()` that always unmaps the VM with `munmap()`. It makes the CQE return -EFAULT because the kernel reads unmapped user memory from the pending `write()` SQE. I believe this test can run properly with libc build because `free()` from libc doesn't always unmap the memory, instead it uses free list on the userspace and the freed heap may still be userspace addressable. Fix this by deferring the free. Cc: Jens Axboe <axboe@kernel.dk> Fixes: 2edfa3f84bcc44612b7a04caf1f048f5406fcc7a ("Add test case for thread exiting with pending IO") Signed-off-by: Ammar Faizi <ammar.faizi@students.amikom.ac.id> Link: https://lore.kernel.org/r/20211010063906.341014-2-ammar.faizi@students.amikom.ac.id Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--test/thread-exit.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/test/thread-exit.c b/test/thread-exit.c
index 7f66028..b26d4aa 100644
--- a/test/thread-exit.c
+++ b/test/thread-exit.c
@@ -26,8 +26,18 @@ struct d {
unsigned long off;
int pipe_fd;
int err;
+ int i;
};
+static char *g_buf[NR_IOS] = {NULL};
+
+static void free_g_buf(void)
+{
+ int i;
+ for (i = 0; i < NR_IOS; i++)
+ free(g_buf[i]);
+}
+
static void *do_io(void *data)
{
struct d *d = data;
@@ -36,6 +46,7 @@ static void *do_io(void *data)
int ret;
buffer = t_malloc(WSIZE);
+ g_buf[d->i] = buffer;
memset(buffer, 0x5a, WSIZE);
sqe = io_uring_get_sqe(d->ring);
if (!sqe) {
@@ -55,8 +66,6 @@ static void *do_io(void *data)
ret = io_uring_submit(d->ring);
if (ret != 2)
d->err++;
-
- free(buffer);
return NULL;
}
@@ -103,6 +112,7 @@ int main(int argc, char *argv[])
d.pipe_fd = fds[0];
d.err = 0;
for (i = 0; i < NR_IOS; i++) {
+ d.i = i;
memset(&thread, 0, sizeof(thread));
pthread_create(&thread, NULL, do_io, &d);
pthread_join(thread, NULL);
@@ -125,7 +135,9 @@ int main(int argc, char *argv[])
io_uring_cqe_seen(&ring, cqe);
}
+ free_g_buf();
return d.err;
err:
+ free_g_buf();
return 1;
}