Received: by 2002:a25:6193:0:0:0:0:0 with SMTP id v141csp5217450ybb; Tue, 24 Mar 2020 13:06:03 -0700 (PDT) X-Google-Smtp-Source: ADFU+vsRHnVkaT2yzFQS7FyveY7PUbe+ISLEVM4YYzB/uS81tf01d/xLulPTAeV27Zv3Xq8BPaFj X-Received: by 2002:a05:6830:1e55:: with SMTP id e21mr11772595otj.233.1585080363190; Tue, 24 Mar 2020 13:06:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1585080363; cv=none; d=google.com; s=arc-20160816; b=EZI5+Rr8RaGJ+8OqK+Zt76zCFHWTxWfUP5AshFbglIfMPQXTCISNIc3mnVoH+rfY07 hB07Un34NXFGgTKW2l+yzNozqem5SYRMypZy7S0tfl0ufGhnXF6BrpmF8+a3KhKKhmEH gmWMKgvWEGBnT6gOjEskGxXY83W+YthHi6rovglM32j7VlG8KgxmY2/5I8lwPewi6rKo dV2Wi03+04BNIiPtOFxi39aiKRzK8eXMX/GTSeW6nvRu+kdQe7Ay2xvRVILMDvQKJ+zN TOBRLr7wZ/s3IYkkXA1Tk8BAAiB2F2xJQTfp0ojFZDdbzOGZBj7hEtqEqPZuEmTvH8U1 NO7w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-transfer-encoding:content-disposition:mime-version :references:message-id:subject:cc:to:date:from:dkim-signature; bh=Tt0UFZephI2Ue5bqTwLi4oygzZ66RF71KGwdZLCPEUc=; b=SHHNYPIh1GEVSXN6cYll3w8/UpSyoWsVLUeadpUqiy1kuzeKe0gnUhhIBZyxxGVUbe rNRD59JJRLZEyqzAUPmgRfm348brcumqc7DFrb1njipNQaiq8da+9AhYb+YooCUn6KQy zQy03X9CCqVhlk17mixBs/h7PtR9Ah09pWqY4WW2s8GHgTnGGFYqQ5TDIpxCj+qE9JLB 0vxQOZ4P5zGsmFBg7xk7kDE7v/p0Rye/qiJ1gV0UI6K1+ufsF67s1HnExt/ZYVWX9sbO 2NU8zr0Wbinv5cj+GRz20DEtMzOJeN8Ig9a73sIRpuWXGZszwFpSyPkx7Kkp0ovtE8nW I9qQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b="I/qsK+M8"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id q23si9953132otg.271.2020.03.24.13.05.48; Tue, 24 Mar 2020 13:06:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b="I/qsK+M8"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727613AbgCXUEM (ORCPT + 99 others); Tue, 24 Mar 2020 16:04:12 -0400 Received: from mail-wr1-f68.google.com ([209.85.221.68]:46670 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726560AbgCXUEM (ORCPT ); Tue, 24 Mar 2020 16:04:12 -0400 Received: by mail-wr1-f68.google.com with SMTP id j17so19799977wru.13 for ; Tue, 24 Mar 2020 13:04:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:date:to:cc:subject:message-id:references:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=Tt0UFZephI2Ue5bqTwLi4oygzZ66RF71KGwdZLCPEUc=; b=I/qsK+M8mg3ROchM+A9exgLw0tB88VSlpMAyjRnt9nNEZkmWtxKO0s8/EoYu8ra+KW qEVkYgcQIJp+6+Npg20aBla+BEc7SrWjGM0Kapss2WJ9ubRfux3/i4CVQWgnAOw8ObjB L52YEZ1nl0YNOk3W17tEwtyyNYaNNi6JYQ8BE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:date:to:cc:subject:message-id:references :mime-version:content-disposition:content-transfer-encoding :in-reply-to:user-agent; bh=Tt0UFZephI2Ue5bqTwLi4oygzZ66RF71KGwdZLCPEUc=; b=UBwR9FjqIVBpgBPsIRZbeyQQhxZdxLv2R0ENn7PQUckB9qpj21eUzUZYFDDLYDf/3X Y5whwraXkrnV1yovrOHiDHcfOLmg8mmuMvFhaK1OK9FWeEP5+3hP8ivR/A/xg9BFq2Ij 7SGDcpB6wER3Jyyt6Ii81vpCpYvdPFuACp4AO2RL459R9zq1nWsruuprXIBQHsnlCDPn kc6eQAxB8HgDtqUe4hXBnL4aJN0iyDrMKrFSKwn3VLHe69Oy7K0DpZIMSHJnqYxM/DOb RuwbtlDgJRH3o3qCQzP08Dbm3BwaemTeSM8yKdVoNLWjBoAJuW3vJCnYntATkph4UZ54 7GKA== X-Gm-Message-State: ANhLgQ1QjvRu6VW72F0VcPoYh9qQ9Mv85S+E5VwS2G79THZyGlx6778w UgSYdXnH+muVRswfXMFzblrcMg== X-Received: by 2002:adf:b6a5:: with SMTP id j37mr38231704wre.412.1585080248593; Tue, 24 Mar 2020 13:04:08 -0700 (PDT) Received: from chromium.org (77-56-209-237.dclient.hispeed.ch. [77.56.209.237]) by smtp.gmail.com with ESMTPSA id o16sm31229588wrs.44.2020.03.24.13.04.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 24 Mar 2020 13:04:07 -0700 (PDT) From: KP Singh X-Google-Original-From: KP Singh Date: Tue, 24 Mar 2020 21:04:05 +0100 To: Yonghong Song Cc: linux-kernel@vger.kernel.org, bpf@vger.kernel.org, linux-security-module@vger.kernel.org, Brendan Jackman , Florent Revest , Thomas Garnier , Alexei Starovoitov , Daniel Borkmann , James Morris , Kees Cook , Paul Turner , Jann Horn , Florent Revest , Brendan Jackman , Greg Kroah-Hartman Subject: Re: [PATCH bpf-next v5 7/7] bpf: lsm: Add selftests for BPF_PROG_TYPE_LSM Message-ID: <20200324200405.GA7008@chromium.org> References: <20200323164415.12943-1-kpsingh@chromium.org> <20200323164415.12943-8-kpsingh@chromium.org> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 23-M?r 13:04, Yonghong Song wrote: > > > On 3/23/20 9:44 AM, KP Singh wrote: > > From: KP Singh > > > > * 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 > > Reviewed-by: Brendan Jackman > > Reviewed-by: Florent Revest > > Reviewed-by: Thomas Garnier > > --- > > 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 > > +#include > > +#include > > +#include > > +#include > > +#include > > + > > +#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); Thanks, and updated for test_lsm_int_hook as well. > > > + > > +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 > > +#include > > +#include > > +#include > > +#include > > +#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. Done. Thanks! > > > + 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 > > +#include > > +#include > > +#include > > +#include > > +#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? Added CONFIG_BPF_LSM and CONFIG_SECURITY to the list. - KP