diff mbox series

[bpf] bpf, lsm: Fix the file_mprotect LSM test.

Message ID 20200402200751.26372-1-kpsingh@chromium.org
State Accepted
Delegated to: BPF Maintainers
Headers show
Series [bpf] bpf, lsm: Fix the file_mprotect LSM test. | expand

Commit Message

KP Singh April 2, 2020, 8:07 p.m. UTC
From: KP Singh <kpsingh@google.com>

The test was previously using an mprotect on the heap memory allocated
using malloc and was expecting the allocation to be always using
sbrk(2). This is, however, not always true and in certain conditions
malloc may end up using anonymous mmaps for heap alloctions. This means
that the following condition that is used in the "lsm/file_mprotect"
program is not sufficent to detect all mprotect calls done on heap
memory:

	is_heap = (vma->vm_start >= vma->vm_mm->start_brk &&
		   vma->vm_end <= vma->vm_mm->brk);

The test is updated to use an mprotect on memory allocated on the stack.
While this would result in the splitting of the vma, this happens only
after the security_file_mprotect hook. So, the condition used in the BPF
program holds true.

Signed-off-by: KP Singh <kpsingh@google.com>
Reported-by: Alexei Starovoitov <ast@kernel.org>
Fixes: 03e54f100d57 ("bpf: lsm: Add selftests for BPF_PROG_TYPE_LSM")
---
 .../selftests/bpf/prog_tests/test_lsm.c        | 18 +++++++++---------
 tools/testing/selftests/bpf/progs/lsm.c        |  8 ++++----
 2 files changed, 13 insertions(+), 13 deletions(-)

Comments

Alexei Starovoitov April 3, 2020, 2:46 a.m. UTC | #1
On Thu, Apr 2, 2020 at 1:07 PM KP Singh <kpsingh@chromium.org> wrote:
>
> From: KP Singh <kpsingh@google.com>
>
> The test was previously using an mprotect on the heap memory allocated
> using malloc and was expecting the allocation to be always using
> sbrk(2). This is, however, not always true and in certain conditions
> malloc may end up using anonymous mmaps for heap alloctions. This means
> that the following condition that is used in the "lsm/file_mprotect"
> program is not sufficent to detect all mprotect calls done on heap
> memory:
>
>         is_heap = (vma->vm_start >= vma->vm_mm->start_brk &&
>                    vma->vm_end <= vma->vm_mm->brk);
>
> The test is updated to use an mprotect on memory allocated on the stack.
> While this would result in the splitting of the vma, this happens only
> after the security_file_mprotect hook. So, the condition used in the BPF
> program holds true.
>
> Signed-off-by: KP Singh <kpsingh@google.com>
> Reported-by: Alexei Starovoitov <ast@kernel.org>
> Fixes: 03e54f100d57 ("bpf: lsm: Add selftests for BPF_PROG_TYPE_LSM")

Applied. Thanks
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/prog_tests/test_lsm.c b/tools/testing/selftests/bpf/prog_tests/test_lsm.c
index 1e4c258de09d..b17eb2045c1d 100644
--- a/tools/testing/selftests/bpf/prog_tests/test_lsm.c
+++ b/tools/testing/selftests/bpf/prog_tests/test_lsm.c
@@ -15,7 +15,10 @@ 
 
 char *CMD_ARGS[] = {"true", NULL};
 
-int heap_mprotect(void)
+#define GET_PAGE_ADDR(ADDR, PAGE_SIZE)					\
+	(char *)(((unsigned long) (ADDR + PAGE_SIZE)) & ~(PAGE_SIZE-1))
+
+int stack_mprotect(void)
 {
 	void *buf;
 	long sz;
@@ -25,12 +28,9 @@  int heap_mprotect(void)
 	if (sz < 0)
 		return sz;
 
-	buf = memalign(sz, 2 * sz);
-	if (buf == NULL)
-		return -ENOMEM;
-
-	ret = mprotect(buf, sz, PROT_READ | PROT_WRITE | PROT_EXEC);
-	free(buf);
+	buf = alloca(sz * 3);
+	ret = mprotect(GET_PAGE_ADDR(buf, sz), sz,
+		       PROT_READ | PROT_WRITE | PROT_EXEC);
 	return ret;
 }
 
@@ -73,8 +73,8 @@  void test_test_lsm(void)
 
 	skel->bss->monitored_pid = getpid();
 
-	err = heap_mprotect();
-	if (CHECK(errno != EPERM, "heap_mprotect", "want errno=EPERM, got %d\n",
+	err = stack_mprotect();
+	if (CHECK(errno != EPERM, "stack_mprotect", "want err=EPERM, got %d\n",
 		  errno))
 		goto close_prog;
 
diff --git a/tools/testing/selftests/bpf/progs/lsm.c b/tools/testing/selftests/bpf/progs/lsm.c
index a4e3c223028d..b4598d4bc4f7 100644
--- a/tools/testing/selftests/bpf/progs/lsm.c
+++ b/tools/testing/selftests/bpf/progs/lsm.c
@@ -23,12 +23,12 @@  int BPF_PROG(test_int_hook, struct vm_area_struct *vma,
 		return ret;
 
 	__u32 pid = bpf_get_current_pid_tgid() >> 32;
-	int is_heap = 0;
+	int is_stack = 0;
 
-	is_heap = (vma->vm_start >= vma->vm_mm->start_brk &&
-		   vma->vm_end <= vma->vm_mm->brk);
+	is_stack = (vma->vm_start <= vma->vm_mm->start_stack &&
+		    vma->vm_end >= vma->vm_mm->start_stack);
 
-	if (is_heap && monitored_pid == pid) {
+	if (is_stack && monitored_pid == pid) {
 		mprotect_count++;
 		ret = -EPERM;
 	}