All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yonghong Song <yhs@fb.com>
To: KP Singh <kpsingh@chromium.org>, <linux-kernel@vger.kernel.org>,
	<bpf@vger.kernel.org>, <linux-security-module@vger.kernel.org>
Cc: Brendan Jackman <jackmanb@google.com>,
	Florent Revest <revest@google.com>,
	Thomas Garnier <thgarnie@google.com>,
	Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	James Morris <jmorris@namei.org>,
	Kees Cook <keescook@chromium.org>, Paul Turner <pjt@google.com>,
	Jann Horn <jannh@google.com>,
	Florent Revest <revest@chromium.org>,
	Brendan Jackman <jackmanb@chromium.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Subject: Re: [PATCH bpf-next v5 7/7] bpf: lsm: Add selftests for BPF_PROG_TYPE_LSM
Date: Mon, 23 Mar 2020 13:04:48 -0700	[thread overview]
Message-ID: <a071b4ce-9311-5d44-4144-56075a8aa812@fb.com> (raw)
In-Reply-To: <20200323164415.12943-8-kpsingh@chromium.org>



On 3/23/20 9:44 AM, KP Singh wrote:
> From: KP Singh <kpsingh@google.com>
> 
> * Load/attach a BPF program to the file_mprotect (int) and
>    bprm_committed_creds (void) LSM hooks.
> * Perform an action that triggers the hook.
> * Verify if the audit event was received using a shared global
>    result variable.
> 
> Signed-off-by: KP Singh <kpsingh@google.com>
> Reviewed-by: Brendan Jackman <jackmanb@google.com>
> Reviewed-by: Florent Revest <revest@google.com>
> Reviewed-by: Thomas Garnier <thgarnie@google.com>
> ---
>   tools/testing/selftests/bpf/lsm_helpers.h     |  19 +++
>   .../selftests/bpf/prog_tests/lsm_test.c       | 112 ++++++++++++++++++
>   .../selftests/bpf/progs/lsm_int_hook.c        |  54 +++++++++
>   .../selftests/bpf/progs/lsm_void_hook.c       |  41 +++++++
>   4 files changed, 226 insertions(+)
>   create mode 100644 tools/testing/selftests/bpf/lsm_helpers.h
>   create mode 100644 tools/testing/selftests/bpf/prog_tests/lsm_test.c
>   create mode 100644 tools/testing/selftests/bpf/progs/lsm_int_hook.c
>   create mode 100644 tools/testing/selftests/bpf/progs/lsm_void_hook.c
> 
> diff --git a/tools/testing/selftests/bpf/lsm_helpers.h b/tools/testing/selftests/bpf/lsm_helpers.h
> new file mode 100644
> index 000000000000..3de230df93db
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/lsm_helpers.h
> @@ -0,0 +1,19 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +/*
> + * Copyright (C) 2020 Google LLC.
> + */
> +#ifndef _LSM_HELPERS_H
> +#define _LSM_HELPERS_H
> +
> +struct lsm_prog_result {
> +	/* This ensures that the LSM Hook only monitors the PID requested
> +	 * by the loader
> +	 */
> +	__u32 monitored_pid;
> +	/* The number of calls to the prog for the monitored PID.
> +	 */
> +	__u32 count;
> +};
> +
> +#endif /* _LSM_HELPERS_H */
> diff --git a/tools/testing/selftests/bpf/prog_tests/lsm_test.c b/tools/testing/selftests/bpf/prog_tests/lsm_test.c
> new file mode 100644
> index 000000000000..5fd6b8f569f7
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/prog_tests/lsm_test.c
> @@ -0,0 +1,112 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * Copyright (C) 2020 Google LLC.
> + */
> +
> +#include <test_progs.h>
> +#include <sys/mman.h>
> +#include <sys/wait.h>
> +#include <unistd.h>
> +#include <malloc.h>
> +#include <stdlib.h>
> +
> +#include "lsm_helpers.h"
> +#include "lsm_void_hook.skel.h"
> +#include "lsm_int_hook.skel.h"
> +
> +char *LS_ARGS[] = {"true", NULL};
> +
> +int heap_mprotect(void)
> +{
> +	void *buf;
> +	long sz;
> +
> +	sz = sysconf(_SC_PAGESIZE);
> +	if (sz < 0)
> +		return sz;
> +
> +	buf = memalign(sz, 2 * sz);
> +	if (buf == NULL)
> +		return -ENOMEM;
> +
> +	return mprotect(buf, sz, PROT_READ | PROT_EXEC);

"buf" is leaking memory here.

> +}
> +
> +int exec_ls(struct lsm_prog_result *result)
> +{
> +	int child_pid;
> +
> +	child_pid = fork();
> +	if (child_pid == 0) {
> +		result->monitored_pid = getpid();
> +		execvp(LS_ARGS[0], LS_ARGS);
> +		return -EINVAL;
> +	} else if (child_pid > 0)
> +		return wait(NULL);
> +
> +	return -EINVAL;
> +}
> +
> +void test_lsm_void_hook(void)
> +{
> +	struct lsm_prog_result *result;
> +	struct lsm_void_hook *skel = NULL;
> +	int err, duration = 0;
> +
> +	skel = lsm_void_hook__open_and_load();
> +	if (CHECK(!skel, "skel_load", "lsm_void_hook skeleton failed\n"))
> +		goto close_prog;
> +
> +	err = lsm_void_hook__attach(skel);
> +	if (CHECK(err, "attach", "lsm_void_hook attach failed: %d\n", err))
> +		goto close_prog;
> +
> +	result = &skel->bss->result;
> +
> +	err = exec_ls(result);
> +	if (CHECK(err < 0, "exec_ls", "err %d errno %d\n", err, errno))
> +		goto close_prog;
> +
> +	if (CHECK(result->count != 1, "count", "count = %d", result->count))
> +		goto close_prog;
> +
> +	CHECK_FAIL(result->count != 1);

I think the above
	if (CHECK(result->count != 1, "count", "count = %d", result->count))
		goto close_prog;

	CHECK_FAIL(result->count != 1);
can be replaced with
	CHECK(result->count != 1, "count", "count = %d", result->count);

> +
> +close_prog:
> +	lsm_void_hook__destroy(skel);
> +}
> +
> +void test_lsm_int_hook(void)
> +{
> +	struct lsm_prog_result *result;
> +	struct lsm_int_hook *skel = NULL;
> +	int err, duration = 0;
> +
> +	skel = lsm_int_hook__open_and_load();
> +	if (CHECK(!skel, "skel_load", "lsm_int_hook skeleton failed\n"))
> +		goto close_prog;
> +
> +	err = lsm_int_hook__attach(skel);
> +	if (CHECK(err, "attach", "lsm_int_hook attach failed: %d\n", err))
> +		goto close_prog;
> +
> +	result = &skel->bss->result;
> +	result->monitored_pid = getpid();
> +
> +	err = heap_mprotect();
> +	if (CHECK(errno != EPERM, "heap_mprotect", "want errno=EPERM, got %d\n",
> +		  errno))
> +		goto close_prog;
> +
> +	CHECK_FAIL(result->count != 1);
> +
> +close_prog:
> +	lsm_int_hook__destroy(skel);
> +}
> +
> +void test_lsm_test(void)
> +{
> +	test_lsm_void_hook();
> +	test_lsm_int_hook();
> +}
> diff --git a/tools/testing/selftests/bpf/progs/lsm_int_hook.c b/tools/testing/selftests/bpf/progs/lsm_int_hook.c
> new file mode 100644
> index 000000000000..1c5028ddca61
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/progs/lsm_int_hook.c
> @@ -0,0 +1,54 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * Copyright 2020 Google LLC.
> + */
> +
> +#include <linux/bpf.h>
> +#include <stdbool.h>
> +#include <bpf/bpf_helpers.h>
> +#include <bpf/bpf_tracing.h>
> +#include  <errno.h>
> +#include "lsm_helpers.h"
> +
> +char _license[] SEC("license") = "GPL";
> +
> +struct lsm_prog_result result = {
> +	.monitored_pid = 0,
> +	.count = 0,
> +};
> +
> +/*
> + * Define some of the structs used in the BPF program.
> + * Only the field names and their sizes need to be the
> + * same as the kernel type, the order is irrelevant.
> + */
> +struct mm_struct {
> +	unsigned long start_brk, brk;
> +} __attribute__((preserve_access_index));
> +
> +struct vm_area_struct {
> +	unsigned long vm_start, vm_end;
> +	struct mm_struct *vm_mm;
> +} __attribute__((preserve_access_index));
> +
> +SEC("lsm/file_mprotect")
> +int BPF_PROG(test_int_hook, struct vm_area_struct *vma,
> +	     unsigned long reqprot, unsigned long prot, int ret)
> +{
> +	if (ret != 0)
> +		return ret;
> +
> +	__u32 pid = bpf_get_current_pid_tgid();

In user space, we assign monitored_pid with getpid()
which is the process pid. Here
    pid = bpf_get_current_pid_tgid()
actually got tid in the kernel.

Although it does not matter in this particular example,
maybe still use
    bpf_get_current_pid_tgid() >> 32
to get process pid to be consistent.

The same for lsm_void_hook.c.

> +	int is_heap = 0;
> +
> +	is_heap = (vma->vm_start >= vma->vm_mm->start_brk &&
> +		   vma->vm_end <= vma->vm_mm->brk);
> +
> +	if (is_heap && result.monitored_pid == pid) {
> +		result.count++;
> +		ret = -EPERM;
> +	}
> +
> +	return ret;
> +}
> diff --git a/tools/testing/selftests/bpf/progs/lsm_void_hook.c b/tools/testing/selftests/bpf/progs/lsm_void_hook.c
> new file mode 100644
> index 000000000000..4d01a8536413
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/progs/lsm_void_hook.c
> @@ -0,0 +1,41 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +/*
> + * Copyright (C) 2020 Google LLC.
> + */
> +
> +#include <linux/bpf.h>
> +#include <stdbool.h>
> +#include <bpf/bpf_helpers.h>
> +#include <bpf/bpf_tracing.h>
> +#include  <errno.h>
> +#include "lsm_helpers.h"
> +
> +char _license[] SEC("license") = "GPL";
> +
> +struct lsm_prog_result result = {
> +	.monitored_pid = 0,
> +	.count = 0,
> +};
> +
> +/*
> + * Define some of the structs used in the BPF program.
> + * Only the field names and their sizes need to be the
> + * same as the kernel type, the order is irrelevant.
> + */
> +struct linux_binprm {
> +	const char *filename;
> +} __attribute__((preserve_access_index));
> +
> +SEC("lsm/bprm_committed_creds")
> +int BPF_PROG(test_void_hook, struct linux_binprm *bprm)
> +{
> +	__u32 pid = bpf_get_current_pid_tgid();
> +	char fmt[] = "lsm(bprm_committed_creds): process executed %s\n";
> +
> +	bpf_trace_printk(fmt, sizeof(fmt), bprm->filename);
> +	if (result.monitored_pid == pid)
> +		result.count++;
> +
> +	return 0;
> +}
> 

