File Index
Files and directories
Sign in
FILE

file_reader.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/bpf/prog_tests/file_reader.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
  3
  4#include <test_progs.h>
  5#include <network_helpers.h>
  6#include "file_reader.skel.h"
  7#include "file_reader_fail.skel.h"
  8#include <dlfcn.h>
  9#include <sys/mman.h>
 10
 11const char *user_ptr = "hello world";
 12char file_contents[256000];
 13
 14void *get_executable_base_addr(void)
 15{
 16	Dl_info info;
 17
 18	if (!dladdr((void *)&get_executable_base_addr, &info)) {
 19		fprintf(stderr, "dladdr failed\n");
 20		return NULL;
 21	}
 22
 23	return info.dli_fbase;
 24}
 25
 26static int initialize_file_contents(void)
 27{
 28	int fd, page_sz = sysconf(_SC_PAGESIZE);
 29	ssize_t n = 0, cur, off;
 30	void *addr;
 31
 32	fd = open("/proc/self/exe", O_RDONLY);
 33	if (!ASSERT_OK_FD(fd, "Open /proc/self/exe\n"))
 34		return 1;
 35
 36	do {
 37		cur = read(fd, file_contents + n, sizeof(file_contents) - n);
 38		if (!ASSERT_GT(cur, 0, "read success"))
 39			break;
 40		n += cur;
 41	} while (n < sizeof(file_contents));
 42
 43	close(fd);
 44
 45	if (!ASSERT_EQ(n, sizeof(file_contents), "Read /proc/self/exe\n"))
 46		return 1;
 47
 48	addr = get_executable_base_addr();
 49	if (!ASSERT_NEQ(addr, NULL, "get executable address"))
 50		return 1;
 51
 52	/* page-align base file address */
 53	addr = (void *)((unsigned long)addr & ~(page_sz - 1));
 54
 55	/*
 56	 * Page out range 0..512K, use 0..256K for positive tests and
 57	 * 256K..512K for negative tests expecting page faults
 58	 */
 59	for (off = 0; off < sizeof(file_contents) * 2; off += page_sz) {
 60		if (!ASSERT_OK(madvise(addr + off, page_sz, MADV_PAGEOUT),
 61			       "madvise pageout"))
 62			return errno;
 63	}
 64
 65	return 0;
 66}
 67
 68static void run_test(const char *prog_name)
 69{
 70	struct file_reader *skel;
 71	struct bpf_program *prog;
 72	int err, fd;
 73
 74	err = initialize_file_contents();
 75	if (!ASSERT_OK(err, "initialize file contents"))
 76		return;
 77
 78	skel = file_reader__open();
 79	if (!ASSERT_OK_PTR(skel, "file_reader__open"))
 80		return;
 81
 82	bpf_object__for_each_program(prog, skel->obj) {
 83		bpf_program__set_autoload(prog, strcmp(bpf_program__name(prog), prog_name) == 0);
 84	}
 85
 86	memcpy(skel->bss->user_buf, file_contents, sizeof(file_contents));
 87	skel->bss->pid = getpid();
 88
 89	err = file_reader__load(skel);
 90	if (!ASSERT_OK(err, "file_reader__load"))
 91		goto cleanup;
 92
 93	err = file_reader__attach(skel);
 94	if (!ASSERT_OK(err, "file_reader__attach"))
 95		goto cleanup;
 96
 97	fd = open("/proc/self/exe", O_RDONLY);
 98	if (fd >= 0)
 99		close(fd);
100
101	ASSERT_EQ(skel->bss->err, 0, "err");
102	ASSERT_EQ(skel->bss->run_success, 1, "run_success");
103cleanup:
104	file_reader__destroy(skel);
105}
106
107void test_file_reader(void)
108{
109	if (test__start_subtest("on_open_expect_fault"))
110		run_test("on_open_expect_fault");
111
112	if (test__start_subtest("on_open_validate_file_read"))
113		run_test("on_open_validate_file_read");
114
115	if (test__start_subtest("negative"))
116		RUN_TESTS(file_reader_fail);
117}
~/ Read-only file preview.