From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CA6541A0BD0 for ; Tue, 24 Feb 2026 01:16:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.49 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771895769; cv=none; b=VVffzJiTKS82hZqcUyzR/kGEG0G2IemBS55J9MOCMVSDlkk+4egJg9djaAHSaQTN5MGLx0DEh4A5+pdxIQfN7KO/Y1NQJKWkpSTHDWIwj+7c6TTads5nAILomr7tWRpJb7NonucM+NnTkssXSGgT6GvTln7nZ2OQeOux3EQAWS4= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771895769; c=relaxed/simple; bh=/WEwMXI9+NBYnYEUwRmLcJPLue1w5B8049oasKnv6uc=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=dml5JZurWEc/FoZNh62FGnpekvQtfafXUEe7YWLlD9GTpwZBXYWFPh1tuo8ePogtmXr7DZvoz956ySnMzqKYfvg37IQXfdKzkUwAllMLKtIyf9LKO+WhkcOE2Od9Qi97C1hFpFvNOCwx5X0FZHFYk2XwbVxhzQJmlbrFBt+1CSY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=MidSfS62; arc=none smtp.client-ip=209.85.218.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="MidSfS62" Received: by mail-ej1-f49.google.com with SMTP id a640c23a62f3a-b8f86167d39so630513266b.0 for ; Mon, 23 Feb 2026 17:16:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1771895766; x=1772500566; darn=vger.kernel.org; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=oyTNmHcTbqte4mfYZdJqgeiDYGxy4Pb6et+1aAN/vEo=; b=MidSfS62yG/6BrxdljqXq7zA2g7ak6LuqOkeDboDKzl/I1z14/EDZRKX2xEVJ7+t6e IwynIFXb0UyScYZEO72fq4jtO29jF8ItF2Bv19y7vTd8IQs+x5V9jS8wNhItLdkgS7On COT9cYxI3z0YgTX0xTeZ1ZyzBNEfDgqqUgQAEcIhdWy+gOrhE4uCIqjXc7o8m6evZ7zS qRs+xxtZy4LE9rlubZb3QJxB0J79jvt6Z+fwoNnHKz+DJ5qeZJuEvJobXWuNvcNYosOZ QKUN6EjJIn6sv98RiAa+EV7Jauh2H2+1NsClQvCCwNttX0nqmyGIQ4pnLIXDk/gwkPo4 KBCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771895766; x=1772500566; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oyTNmHcTbqte4mfYZdJqgeiDYGxy4Pb6et+1aAN/vEo=; b=OYyx6h8v0OhIhTOvpEcIE76ddLf6/PUpTHvcxzotfWjSKCvxR35UJwPP8VeZYJT0ZT eO7hNuOC0AaAekpKoQUpDzTOQj16o6hOO8PPZABssv4EPH9aARs/C4gczGCDu3F5z0Mt SHWhHj6ZxyVERTAgYBsvGiMZd6ApYqKpqICJjwUhROKLuRJGehJrjELBu25TzLWgsHV6 aAFDMrrpxNX+wNFGqf290em8xs5X9F779b/OvPHyENQgQ/BYrVEAENbETYXzq79uiDVH WNFY5vTt1reQbjSORfCoZJpHUhVERtG+3RTSti8AKX+nBed0qjpwtKYl+fLBgj1w+CIV gf7Q== X-Forwarded-Encrypted: i=1; AJvYcCVTgmn8RsBXEt+iye56VJi0axXftrluLGpq1MSwcaNUrXI49Hpzs8zl0bRaZ0bvfX6hyRiNqGhD8IR/jRQ=@vger.kernel.org X-Gm-Message-State: AOJu0YzgF2nFyHG+KtZSR044kBMSIIitFgVxWdvL/+NjrZX4g0pZtbfx pXE7GvPg1545t2NjR/OGqzBhBOctcwcm+DIsBbP8YKzTYeyryuFnbT4HfXXj6bgTRw== X-Gm-Gg: AZuq6aJ2oME1UO6VdsIIlCA25xEq8eMxUjr+KsGJUBmt+yz0Df3+rpnjCxLnsB/6j4/ Rjlj+JDtAfYOz8Vr49sxGU57D0RuSGyzcWNMx4f5RWC4saRTeNXS0zA6wK4MbR9OoNILv7B5YlQ 3Q65HPMSXTSlKziml+ZivGRqRyaL9ialrNpC4QITXTH8XbklAiMj0VVqCGEUEiD3AePP9GUN6Y3 mhGTxeIURzJSCmCs7momc6mjX1glFnjF63aUdCvc1D7jyX5LWNQdSW0PFAvDt+KQvLn1CFxLC29 wAndaPOnGoMXaUqXsWpZl6UuVCcaebUxGdLp25EAINV59ok6gAoi/sF8Y/cRVQaeFbYfS9hoOQ4 gVymWLfW9TDFAHwZb1BgK5SzhHla1uCzZgFaaG+BeO0gH/IO4WQO5UkVn3wVCFb/peZnfD9YT/v s8hkIsYLSwPKoO+VZ3zSVzRZu8jt6ZeH0Dn/Hnl4DXaFt/B2hceLHFDQdIaOtywpA= X-Received: by 2002:a17:907:d8b:b0:b87:1c20:7c63 with SMTP id a640c23a62f3a-b90819bfa47mr720467266b.20.1771895765741; Mon, 23 Feb 2026 17:16:05 -0800 (PST) Received: from google.com (93.50.90.34.bc.googleusercontent.com. [34.90.50.93]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-b9084e4bf5dsm379639166b.32.2026.02.23.17.16.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 23 Feb 2026 17:16:04 -0800 (PST) Date: Tue, 24 Feb 2026 01:16:01 +0000 From: Matt Bobrowski To: Christian Brauner Cc: Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Tejun Heo , KP Singh , bpf@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, Lennart Poettering Subject: Re: [PATCH 1/4] ns: add bpf hooks Message-ID: References: <20260220-work-bpf-namespace-v1-0-866207db7b83@kernel.org> <20260220-work-bpf-namespace-v1-1-866207db7b83@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20260220-work-bpf-namespace-v1-1-866207db7b83@kernel.org> On Fri, Feb 20, 2026 at 01:38:29AM +0100, Christian Brauner wrote: > Add the three namespace lifecycle hooks and make them available to bpf > lsm program types. This allows bpf to supervise namespace creation. I'm > in the process of adding various "universal truth" bpf programs to > systemd that will make use of this. This e.g., allows to lock in a > program into a given set of namespaces. > > Signed-off-by: Christian Brauner > --- > include/linux/bpf_lsm.h | 21 +++++++++++++++++++++ > kernel/bpf/bpf_lsm.c | 25 +++++++++++++++++++++++++ > kernel/nscommon.c | 9 ++++++++- > kernel/nsproxy.c | 7 +++++++ > 4 files changed, 61 insertions(+), 1 deletion(-) > > diff --git a/include/linux/bpf_lsm.h b/include/linux/bpf_lsm.h > index 643809cc78c3..5ae438fdf567 100644 > --- a/include/linux/bpf_lsm.h > +++ b/include/linux/bpf_lsm.h > @@ -12,6 +12,9 @@ > #include > #include > > +struct ns_common; > +struct nsset; > + > #ifdef CONFIG_BPF_LSM > > #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ > @@ -48,6 +51,11 @@ void bpf_lsm_find_cgroup_shim(const struct bpf_prog *prog, bpf_func_t *bpf_func) > > int bpf_lsm_get_retval_range(const struct bpf_prog *prog, > struct bpf_retval_range *range); > + > +int bpf_lsm_namespace_alloc(struct ns_common *ns); > +void bpf_lsm_namespace_free(struct ns_common *ns); > +int bpf_lsm_namespace_install(struct nsset *nsset, struct ns_common *ns); > + > int bpf_set_dentry_xattr_locked(struct dentry *dentry, const char *name__str, > const struct bpf_dynptr *value_p, int flags); > int bpf_remove_dentry_xattr_locked(struct dentry *dentry, const char *name__str); > @@ -104,6 +112,19 @@ static inline bool bpf_lsm_has_d_inode_locked(const struct bpf_prog *prog) > { > return false; > } > + > +static inline int bpf_lsm_namespace_alloc(struct ns_common *ns) > +{ > + return 0; > +} > +static inline void bpf_lsm_namespace_free(struct ns_common *ns) > +{ > +} > +static inline int bpf_lsm_namespace_install(struct nsset *nsset, > + struct ns_common *ns) > +{ > + return 0; > +} > #endif /* CONFIG_BPF_LSM */ > > #endif /* _LINUX_BPF_LSM_H */ > diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c > index 0c4a0c8e6f70..f6378db46220 100644 > --- a/kernel/bpf/bpf_lsm.c > +++ b/kernel/bpf/bpf_lsm.c > @@ -30,10 +30,32 @@ __weak noinline RET bpf_lsm_##NAME(__VA_ARGS__) \ > #include > #undef LSM_HOOK > > +__bpf_hook_start(); > + > +__weak noinline int bpf_lsm_namespace_alloc(struct ns_common *ns) > +{ > + return 0; > +} > + > +__weak noinline void bpf_lsm_namespace_free(struct ns_common *ns) > +{ > +} > + > +__weak noinline int bpf_lsm_namespace_install(struct nsset *nsset, > + struct ns_common *ns) > +{ > + return 0; > +} > + > +__bpf_hook_end(); Is the usage of __bpf_hook_start()/__bpf_hook_end() strictly necessary here? If so, why is that? My understanding was that they're only needed in situations where public function prototypes don't exist (e.g., BPF kfuncs). > #define LSM_HOOK(RET, DEFAULT, NAME, ...) BTF_ID(func, bpf_lsm_##NAME) > BTF_SET_START(bpf_lsm_hooks) > #include > #undef LSM_HOOK > +BTF_ID(func, bpf_lsm_namespace_alloc) > +BTF_ID(func, bpf_lsm_namespace_free) > +BTF_ID(func, bpf_lsm_namespace_install) > BTF_SET_END(bpf_lsm_hooks) > > BTF_SET_START(bpf_lsm_disabled_hooks) > @@ -383,6 +405,8 @@ BTF_ID(func, bpf_lsm_task_prctl) > BTF_ID(func, bpf_lsm_task_setscheduler) > BTF_ID(func, bpf_lsm_task_to_inode) > BTF_ID(func, bpf_lsm_userns_create) > +BTF_ID(func, bpf_lsm_namespace_alloc) > +BTF_ID(func, bpf_lsm_namespace_install) > BTF_SET_END(sleepable_lsm_hooks) > > BTF_SET_START(untrusted_lsm_hooks) > @@ -395,6 +419,7 @@ BTF_ID(func, bpf_lsm_sk_alloc_security) > BTF_ID(func, bpf_lsm_sk_free_security) > #endif /* CONFIG_SECURITY_NETWORK */ > BTF_ID(func, bpf_lsm_task_free) > +BTF_ID(func, bpf_lsm_namespace_free) > BTF_SET_END(untrusted_lsm_hooks) > > bool bpf_lsm_is_sleepable_hook(u32 btf_id) > diff --git a/kernel/nscommon.c b/kernel/nscommon.c > index bdc3c86231d3..c3613cab3d41 100644 > --- a/kernel/nscommon.c > +++ b/kernel/nscommon.c > @@ -1,6 +1,7 @@ > // SPDX-License-Identifier: GPL-2.0-only > /* Copyright (c) 2025 Christian Brauner */ > > +#include > #include > #include > #include > @@ -77,6 +78,7 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_ope > ret = proc_alloc_inum(&ns->inum); > if (ret) > return ret; > + > /* > * Tree ref starts at 0. It's incremented when namespace enters > * active use (installed in nsproxy) and decremented when all > @@ -86,11 +88,16 @@ int __ns_common_init(struct ns_common *ns, u32 ns_type, const struct proc_ns_ope > atomic_set(&ns->__ns_ref_active, 1); > else > atomic_set(&ns->__ns_ref_active, 0); > - return 0; > + > + ret = bpf_lsm_namespace_alloc(ns); > + if (ret && !inum) > + proc_free_inum(ns->inum); > + return ret; > } > > void __ns_common_free(struct ns_common *ns) > { > + bpf_lsm_namespace_free(ns); > proc_free_inum(ns->inum); > } > > diff --git a/kernel/nsproxy.c b/kernel/nsproxy.c > index 259c4b4f1eeb..5742f9664dbb 100644 > --- a/kernel/nsproxy.c > +++ b/kernel/nsproxy.c > @@ -9,6 +9,7 @@ > * Pavel Emelianov > */ > > +#include > #include > #include > #include > @@ -379,6 +380,12 @@ static int prepare_nsset(unsigned flags, struct nsset *nsset) > > static inline int validate_ns(struct nsset *nsset, struct ns_common *ns) > { > + int ret; > + > + ret = bpf_lsm_namespace_install(nsset, ns); > + if (ret) > + return ret; > + > return ns->ops->install(nsset, ns); > } > > > -- > 2.47.3 >