Commit 9489d457 authored by T.J. Mercier's avatar T.J. Mercier Committed by Alexei Starovoitov
Browse files

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: default avatarT.J. Mercier <tjmercier@google.com>
Link: https://lore.kernel.org/r/20251204000348.1413593-2-tjmercier@google.com


Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 23448356
Loading
Loading
Loading
Loading
+42 −5
Original line number Diff line number Diff line
@@ -73,12 +73,10 @@ static int create_udmabuf(void)
	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 @@ static int create_sys_heap_dmabuf(void)
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 @@ static void subtest_dmabuf_iter_check_default_iter(struct dmabuf_iter *skel)
	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);