Skip to content

Commit

Permalink
test/regbuf-clone: test dummy ubuf cloning
Browse files Browse the repository at this point in the history
The 6.12-rc kernels had a bug where the cloning would attempt to grab
a reference to a dummy ubuf that was assigned, which would crash the
kernel. Add a test case for that.

Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
axboe committed Oct 16, 2024
1 parent cbae992 commit 1419174
Showing 1 changed file with 60 additions and 0 deletions.
60 changes: 60 additions & 0 deletions test/regbuf-clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#define NR_VECS 64
#define BUF_SIZE 8192

static int no_buf_clone;

static int test(int reg_src, int reg_dst)
{
struct iovec vecs[NR_VECS];
Expand Down Expand Up @@ -54,6 +56,7 @@ static int test(int reg_src, int reg_dst)
ret = io_uring_clone_buffers(&dst, &src);
if (ret == -EINVAL) {
/* no buffer copy support */
no_buf_clone = true;
return T_EXIT_SKIP;
} else if (ret != -ENXIO) {
fprintf(stderr, "empty copy: %d\n", ret);
Expand Down Expand Up @@ -144,6 +147,53 @@ static int test(int reg_src, int reg_dst)
return T_EXIT_PASS;
}

static int test_dummy(void)
{
struct iovec vec = { };
struct io_uring src, dst;
int ret;

ret = io_uring_queue_init(1, &src, 0);
if (ret) {
fprintf(stderr, "ring_init: %d\n", ret);
return T_EXIT_FAIL;
}
ret = io_uring_queue_init(1, &dst, 0);
if (ret) {
fprintf(stderr, "ring_init: %d\n", ret);
return T_EXIT_FAIL;
}

ret = io_uring_register_buffers(&src, &vec, 1);
if (ret < 0) {
fprintf(stderr, "failed to register dummy buffer: %d\n", ret);
return T_EXIT_FAIL;
}

ret = io_uring_clone_buffers(&dst, &src);
if (ret) {
fprintf(stderr, "clone dummy buf: %d\n", ret);
return T_EXIT_FAIL;
}

ret = io_uring_unregister_buffers(&src);
if (ret) {
fprintf(stderr, "rsc unregister buffers: %d\n", ret);
return T_EXIT_FAIL;
}

ret = io_uring_unregister_buffers(&dst);
if (ret) {
fprintf(stderr, "dst unregister buffers: %d\n", ret);
return T_EXIT_FAIL;
}

io_uring_queue_exit(&src);
io_uring_queue_exit(&dst);

return T_EXIT_PASS;
}

int main(int argc, char *argv[])
{
int ret;
Expand All @@ -158,6 +208,8 @@ int main(int argc, char *argv[])
fprintf(stderr, "test 0 0 failed\n");
return T_EXIT_FAIL;
}
if (no_buf_clone)
return T_EXIT_SKIP;

ret = test(0, 1);
if (ret == T_EXIT_SKIP) {
Expand All @@ -183,5 +235,13 @@ int main(int argc, char *argv[])
return T_EXIT_FAIL;
}

ret = test_dummy();
if (ret == T_EXIT_SKIP) {
return T_EXIT_SKIP;
} else if (ret != T_EXIT_PASS) {
fprintf(stderr, "test_dummy failed\n");
return T_EXIT_FAIL;
}

return T_EXIT_PASS;
}

0 comments on commit 1419174

Please sign in to comment.