Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Add test for truncated dmabuf_iter reads

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>

authored by

T.J. Mercier and committed by
Alexei Starovoitov
9489d457 23448356

+42 -5
+42 -5
tools/testing/selftests/bpf/prog_tests/dmabuf_iter.c
··· 73 73 return -1; 74 74 } 75 75 76 - static int create_sys_heap_dmabuf(void) 76 + static int create_sys_heap_dmabuf(size_t bytes) 77 77 { 78 - sysheap_test_buffer_size = 20 * getpagesize(); 79 - 80 78 struct dma_heap_allocation_data data = { 81 - .len = sysheap_test_buffer_size, 79 + .len = bytes, 82 80 .fd = 0, 83 81 .fd_flags = O_RDWR | O_CLOEXEC, 84 82 .heap_flags = 0, ··· 108 110 static int create_test_buffers(void) 109 111 { 110 112 udmabuf = create_udmabuf(); 111 - sysheap_dmabuf = create_sys_heap_dmabuf(); 113 + 114 + sysheap_test_buffer_size = 20 * getpagesize(); 115 + sysheap_dmabuf = create_sys_heap_dmabuf(sysheap_test_buffer_size); 112 116 113 117 if (udmabuf < 0 || sysheap_dmabuf < 0) 114 118 return -1; ··· 219 219 close(iter_fd); 220 220 } 221 221 222 + static void subtest_dmabuf_iter_check_lots_of_buffers(struct dmabuf_iter *skel) 223 + { 224 + int iter_fd; 225 + char buf[1024]; 226 + size_t total_bytes_read = 0; 227 + ssize_t bytes_read; 228 + 229 + iter_fd = bpf_iter_create(bpf_link__fd(skel->links.dmabuf_collector)); 230 + if (!ASSERT_OK_FD(iter_fd, "iter_create")) 231 + return; 232 + 233 + while ((bytes_read = read(iter_fd, buf, sizeof(buf))) > 0) 234 + total_bytes_read += bytes_read; 235 + 236 + ASSERT_GT(total_bytes_read, getpagesize(), "total_bytes_read"); 237 + 238 + close(iter_fd); 239 + } 240 + 241 + 222 242 static void subtest_dmabuf_iter_check_open_coded(struct dmabuf_iter *skel, int map_fd) 223 243 { 224 244 LIBBPF_OPTS(bpf_test_run_opts, topts); ··· 295 275 subtest_dmabuf_iter_check_no_infinite_reads(skel); 296 276 if (test__start_subtest("default_iter")) 297 277 subtest_dmabuf_iter_check_default_iter(skel); 278 + if (test__start_subtest("lots_of_buffers")) { 279 + size_t NUM_BUFS = 100; 280 + int buffers[NUM_BUFS]; 281 + int i; 282 + 283 + for (i = 0; i < NUM_BUFS; ++i) { 284 + buffers[i] = create_sys_heap_dmabuf(getpagesize()); 285 + if (!ASSERT_OK_FD(buffers[i], "dmabuf_fd")) 286 + goto cleanup_bufs; 287 + } 288 + 289 + subtest_dmabuf_iter_check_lots_of_buffers(skel); 290 + 291 + cleanup_bufs: 292 + for (--i; i >= 0; --i) 293 + close(buffers[i]); 294 + } 298 295 if (test__start_subtest("open_coded")) 299 296 subtest_dmabuf_iter_check_open_coded(skel, map_fd); 300 297