From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f50.google.com (mail-wm1-f50.google.com [209.85.128.50]) (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 F3F093659EF for ; Mon, 23 Feb 2026 12:44:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.50 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771850689; cv=none; b=NNYhcZ7I+NaF0/7UlJ5FaS9pX9QEYE1hsOqLwa/eEHNKXK8OuEMoGB8MGL2szRY2jO1gNgIVBKp2uotsQ0fxXJAkS+8ZfpX7KlIkP3C9s2c9jpETvbbV0ukErJytzuyAlnaC5+2UOu8vUQQEkDRFOGih87r2IFnFW2LroD81hXk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771850689; c=relaxed/simple; bh=M68f3APN5bd7LHloA6NrKBqIULn49u+ujIMSnSth66g=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=I6rgzjwX0ziqqPgeP+SO9huv6WUCIirE04m2AqikSUgCFy7lXt0pD8OB1nnQE01WIa1o6+nWWjgVlG4adrwa+kEOnxuGxcFQkj+6R2cWqOGNOLzwK9s3zUxTJBOXIqGiiFs8L27vanVPEIFDMe8kD1iw2y4IQt6zlrw+Wb3IuiE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lZkgpyZJ; arc=none smtp.client-ip=209.85.128.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lZkgpyZJ" Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-483487335c2so39500215e9.2 for ; Mon, 23 Feb 2026 04:44:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1771850686; x=1772455486; darn=vger.kernel.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:mime-version:date:message-id:from:to:cc :subject:date:message-id:reply-to; bh=xnW1Wqd58lECj55tVKLq7KbjiXWb8oIkcZq5dzctHUw=; b=lZkgpyZJMyM09+sAtaO3V0UzXHQP7CQNT2IjG9sVc0wdU3F2kGV3pfKFY9HSkqdsgi C+MemvkbIzd2+99eyd3Bv8rvgpHGilq6mrKLLATwQ960y/BvCvErppPryVvqOHXKgyJR sj0G+g/4vyM/EmCNhlqe4W/3KY3QnlxsH4omkH2nxdrrXZbDMa60It4wZC2j0tyHRLaU s70Yve3MKnM5umkzfIlPaxV5utVf7L+e8Kw7/iQF9XwgXyQW8+KCgb/HZwkHXnrjV7sq hT8APpHXZW49WjW1a4ZEWTMRHfoThs//HarOUfgFeSQE1KrVVuqtFXCTb1s0geIovADD oJNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1771850686; x=1772455486; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:mime-version:date:message-id:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=xnW1Wqd58lECj55tVKLq7KbjiXWb8oIkcZq5dzctHUw=; b=DNagHxmnafpS27f9fejYTG1Lbn/7jxR2fgN53446AFa5Y/UKGrBiaaN7iLG3NpIXu5 jXTNu5Wq4cOgzWJPDNRfWLjTdUl6L0E1r5DiuUWp8ieLF/fQQ076lowyoFMXJOKjtxrJ uG3FxKCO9xBmq3Bsbjn/u1AKlkKZ9q0c0L42WkDF36NMM927RtkhUfybr34E88Heb+O9 Ksnb7It5sOcaF22PMurQJG5b1ECONEBaq3vi6wZLn161NTLDm3cgVos+AC90USZM8zVy Mx4BoNcxMMeRxnKZ6yVmNJUwWwT2Ru0HdPCz4MrkGSdFp2dqJjBqccIuF64lI+xUG9rA 6z8A== X-Forwarded-Encrypted: i=1; AJvYcCVr2o7Q5c8Z5pRi7enrSYr928uf1wcbJ+WEaOxvktp1CVV1Nh4OUqlDQcazLIhUEcyzPv2hvHu5+MVTpHQ=@vger.kernel.org X-Gm-Message-State: AOJu0YymU/E2rON2hwkXlmDyu4KjGQ1r/E5VvfIgHwIGrFnWrmNwqAA0 h3oojNTE76zeI+8WngfwajjgAJ047BBFZVPUAGkaJIHG4cClgeRxzUQE X-Gm-Gg: AZuq6aKp2WVM+zcA+M8LXHBknbCwCed11r3okRtFWTJMq+L6AP8ydxX7kgGfVJPIbJu 6Fo7TlK0z6AWgqldZl8B0/fOXPyvaelKN3DW5K9sljBQDlSpn6FTLarPmRcE10jexIWskZPxVMJ eNzeg7cDAl35RmZXRuE7QJxvWPzJYPng2QyRTFTtWjdk6OQSDnk89i9mPpjnxwOC0iO7D6KBI8K HkvkxziDcK70UhejyCQeTMhVh+UJSfBMsl1eAq9rTmSz3KHSNVwgz6jwdvMLkQ3iH6hzjapwAGt msINNc9e5M9w3Xdr+umo1hTPrtQ2QtjeTW8RO3n9N23URLc6oNVYDcisu/fK5BGcbFFWnwD7Qcj g1oNiWtj6ntYzX8m9/Ofa4Qtsp5RxHSG1AAup/Yxp4/dkefiVeTJ8mnRS6wcPBlfJp4YoYi4aPF Oyech6AaRay0RbZ5rb7vYyPHqDL5KiZpTLJ3qBAeiBApYXfQ== X-Received: by 2002:a05:600c:638d:b0:480:1e40:3d2 with SMTP id 5b1f17b1804b1-483a95f5a62mr129387105e9.29.1771850685905; Mon, 23 Feb 2026 04:44:45 -0800 (PST) Received: from [10.2.0.2] ([146.70.48.20]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-483a3deb73bsm83621845e9.3.2026.02.23.04.44.36 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 23 Feb 2026 04:44:45 -0800 (PST) Message-ID: <6f4af118-ecb1-422e-a8db-8e6f50d6d988@gmail.com> Date: Mon, 23 Feb 2026 13:44:23 +0100 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Subject: Re: [PATCH 1/4] ns: add bpf hooks To: Christian Brauner , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Tejun Heo Cc: KP Singh , bpf@vger.kernel.org, linux-kernel@vger.kernel.org, cgroups@vger.kernel.org, Lennart Poettering References: <20260220-work-bpf-namespace-v1-0-866207db7b83@kernel.org> <20260220-work-bpf-namespace-v1-1-866207db7b83@kernel.org> Content-Language: en-US From: Djalal Harouni In-Reply-To: <20260220-work-bpf-namespace-v1-1-866207db7b83@kernel.org> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit On 2/20/26 01:38, 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. Thank you Christian, so if this feature is added we will also use it. The commit log says lock in a given set of namespaces where I see only setns path am I right? would it make sense to also have the check around some callers of create_new_namespaces() where appropriate befor nsproxy switch if we don't want to go deep, but allow a bit of control or easy checks around CLONE_NEWNS/mount/pivot_root fs combinations? Or defering the combination checks to userspace makes more sense? The other clone flags are presumably nested so safe, for userns there is already a check, and cgroup+sb you added in the other patch is great! Thank you! > 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(); > + > #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); > } > >