From: Jiri Olsa <jolsa@kernel.org>
To: Alexei Starovoitov <ast@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>
Cc: bpf@vger.kernel.org, Andrii Nakryiko <andrii@kernel.org>,
Eduard Zingerman <eddyz87@gmail.com>,
Kumar Kartikeya Dwivedi <memxor@gmail.com>,
linux-mm@kvack.org, Andrew Morton <akpm@linux-foundation.org>,
"Liam R. Howlett" <liam@infradead.org>,
Lorenzo Stoakes <ljs@kernel.org>,
linux-kselftest@vger.kernel.org, Shuah Khan <shuah@kernel.org>,
John Fastabend <john.fastabend@gmail.com>
Subject: [RFC bpf-next 9/9] selftests/bpf: Add user page failures test
Date: Wed, 21 Oct 2026 21:57:58 +0200 [thread overview]
Message-ID: <20261021195759.119421-10-jolsa@kernel.org> (raw)
In-Reply-To: <20261021195759.119421-1-jolsa@kernel.org>
Cover expected failures for invalid allocation sizes, misaligned or
unrelated exec requests, replacement of sealed mappings, repeated
execution, bad writes and attempts to restore write permission.
Assisted-by: Codex:GPT-6
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
.../selftests/bpf/prog_tests/user_page.c | 141 ++++++++++++++++++
tools/testing/selftests/bpf/progs/user_page.c | 5 +
2 files changed, 146 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/user_page.c b/tools/testing/selftests/bpf/prog_tests/user_page.c
index 74ce52d726ec..107349aace94 100644
--- a/tools/testing/selftests/bpf/prog_tests/user_page.c
+++ b/tools/testing/selftests/bpf/prog_tests/user_page.c
@@ -12,6 +12,7 @@ enum {
USER_PAGE_EXEC = 2,
USER_PAGE_EXEC_ONLY = 3,
USER_PAGE_WRITE = 4,
+ USER_PAGE_BAD_WRITE = 5,
};
static noinline void user_page_trigger(void)
@@ -209,6 +210,144 @@ static void test_faultable_write(struct user_page *skel)
munmap((void *)addr, page_size);
}
+static void test_invalid_allocation_size(struct user_page *skel)
+{
+ skel->bss->action = USER_PAGE_ALLOC;
+ skel->bss->nr_pages = 0;
+ user_page_trigger();
+ if (!ASSERT_EQ(skel->bss->user_addr, -EINVAL, "zero_pages_ret"))
+ return;
+
+ skel->bss->nr_pages = ~0UL;
+ user_page_trigger();
+ ASSERT_EQ(skel->bss->user_addr, -EINVAL, "overflow_pages_ret");
+}
+
+static void test_misaligned_exec(struct user_page *skel)
+{
+ long page_size = sysconf(_SC_PAGESIZE);
+ long addr = -1;
+
+ if (!alloc_user_pages(skel, 1, &addr))
+ return;
+
+ skel->bss->exec_addr = addr + 1;
+ skel->bss->action = USER_PAGE_EXEC_ONLY;
+ user_page_trigger();
+ ASSERT_EQ(skel->bss->exec_ret, -EINVAL, "misaligned_exec_ret");
+
+ if (addr >= 0)
+ munmap((void *)addr, page_size);
+}
+
+static void test_reject_replacement(struct user_page *skel)
+{
+ long page_size = sysconf(_SC_PAGESIZE);
+ long addr = -1;
+ void *ret;
+
+ if (!alloc_user_pages(skel, 1, &addr))
+ return;
+
+ ret = mmap((void *)addr, page_size, PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
+ if (!ASSERT_EQ(ret, (void *)addr, "replace_mmap"))
+ goto out;
+
+ skel->bss->exec_addr = addr;
+ skel->bss->action = USER_PAGE_EXEC_ONLY;
+ user_page_trigger();
+ ASSERT_EQ(skel->bss->exec_ret, -EINVAL, "replacement_not_bpf");
+
+out:
+ if (addr >= 0)
+ munmap((void *)addr, page_size);
+}
+
+static void test_bad_write(struct user_page *skel)
+{
+ skel->bss->action = USER_PAGE_BAD_WRITE;
+ user_page_trigger();
+ ASSERT_EQ(skel->bss->write_ret, -EFAULT, "bad_write_ret");
+}
+
+static void test_unrelated_mapping_exec_rejected(struct user_page *skel)
+{
+ long page_size = sysconf(_SC_PAGESIZE);
+ void *unrelated;
+
+ unrelated = mmap(NULL, page_size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (!ASSERT_NEQ(unrelated, MAP_FAILED, "unrelated_mmap"))
+ return;
+
+ skel->bss->exec_addr = (long)unrelated;
+ skel->bss->action = USER_PAGE_EXEC_ONLY;
+ user_page_trigger();
+ ASSERT_EQ(skel->bss->exec_ret, -EINVAL, "bad_exec_ret");
+
+ munmap(unrelated, page_size);
+}
+
+static void test_repeat_exec_rejected(struct user_page *skel)
+{
+ long page_size = sysconf(_SC_PAGESIZE);
+ long addr = -1;
+
+ if (!alloc_user_pages(skel, 1, &addr))
+ return;
+
+ skel->bss->exec_addr = addr;
+ skel->bss->action = USER_PAGE_EXEC_ONLY;
+ user_page_trigger();
+ if (!ASSERT_OK(skel->bss->exec_ret, "first_exec_ret"))
+ goto out;
+ user_page_trigger();
+
+ ASSERT_EQ(skel->bss->exec_ret, -EINVAL, "repeat_exec_ret");
+
+out:
+ if (addr >= 0)
+ munmap((void *)addr, page_size);
+}
+
+static void test_exec_write_protection(struct user_page *skel)
+{
+ long page_size = sysconf(_SC_PAGESIZE);
+ long addr = -1;
+
+ if (!alloc_user_pages(skel, 1, &addr))
+ return;
+
+ skel->bss->exec_addr = addr;
+ skel->bss->action = USER_PAGE_EXEC_ONLY;
+ user_page_trigger();
+ if (!ASSERT_OK(skel->bss->exec_ret, "exec_ret"))
+ goto out;
+
+ errno = 0;
+ if (!ASSERT_EQ(mprotect((void *)addr, page_size,
+ PROT_READ | PROT_WRITE), -1, "restore_write"))
+ goto out;
+
+ ASSERT_EQ(errno, EACCES, "restore_write_errno");
+
+out:
+ if (addr >= 0)
+ munmap((void *)addr, page_size);
+}
+
+static void test_fails(struct user_page *skel)
+{
+ test_invalid_allocation_size(skel);
+ test_misaligned_exec(skel);
+ test_reject_replacement(skel);
+ test_bad_write(skel);
+ test_unrelated_mapping_exec_rejected(skel);
+ test_repeat_exec_rejected(skel);
+ test_exec_write_protection(skel);
+}
+
void test_user_page(void)
{
struct user_page *skel;
@@ -233,6 +372,8 @@ void test_user_page(void)
test_partial_exec(skel);
if (test__start_subtest("faultable_write"))
test_faultable_write(skel);
+ if (test__start_subtest("fails"))
+ test_fails(skel);
out:
user_page__destroy(skel);
diff --git a/tools/testing/selftests/bpf/progs/user_page.c b/tools/testing/selftests/bpf/progs/user_page.c
index a855b0b46350..530a0be3737b 100644
--- a/tools/testing/selftests/bpf/progs/user_page.c
+++ b/tools/testing/selftests/bpf/progs/user_page.c
@@ -12,6 +12,7 @@ char _license[] SEC("license") = "GPL";
#define USER_PAGE_EXEC 2
#define USER_PAGE_EXEC_ONLY 3
#define USER_PAGE_WRITE 4
+#define USER_PAGE_BAD_WRITE 5
int monitored_pid;
int action;
@@ -50,6 +51,10 @@ int user_page_test(struct pt_regs *ctx)
write_ret = bpf_probe_write_user_faultable((void *)user_addr, data,
sizeof(data));
break;
+ case USER_PAGE_BAD_WRITE:
+ write_ret = bpf_probe_write_user_faultable((void *)1, data,
+ sizeof(data));
+ break;
}
return 0;
--
2.54.0
next prev parent reply other threads:[~2026-10-21 19:59 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 19:57 [RFC bpf-next 0/9] bpf: Add support to allocate user page Jiri Olsa
2026-10-21 19:57 ` [RFC bpf-next 1/9] bpf: Add __srcptr kfunc argument suffix Jiri Olsa
2026-10-21 20:16 ` sashiko-bot
2026-10-21 19:57 ` [RFC bpf-next 2/9] bpf: Add uprobe faultable user copy kfunc Jiri Olsa
2026-10-21 20:22 ` sashiko-bot
2026-10-21 20:30 ` bot+bpf-ci
2026-10-21 19:57 ` [RFC bpf-next 3/9] mm: Expose locked mprotect operation Jiri Olsa
2026-10-21 20:30 ` bot+bpf-ci
2026-10-22 10:25 ` Lorenzo Stoakes (ARM)
2026-10-22 19:39 ` Jiri Olsa
2026-10-21 19:57 ` [RFC bpf-next 4/9] bpf: Add kfuncs to allocate and seal user pages Jiri Olsa
2026-10-21 20:28 ` sashiko-bot
2026-10-21 20:41 ` bot+bpf-ci
2026-10-26 12:51 ` kernel test robot
2026-10-26 15:27 ` kernel test robot
2026-10-21 19:57 ` [RFC bpf-next 5/9] selftests/bpf: Add __srcptr kfunc arguments test Jiri Olsa
2026-10-21 19:57 ` [RFC bpf-next 6/9] selftests/bpf: Add user page allocation test Jiri Olsa
2026-10-21 19:57 ` [RFC bpf-next 7/9] selftests/bpf: Add uprobe user page exec test Jiri Olsa
2026-10-21 19:57 ` [RFC bpf-next 8/9] selftests/bpf: Add faultable user page writes test Jiri Olsa
2026-10-21 19:57 ` Jiri Olsa [this message]
2026-10-21 20:30 ` [RFC bpf-next 9/9] selftests/bpf: Add user page failures test bot+bpf-ci
2026-10-21 21:53 ` [RFC bpf-next 0/9] bpf: Add support to allocate user page Alexei Starovoitov
2026-10-22 10:01 ` Jiri Olsa
2026-10-22 10:27 ` Lorenzo Stoakes (ARM)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261021195759.119421-10-jolsa@kernel.org \
--to=jolsa@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=john.fastabend@gmail.com \
--cc=liam@infradead.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=memxor@gmail.com \
--cc=shuah@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.