Could you also upddate tools/testing/selftests/bpf/config file
so people will know what config options are needed to run the
self tests properly?

  reply	other threads:[~2020-03-23 20:05 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-23 16:44 [PATCH bpf-next v5 0/8] MAC and Audit policy using eBPF (KRSI) KP Singh
2020-03-23 16:44 ` [PATCH bpf-next v5 1/7] bpf: Introduce BPF_PROG_TYPE_LSM KP Singh
2020-03-23 19:02   ` Yonghong Song
2020-03-23 16:44 ` [PATCH bpf-next v5 2/7] security: Refactor declaration of LSM hooks KP Singh
2020-03-23 19:33   ` Kees Cook
2020-03-23 19:56   ` Andrii Nakryiko
2020-03-24 16:06     ` KP Singh
2020-03-23 16:44 ` [PATCH bpf-next v5 3/7] bpf: lsm: provide attachment points for BPF LSM programs KP Singh
2020-03-23 19:04   ` Yonghong Song
2020-03-23 19:33   ` Kees Cook
2020-03-23 19:59   ` Andrii Nakryiko
2020-03-24 10:39     ` KP Singh
2020-03-24 16:12       ` KP Singh
2020-03-24 21:26         ` Andrii Nakryiko
2020-03-24 22:39           ` KP Singh
2020-03-23 16:44 ` [PATCH bpf-next v5 4/7] bpf: lsm: Implement attach, detach and execution KP Singh
2020-03-23 19:16   ` Yonghong Song
2020-03-23 19:44     ` KP Singh
2020-03-23 20:18   ` Andrii Nakryiko
2020-03-24 19:00     ` KP Singh
2020-03-24 14:35   ` Stephen Smalley
2020-03-24 14:50     ` KP Singh
2020-03-24 14:58       ` Stephen Smalley
2020-03-24 16:25         ` Casey Schaufler
2020-03-24 17:49           ` Stephen Smalley
2020-03-24 18:01             ` Kees Cook
2020-03-24 18:06               ` KP Singh
2020-03-24 18:21                 ` Stephen Smalley
2020-03-24 18:27                   ` KP Singh
2020-03-24 18:31                     ` KP Singh
2020-03-24 18:34                       ` Kees Cook
2020-03-24 18:33                   ` Kees Cook
2020-03-23 16:44 ` [PATCH bpf-next v5 5/7] bpf: lsm: Initialize the BPF LSM hooks KP Singh
2020-03-23 19:44   ` Kees Cook
2020-03-23 19:47     ` KP Singh
2020-03-23 20:21       ` Andrii Nakryiko
2020-03-23 20:47     ` Casey Schaufler
2020-03-23 21:44       ` Kees Cook
2020-03-23 21:58         ` Casey Schaufler
2020-03-23 22:12           ` Kees Cook
2020-03-23 23:39             ` Casey Schaufler
2020-03-24  1:53             ` KP Singh
2020-03-25 14:35             ` KP Singh
2020-03-24  1:13   ` Casey Schaufler
2020-03-24  1:52     ` KP Singh
2020-03-24 14:37       ` Stephen Smalley
2020-03-24 14:42         ` KP Singh
2020-03-24 14:51           ` Stephen Smalley
2020-03-24 14:51             ` KP Singh
2020-03-24 17:57               ` Kees Cook
2020-03-23 16:44 ` [PATCH bpf-next v5 6/7] tools/libbpf: Add support for BPF_PROG_TYPE_LSM KP Singh
2020-03-23 19:21   ` Yonghong Song
2020-03-23 20:25   ` Andrii Nakryiko
2020-03-24  1:57     ` KP Singh
2020-03-23 16:44 ` [PATCH bpf-next v5 7/7] bpf: lsm: Add selftests " KP Singh
2020-03-23 20:04   ` Yonghong Song [this message]
2020-03-24 20:04     ` KP Singh
2020-03-24 23:54   ` Andrii Nakryiko
2020-03-25  0:36     ` KP Singh

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=a071b4ce-9311-5d44-4144-56075a8aa812@fb.com \
    --to=yhs@fb.com \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=jackmanb@chromium.org \
    --cc=jackmanb@google.com \
    --cc=jannh@google.com \
    --cc=jmorris@namei.org \
    --cc=keescook@chromium.org \
    --cc=kpsingh@chromium.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=pjt@google.com \
    --cc=revest@chromium.org \
    --cc=revest@google.com \
    --cc=thgarnie@google.com \
    /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.