Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp913403ybl; Thu, 23 Jan 2020 10:02:33 -0800 (PST) X-Google-Smtp-Source: APXvYqxmGz15xiryvHwxWcCFf0hwIfgMDCpnU/D0uDzNWgBrjReqDR7YLovSn6Kr83C76uy11y4V X-Received: by 2002:aca:c786:: with SMTP id x128mr10880923oif.2.1579802553777; Thu, 23 Jan 2020 10:02:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1579802553; cv=none; d=google.com; s=arc-20160816; b=xpsa7TT5R+qpE9JTP2LZnOQQJ3OUdjMVd0OzNeLDBtcn6ckm5jSjMdsdlUMNvxjWTm lvJ5YFA7x7rQbqwChROjI1F1VLh7Ng01c2H9in/HKiuE+ukOGwN4umITcjE9PmRaTvxm J3jay+fqyJOtg60QFxymjHSSP98kYNcJCCnHlIMlen5fmuHoM3zDXEwhxPXMipjrHeRh +is+rzkLJ0o1s9k/iUNFhjCLTOzCbYoqmEh0k7gMQUV3w9MpdDLwSyQWTLss38+U/zK/ hopFEeALrIAdB+BTitK/MpfylPn7x3/RA8jXHx+rdWROoSkvqXfdUBSDB/lzWPZbZPFL kO/w== 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-disposition:mime-version:references:message-id:subject:cc :to:date:from:dkim-signature; bh=iR3jr3L61KPYRB1VPXCrOLzc7KLrPfoT5IhUgDxXQ34=; b=pGyFxfDr08TsaKx3Lb/14rQlGP+umDO19LDaeIDK/KJAizziUphUSRPddbhBLK6TOw mGmGoxpmsPA3jKkCRuqybXyfAk5uXtmie36CDEtdD+RDN3RnxbX7rcgMixB1GE8Tmrto jaam043j/lSuy0QbBNtUWjaJm+rgoS8C/v7z0QBdj2RUi7GfrE1kdOM9xQCe+B68CKRr cUhOAhJqqenzx1iiFn/N7IgpUJ7xeNU4ZU3jP0okHEDzrQJakBuq770qZbfmje5PSPGz wK63qoo8blQ28/MGGwc6odX40AEga5a06kQjjxlbPyh/OqTnAuF1HrtOa3oKC7QLqzmS sJUA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=lPJ+8BtH; 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 q66si1075811oig.65.2020.01.23.10.02.21; Thu, 23 Jan 2020 10:02:33 -0800 (PST) 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=lPJ+8BtH; 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 S1728665AbgAWR7t (ORCPT + 99 others); Thu, 23 Jan 2020 12:59:49 -0500 Received: from mail-wr1-f67.google.com ([209.85.221.67]:33745 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728139AbgAWR7t (ORCPT ); Thu, 23 Jan 2020 12:59:49 -0500 Received: by mail-wr1-f67.google.com with SMTP id b6so4184217wrq.0 for ; Thu, 23 Jan 2020 09:59:45 -0800 (PST) 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:in-reply-to:user-agent; bh=iR3jr3L61KPYRB1VPXCrOLzc7KLrPfoT5IhUgDxXQ34=; b=lPJ+8BtHsdYnwKpSbc/mDntsZlU+WGUXk7nZZyQV3XxeGLntofMWOckXOUGSybSYFA MLnZ08HTwdnVPd1+0rdlQSOu0GwSL6GGfIe2QWHLh08YH58O7K8ccLzaj9YWjji/oKm+ eiGhb+7BJGEP78a6SlpKW8Bq1YDBKgN2RCp7Q= 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:in-reply-to:user-agent; bh=iR3jr3L61KPYRB1VPXCrOLzc7KLrPfoT5IhUgDxXQ34=; b=Tnjr1Ks65Dj/HKBDjB5M0opNB04Q/PJEaBV95pBeiYmp+N29IEcGZnFD6pHWD861zA +85vxAtvGiL5sESsIHQMWFlFKcOkKO+/MJlCjgXCZNbtO+iSCgfuLQ3AqljX6gFE7jL1 OH/i6OhvsWv4gmGuLcuX9oj+xu2cPIVsmlfvR79b3+p87dfS3Jvmn+6LEH22hp/96hLR qY33yhyU1GGS867fersGpEm8CQG+ENO6ieW750v5DfHJltOh8LqmsRGOuUt2jg3KkPZG NqfGEBuqsUZ0gc4OtPcF9Mk2oTbTClowTUNJ8BGr3hmpN60WZj9skWeVVU8F0thU9LVW Wj1A== X-Gm-Message-State: APjAAAWBC7AtPsDnXC7kybyzqltDYVjZQeqfRPvZBqJhgX9m29RyS/bB bJiIc2gdwyhQxlyKsr65gUQg6g== X-Received: by 2002:adf:ee45:: with SMTP id w5mr19078835wro.352.1579802384594; Thu, 23 Jan 2020 09:59:44 -0800 (PST) Received: from google.com ([2a00:79e0:42:204:8a21:ba0c:bb42:75ec]) by smtp.gmail.com with ESMTPSA id m7sm3950205wrr.40.2020.01.23.09.59.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 23 Jan 2020 09:59:44 -0800 (PST) From: KP Singh X-Google-Original-From: KP Singh Date: Thu, 23 Jan 2020 18:59:42 +0100 To: Casey Schaufler Cc: KP Singh , LKML , Linux Security Module list , bpf@vger.kernel.org Subject: Re: [PATCH bpf-next v3 04/10] bpf: lsm: Add mutable hooks list for the BPF LSM Message-ID: <20200123175942.GA131348@google.com> References: <20200123152440.28956-1-kpsingh@chromium.org> <20200123152440.28956-5-kpsingh@chromium.org> <29157a88-7049-906e-fe92-b7a1e2183c6b@schaufler-ca.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <29157a88-7049-906e-fe92-b7a1e2183c6b@schaufler-ca.com> 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-Jan 09:03, Casey Schaufler wrote: > On 1/23/2020 7:24 AM, KP Singh wrote: > > From: KP Singh > > > > - The list of hooks registered by an LSM is currently immutable as they > > are declared with __lsm_ro_after_init and they are attached to a > > security_hook_heads struct. > > - For the BPF LSM we need to de/register the hooks at runtime. Making > > the existing security_hook_heads mutable broadens an > > attack vector, so a separate security_hook_heads is added for only > > those that ~must~ be mutable. > > - These mutable hooks are run only after all the static hooks have > > successfully executed. > > > > This is based on the ideas discussed in: > > > > https://lore.kernel.org/lkml/20180408065916.GA2832@ircssh-2.c.rugged-nimbus-611.internal > > > > Reviewed-by: Brendan Jackman > > Reviewed-by: Florent Revest > > Reviewed-by: Thomas Garnier > > Signed-off-by: KP Singh > > --- > > MAINTAINERS | 1 + > > include/linux/bpf_lsm.h | 72 +++++++++++++++++++++++++++++++++++++++++ > > security/bpf/Kconfig | 1 + > > security/bpf/Makefile | 2 +- > > security/bpf/hooks.c | 20 ++++++++++++ > > security/bpf/lsm.c | 7 ++++ > > security/security.c | 25 +++++++------- > > 7 files changed, 116 insertions(+), 12 deletions(-) > > create mode 100644 include/linux/bpf_lsm.h > > create mode 100644 security/bpf/hooks.c > > > > diff --git a/MAINTAINERS b/MAINTAINERS > > index e2b7f76a1a70..c606b3d89992 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -3209,6 +3209,7 @@ L: linux-security-module@vger.kernel.org > > L: bpf@vger.kernel.org > > S: Maintained > > F: security/bpf/ > > +F: include/linux/bpf_lsm.h > > > > BROADCOM B44 10/100 ETHERNET DRIVER > > M: Michael Chan > > diff --git a/include/linux/bpf_lsm.h b/include/linux/bpf_lsm.h > > new file mode 100644 > > index 000000000000..57c20b2cd2f4 > > --- /dev/null > > +++ b/include/linux/bpf_lsm.h > > @@ -0,0 +1,72 @@ > > +/* SPDX-License-Identifier: GPL-2.0 */ > > + > > +/* > > + * Copyright 2019 Google LLC. > > + */ > > + > > +#ifndef _LINUX_BPF_LSM_H > > +#define _LINUX_BPF_LSM_H > > + > > +#include > > +#include > > + > > +#ifdef CONFIG_SECURITY_BPF > > + > > +/* Mutable hooks defined at runtime and executed after all the statically > > + * defined LSM hooks. > > + */ > > +extern struct security_hook_heads bpf_lsm_hook_heads; > > + > > +int bpf_lsm_srcu_read_lock(void); > > +void bpf_lsm_srcu_read_unlock(int idx); > > + > > +#define CALL_BPF_LSM_VOID_HOOKS(FUNC, ...) \ > > + do { \ > > + struct security_hook_list *P; \ > > + int _idx; \ > > + \ > > + if (hlist_empty(&bpf_lsm_hook_heads.FUNC)) \ > > + break; \ > > + \ > > + _idx = bpf_lsm_srcu_read_lock(); \ > > + hlist_for_each_entry(P, &bpf_lsm_hook_heads.FUNC, list) \ > > + P->hook.FUNC(__VA_ARGS__); \ > > + bpf_lsm_srcu_read_unlock(_idx); \ > > + } while (0) > > + > > +#define CALL_BPF_LSM_INT_HOOKS(FUNC, ...) ({ \ > > + int _ret = 0; \ > > + do { \ > > + struct security_hook_list *P; \ > > + int _idx; \ > > + \ > > + if (hlist_empty(&bpf_lsm_hook_heads.FUNC)) \ > > + break; \ > > + \ > > + _idx = bpf_lsm_srcu_read_lock(); \ > > + \ > > + hlist_for_each_entry(P, \ > > + &bpf_lsm_hook_heads.FUNC, list) { \ > > + _ret = P->hook.FUNC(__VA_ARGS__); \ > > + if (_ret && IS_ENABLED(CONFIG_SECURITY_BPF_ENFORCE)) \ > > + break; \ > > + } \ > > + bpf_lsm_srcu_read_unlock(_idx); \ > > + } while (0); \ > > + IS_ENABLED(CONFIG_SECURITY_BPF_ENFORCE) ? _ret : 0; \ > > +}) > > + > > +#else /* !CONFIG_SECURITY_BPF */ > > + > > +#define CALL_BPF_LSM_INT_HOOKS(FUNC, ...) (0) > > +#define CALL_BPF_LSM_VOID_HOOKS(...) > > + > > +static inline int bpf_lsm_srcu_read_lock(void) > > +{ > > + return 0; > > +} > > +static inline void bpf_lsm_srcu_read_unlock(int idx) {} > > + > > +#endif /* CONFIG_SECURITY_BPF */ > > + > > +#endif /* _LINUX_BPF_LSM_H */ > > diff --git a/security/bpf/Kconfig b/security/bpf/Kconfig > > index a5f6c67ae526..595e4ad597ae 100644 > > --- a/security/bpf/Kconfig > > +++ b/security/bpf/Kconfig > > @@ -6,6 +6,7 @@ config SECURITY_BPF > > bool "BPF-based MAC and audit policy" > > depends on SECURITY > > depends on BPF_SYSCALL > > + depends on SRCU > > help > > This enables instrumentation of the security hooks with > > eBPF programs. > > diff --git a/security/bpf/Makefile b/security/bpf/Makefile > > index c78a8a056e7e..c526927c337d 100644 > > --- a/security/bpf/Makefile > > +++ b/security/bpf/Makefile > > @@ -2,4 +2,4 @@ > > # > > # Copyright 2019 Google LLC. > > > > -obj-$(CONFIG_SECURITY_BPF) := lsm.o ops.o > > +obj-$(CONFIG_SECURITY_BPF) := lsm.o ops.o hooks.o > > diff --git a/security/bpf/hooks.c b/security/bpf/hooks.c > > new file mode 100644 > > index 000000000000..b123d9cb4cd4 > > --- /dev/null > > +++ b/security/bpf/hooks.c > > @@ -0,0 +1,20 @@ > > +// SPDX-License-Identifier: GPL-2.0 > > + > > +/* > > + * Copyright 2019 Google LLC. > > + */ > > + > > +#include > > +#include > > + > > +DEFINE_STATIC_SRCU(security_hook_srcu); > > + > > +int bpf_lsm_srcu_read_lock(void) > > +{ > > + return srcu_read_lock(&security_hook_srcu); > > +} > > + > > +void bpf_lsm_srcu_read_unlock(int idx) > > +{ > > + return srcu_read_unlock(&security_hook_srcu, idx); > > +} > > diff --git a/security/bpf/lsm.c b/security/bpf/lsm.c > > index dc9ac03c7aa0..a25a068e1781 100644 > > --- a/security/bpf/lsm.c > > +++ b/security/bpf/lsm.c > > @@ -4,6 +4,7 @@ > > * Copyright 2019 Google LLC. > > */ > > > > +#include > > #include > > > > /* This is only for internal hooks, always statically shipped as part of the > > @@ -12,6 +13,12 @@ > > */ > > static struct security_hook_list bpf_lsm_hooks[] __lsm_ro_after_init = {}; > > > > +/* Security hooks registered dynamically by the BPF LSM and must be accessed > > + * by holding bpf_lsm_srcu_read_lock and bpf_lsm_srcu_read_unlock. The mutable > > + * hooks dynamically allocated by the BPF LSM are appeneded here. > > + */ > > +struct security_hook_heads bpf_lsm_hook_heads; > > + > > static int __init bpf_lsm_init(void) > > { > > security_add_hooks(bpf_lsm_hooks, ARRAY_SIZE(bpf_lsm_hooks), "bpf"); > > diff --git a/security/security.c b/security/security.c > > index 30a8aa700557..95a46ca25dcd 100644 > > --- a/security/security.c > > +++ b/security/security.c > > @@ -27,6 +27,7 @@ > > #include > > #include > > #include > > +#include > > #include > > > > #define MAX_LSM_EVM_XATTR 2 > > @@ -657,20 +658,22 @@ static void __init lsm_early_task(struct task_struct *task) > > \ > > hlist_for_each_entry(P, &security_hook_heads.FUNC, list) \ > > P->hook.FUNC(__VA_ARGS__); \ > > + CALL_BPF_LSM_VOID_HOOKS(FUNC, __VA_ARGS__); \ > > I'm sorry if I wasn't clear on the v2 review. > This does not belong in the infrastructure. You should be > doing all the bpf_lsm hook processing in you module. > bpf_lsm_task_alloc() should loop though all the bpf > task_alloc hooks if they have to be handled differently > from "normal" LSM hooks. The BPF LSM does not define static hooks (the ones registered to security_hook_heads in security.c with __lsm_ro_after_init) for each LSM hook. If it tries to do that one ends with what was in v1: https://lore.kernel.org/bpf/20191220154208.15895-7-kpsingh@chromium.org This gets quite ugly (security/bpf/hooks.h from v1) and was noted by the BPF maintainers: https://lore.kernel.org/bpf/20191222012722.gdqhppxpfmqfqbld@ast-mbp.dhcp.thefacebook.com/ As I mentioned, some of the ideas we used here are based on: https://lore.kernel.org/lkml/20180408065916.GA2832@ircssh-2.c.rugged-nimbus-611.internal Which gave each LSM the ability to add mutable hooks at runtime. If you prefer we can make this generic and allow the LSMs to register mutable hooks with the BPF LSM be the only LSM that uses it (and enforce it with a whitelist). Would this generic approach be something you would consider better than just calling the BPF mutable hooks directly? - KP > > > } while (0) > > > > -#define call_int_hook(FUNC, IRC, ...) ({ \ > > - int RC = IRC; \ > > - do { \ > > - struct security_hook_list *P; \ > > - \ > > +#define call_int_hook(FUNC, IRC, ...) ({ \ > > + int RC = IRC; \ > > + do { \ > > + struct security_hook_list *P; \ > > hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \ > > - RC = P->hook.FUNC(__VA_ARGS__); \ > > - if (RC != 0) \ > > - break; \ > > - } \ > > - } while (0); \ > > - RC; \ > > + RC = P->hook.FUNC(__VA_ARGS__); \ > > + if (RC != 0) \ > > + break; \ > > + } \ > > + if (RC == 0) \ > > + RC = CALL_BPF_LSM_INT_HOOKS(FUNC, __VA_ARGS__); \ > > + } while (0); \ > > + RC; \ > > }) > > > > /* Security operations */