]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
selftests/bpf: Add test for truncated dmabuf_iter reads
authorT.J. Mercier <tjmercier@google.com>
Thu, 4 Dec 2025 00:03:48 +0000 (16:03 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 10 Dec 2025 07:49:04 +0000 (23:49 -0800)
If many dmabufs are present, reads of the dmabuf iterator can be
truncated at PAGE_SIZE or user buffer size boundaries before the fix in
"bpf: Fix truncated dmabuf iterator reads". Add a test to
confirm truncation does not occur.

Signed-off-by: T.J. Mercier <tjmercier@google.com>
Link: https://lore.kernel.org/r/20251204000348.1413593-2-tjmercier@google.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/prog_tests/dmabuf_iter.c

index 6c2b0c3dbcd86c14a40657667e8a1c90b2b91072..e442be9dde7e1501b00cb2530bb4ff333c29985a 100644 (file)
@@ -73,12 +73,10 @@ close_memfd:
        return -1;
 }
 
-static int create_sys_heap_dmabuf(void)
+static int create_sys_heap_dmabuf(size_t bytes)
 {
-       sysheap_test_buffer_size = 20 * getpagesize();
-
        struct dma_heap_allocation_data data = {
-               .len = sysheap_test_buffer_size,
+               .len = bytes,
                .fd = 0,
                .fd_flags = O_RDWR | O_CLOEXEC,
                .heap_flags = 0,
@@ -110,7 +108,9 @@ close_sysheap_dmabuf:
 static int create_test_buffers(void)
 {
        udmabuf = create_udmabuf();
-       sysheap_dmabuf = create_sys_heap_dmabuf();
+
+       sysheap_test_buffer_size = 20 * getpagesize();
+       sysheap_dmabuf = create_sys_heap_dmabuf(sysheap_test_buffer_size);
 
        if (udmabuf < 0 || sysheap_dmabuf < 0)
                return -1;
@@ -219,6 +219,26 @@ close_iter_fd:
        close(iter_fd);
 }
 
+static void subtest_dmabuf_iter_check_lots_of_buffers(struct dmabuf_iter *skel)
+{
+       int iter_fd;
+       char buf[1024];
+       size_t total_bytes_read = 0;
+       ssize_t bytes_read;
+
+       iter_fd = bpf_iter_create(bpf_link__fd(skel->links.dmabuf_collector));
+       if (!ASSERT_OK_FD(iter_fd, "iter_create"))
+               return;
+
+       while ((bytes_read = read(iter_fd, buf, sizeof(buf))) > 0)
+               total_bytes_read += bytes_read;
+
+       ASSERT_GT(total_bytes_read, getpagesize(), "total_bytes_read");
+
+       close(iter_fd);
+}
+
+
 static void subtest_dmabuf_iter_check_open_coded(struct dmabuf_iter *skel, int map_fd)
 {
        LIBBPF_OPTS(bpf_test_run_opts, topts);
@@ -275,6 +295,23 @@ void test_dmabuf_iter(void)
                subtest_dmabuf_iter_check_no_infinite_reads(skel);
        if (test__start_subtest("default_iter"))
                subtest_dmabuf_iter_check_default_iter(skel);
+       if (test__start_subtest("lots_of_buffers")) {
+               size_t NUM_BUFS = 100;
+               int buffers[NUM_BUFS];
+               int i;
+
+               for (i = 0; i < NUM_BUFS; ++i) {
+                       buffers[i] = create_sys_heap_dmabuf(getpagesize());
+                       if (!ASSERT_OK_FD(buffers[i], "dmabuf_fd"))
+                               goto cleanup_bufs;
+               }
+
+               subtest_dmabuf_iter_check_lots_of_buffers(skel);
+
+cleanup_bufs:
+               for (--i; i >= 0; --i)
+                       close(buffers[i]);
+       }
        if (test__start_subtest("open_coded"))
                subtest_dmabuf_iter_check_open_coded(skel, map_fd);