* [PATCH -next 1/2] security: Some cleanup code
From: Cai Xinchen @ 2026-06-26 1:17 UTC (permalink / raw)
To: paul, jmorris, serge, stephen.smalley.work, omosnace, amir73il,
brauner
Cc: linux-security-module, linux-kernel, selinux, caixinchen1,
lujialin4
In-Reply-To: <20260626011720.1144213-1-caixinchen1@huawei.com>
Delete an unnecessary blank line and a blobs variable with
duplicate assignment.
Signed-off-by: Cai Xinchen <caixinchen1@huawei.com>
---
security/lsm_init.c | 1 -
security/selinux/hooks.c | 1 -
2 files changed, 2 deletions(-)
diff --git a/security/lsm_init.c b/security/lsm_init.c
index 7c0fd17f1601..d7384866e3a5 100644
--- a/security/lsm_init.c
+++ b/security/lsm_init.c
@@ -290,7 +290,6 @@ static void __init lsm_prepare(struct lsm_info *lsm)
return;
/* Register the LSM blob sizes. */
- blobs = lsm->blobs;
lsm_blob_size_update(&blobs->lbs_cred, &blob_sizes.lbs_cred);
lsm_blob_size_update(&blobs->lbs_file, &blob_sizes.lbs_file);
lsm_blob_size_update(&blobs->lbs_backing_file,
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 1a713d96206f..e5930ebc9e37 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -1748,7 +1748,6 @@ static int bpf_fd_pass(const struct file *file, u32 sid);
static int __file_has_perm(const struct cred *cred, const struct file *file,
u32 av, bool bf_user_file)
-
{
struct common_audit_data ad;
struct inode *inode;
--
2.34.1
^ permalink raw reply related
* [PATCH -next 0/2] Fix call security_backing_file_free second time
From: Cai Xinchen @ 2026-06-26 1:17 UTC (permalink / raw)
To: paul, jmorris, serge, stephen.smalley.work, omosnace, amir73il,
brauner
Cc: linux-security-module, linux-kernel, selinux, caixinchen1,
lujialin4
I found the following path:
alloc_empty_backing-file
init_file(&ff->file, xxx)
-> file_ref_init(&f->f_ref, 1); // only 1
error = init_backing_file
-> security_backing_file_alloc
-> rc = call_int_hook(backing_file_alloc, ...)
if (unlikely(rc))
security_backing_file_free(backing_file); // first call
if (unlikely(error)) {
fput(&ff->file);
-> if (unlikely(file_ref_put(&file->f_ref))) // zero
__fput_deferred(file);
-> ____fput -> __fput -> file_free(file);
-> backing_file_free(backing_file(f));
-> security_backing_file_free(&ff->file); // second call
Cai Xinchen (2):
security: Some cleanup code
security: Fix call security_backing_file_free second time
security/lsm_init.c | 1 -
security/security.c | 5 +----
security/selinux/hooks.c | 1 -
3 files changed, 1 insertion(+), 6 deletions(-)
--
2.34.1
^ permalink raw reply
* Re: [PATCH bpf-next v2 1/5] bpf: Verify signed loader metadata at load time
From: Alexei Starovoitov @ 2026-06-26 1:16 UTC (permalink / raw)
To: Paul Moore, Daniel Borkmann
Cc: ast, kpsingh, James.Bottomley, bboscaccy, memxor, torvalds, bpf,
linux-security-module
In-Reply-To: <CAHC9VhRV9jW+dwNf7mW+1zTCsZ1xstBAugWL-TJ-DVNARdzC=Q@mail.gmail.com>
On Thu Jun 25, 2026 at 5:59 PM PDT, Paul Moore wrote:
>
> For all the reasons I gave previously, I can't support moving the
> existing security_bpf_prog_load() hook at this point in time.
Paul,
it's not up to you to approve or deny where security_bpf_prog_load()
is called within bpf subsystem as long as it doesn't affect behavior.
Daniel's patch doesn't change observable state from LSMs pov.
It merely moves the call from syscall.c to verifier.c.
So we're going to proceed.
> I'm guessing you still haven't looked at Blaise's patchset from last
> September.
Blaise approach was Nacked because you guys ignored TOCTOU issue.
I pointed it a year ago before AI was a thing. Then sashiko
pointed it again and the bot explained it in detail. It was again
ignored.
Daniel's v1 sadly had the same issue and sashiko spotted it too.
Hence v2 is moving the location of security_bpf_prog_load().
> on-list. As you can see from the lore archives, he has vehemently
> opposed the approach you are proposing for quite a while.
Exactly, because you kept ignoring TOCTOU issue.
Claiming support for signed bpf that can be easily defeated
is a shameless security scam.
^ permalink raw reply
* Re: [PATCH bpf-next v2 1/5] bpf: Verify signed loader metadata at load time
From: Paul Moore @ 2026-06-26 0:59 UTC (permalink / raw)
To: Daniel Borkmann
Cc: ast, kpsingh, James.Bottomley, bboscaccy, memxor, torvalds, bpf,
linux-security-module
In-Reply-To: <c4dc3117-ad84-4c94-952a-cf0642cb42e7@iogearbox.net>
On Thu, Jun 25, 2026 at 4:37 PM Daniel Borkmann <daniel@iogearbox.net> wrote:
> On 6/24/26 8:42 PM, Paul Moore wrote:
> > On Wed, Jun 24, 2026 at 11:37 AM Daniel Borkmann <daniel@iogearbox.net> wrote:
> >> On 6/24/26 5:12 PM, Paul Moore wrote:
> >>> On Wed, Jun 24, 2026 at 10:03 AM Daniel Borkmann <daniel@iogearbox.net> wrote:
> >> [...]
> >>>> include/linux/bpf_verifier.h | 1 +
> >>>> kernel/bpf/syscall.c | 76 +---------------
> >>>> kernel/bpf/verifier.c | 163 ++++++++++++++++++++++++++++++++++-
> >>>> 3 files changed, 165 insertions(+), 75 deletions(-)
> >>>
> >>> ...
> >>>
> >>>> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
> >>>> index b44106c8ea75..026b61d78bdb 100644
> >>>> --- a/kernel/bpf/syscall.c
> >>>> +++ b/kernel/bpf/syscall.c
> >>>> @@ -3189,10 +3121,6 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, struct bpf_log_at
> >>>> if (err < 0)
> >>>> goto free_prog;
> >>>>
> >>>> - err = security_bpf_prog_load(prog, attr, token, uattr.is_kernel);
> >>>> - if (err)
> >>>> - goto free_prog;
> >>>> -
> >>>> /* run eBPF verifier */
> >>>> err = bpf_check(&prog, attr, uattr, attr_log);
> >>>> if (err < 0)
> >>>
> >>> We must preserve the existing location of the call into the
> >>> security_bpf_prog_load() hook as some users rely on this hook being
> >>> called *before* the verifier runs.
> >>
> >> Keep in mind that the verifier /at this point/ of the new location did
> >> _not_ verify anything. So there is no heavy-duty work happening yet at
> >> security_bpf_prog_load. The work that is done before security_bpf_prog_load
> >> is basically setting up the env, initializing the verifier log, and doing
> >> the process_fd_array which is resolving the map/BTF objects. But it did
> >> not walk any instructions etc, so semantics of the security_bpf_prog_load
> >> hook did not change from a user PoV.
> >
> > There is still a reasonable amount of work between the existing and
> > new call sites, and the existing location outside of bpf_check()
> > offers an additional robustness benefit that future verifier changes
> > are less likely to impact the hook. If I'm completely honest, I also
> > need to consider the events of the past year and a half; I'm now much
> > less inclined to support LSM hook changes in the BPF subsystem because
> > I'm very concerned about our ability to revert/modify those changes in
> > the future if needed. That doesn't mean I won't support LSM hook
> > changes in BPF, but such changes are going to need to have a *very*
> > strong advantage from a LSM perspective to offset the risk associated
> > with the current BPF subsystem.
>
> From where you sit with regards to LSMs that is a natural stance towards
> all kernel code, but coming back to the LSM hook, to me this is way too
> excessive that we should add *yet another* LSM hook ...
For all the reasons I gave previously, I can't support moving the
existing security_bpf_prog_load() hook at this point in time.
However, unlike Alexei, I am willing to work with you to develop a new
LSM hook to meet your new needs for enforcing signed BPF program
policies via an LSM (BPF or otherwise). If, as you say, you are not
willing to add a new hook, you will need to find a way to make it work
with the existing hooks/placements.
> > I also have to bring up the same question I asked back in your v1
> > posting: have you discussed this signature approach with Alexei? Your
> > patches abandon and remove KP's signature scheme in favor of what is
> > effectively Blaise's signature scheme from last fall; Alexei argued
> > very strongly against these changes in the past. I'd hate to spend a
> > lot more time reviewing and discussing patches that Alexei is simply
> > going to NACK once again.
>
> I think last time I already stated that this is not "effectively Blaise's
> signature scheme" for couple of reasons ...
I already responded to these three points in your last patchset. It
was sent to you directly, as well as to all of the relevant lists (it
was a reply-all), but here is a lore link if you haven't read it:
https://lore.kernel.org/linux-security-module/CAHC9VhQQKNvP1Who0DdUc0EsVYd_JoSneyzOHZ=Q0MP2qQndCw@mail.gmail.com/
> From where you started out back then, it was the stance that while the
> original KP approach generically addresses all the use cases for loading
> BPF related to relocations via the lskel loader, Blaise proposed a parallel
> scheme which would only allow static programs (only insns, no maps) ...
I'm guessing you still haven't looked at Blaise's patchset from last
September. You were CC'd on the original posting, and I sent you a
lore link in our discussion of your v1 patchset, but I guess it's easy
to get busy/distracted and lose track of things. Regardless, here is
another link to Blaise's patchset:
https://lore.kernel.org/linux-security-module/20250929213520.1821223-1-bboscaccy@linux.microsoft.com/
Blaise's patchset proposed a scheme which ran the PKCS7 signature over
the lskel loader and maps in a way *very* similar to what you are
proposing. Blaise's patchset also supported the same key selection as
KP's scheme so user and session signatures were supported without
issue.
> ... So I cannot
> directly speak for Alexei/KP, but I think this proposal should satisfy all
> parties under one roof.
Considering the striking similarities between what you are proposing
and what Blaise proposed last September I *strongly* suggest getting a
basic thumbs-up or thumbs-down from Alexei on this new/old approach
on-list. As you can see from the lore archives, he has vehemently
opposed the approach you are proposing for quite a while. If he has
changed his mind to understand the value in Blaise's approach of
running the PKCS7 signature over both the lskel loader and maps that's
great, but I worry that will not be the case.
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
From: Paul Moore @ 2026-06-25 20:47 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: David Windsor, Christian Brauner, Alexander Viro, Jan Kara,
Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Eduard, Kumar Kartikeya Dwivedi,
Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, KP Singh, Matt Bobrowski, James Morris,
Serge E . Hallyn, Mimi Zohar, Roberto Sassu, dmitry.kasatkin,
eric.snowberg, Stephen Smalley, Ondrej Mosnacek, Casey Schaufler,
Shuah Khan, LKML, Linux-Fsdevel, bpf, LSM List, linux-integrity,
selinux, open list:KERNEL SELFTEST FRAMEWORK
In-Reply-To: <CAADnVQJM15E0PwomdTiz8zvVMGkqs9mTSjYRdPBF6fgE=tsPCQ@mail.gmail.com>
On Thu, Jun 25, 2026 at 4:44 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
> On Thu, Jun 25, 2026 at 1:40 PM Paul Moore <paul@paul-moore.com> wrote:
> > On Thu, Jun 25, 2026 at 3:58 PM Alexei Starovoitov
> > <alexei.starovoitov@gmail.com> wrote:
> > > On Thu, Jun 25, 2026 at 7:23 AM Christian Brauner <brauner@kernel.org> wrote:
> > > > On 2026-06-23 20:12:32-04:00, Paul Moore wrote:
> > > > > On Jun 18, 2026 David Windsor <dwindsor@gmail.com> wrote:
> > > > >
> > > > > > Add bpf_init_inode_xattr() kfunc for BPF LSM programs to atomically set
> > > > > > xattrs via the inode_init_security hook using lsm_get_xattr_slot().
> > > > > >
> > > > > > The inode_init_security hook previously took the xattr array and count
> > > > > > as two separate output parameters (struct xattr *xattrs, int
> > > > > > *xattr_count), which BPF programs cannot write to. Pass the xattr state
> > > > > > as a single context object (struct xattr_ctx) instead, and have
> > > > > > bpf_init_inode_xattr() take that context directly. Update the existing
> > > > > > in-tree callers of inode_init_security to take and forward the new
> > > > > > xattr_ctx.
> > > > > >
> > > > > > A previous attempt [1] required a kmalloc string output protocol for
> > > > > > the xattr name. Since commit 6bcdfd2cac55 ("security: Allow all LSMs to
> > > > > > provide xattrs for inode_init_security hook") [2], the xattr name is no
> > > > > > longer allocated; it is a static constant.
> > > > > >
> > > > > > Because we rely on the hook-specific ctx layout, the kfunc is
> > > > > > restricted to lsm/inode_init_security. Restrict the xattr names that
> > > > > > may be set via this kfunc to the bpf.* namespace.
> > > > > >
> > > > > > Link: https://kernsec.org/pipermail/linux-security-module-archive/2022-October/034878.html [1]
> > > > > > Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6bcdfd2cac55 [2]
> > > > > > Suggested-by: Song Liu <song@kernel.org>
> > > > > > Signed-off-by: David Windsor <dwindsor@gmail.com>
> > > > > > ---
> > > > > > fs/bpf_fs_kfuncs.c | 106 +++++++++++++++++++++++++++++-
> > > > > > include/linux/bpf.h | 1 +
> > > > > > include/linux/bpf_lsm.h | 3 +
> > > > > > include/linux/evm.h | 9 +--
> > > > > > include/linux/lsm_hook_defs.h | 4 +-
> > > > > > include/linux/lsm_hooks.h | 16 ++---
> > > > > > include/linux/security.h | 5 ++
> > > > > > kernel/bpf/bpf_lsm.c | 10 +++
> > > > > > kernel/bpf/trampoline.c | 3 +
> > > > > > security/bpf/hooks.c | 1 +
> > > > > > security/integrity/evm/evm_main.c | 8 ++-
> > > > > > security/security.c | 7 +-
> > > > > > security/selinux/hooks.c | 4 +-
> > > > > > security/smack/smack_lsm.c | 27 ++++----
> > > > > > 14 files changed, 166 insertions(+), 38 deletions(-)
> > > > >
> > > > > I have a few specific comments below, inline with the patch, but I wanted
> > > > > to make some general comments too.
> > > > >
> > > > > The kfunc additions really don't belong in the VFS kfunc file, please
> > > > > create a LSM kfunc file (call it security/bpf_lsm_kfuncs.c) and add the
> > > > > kfunc code to this new file.
> > > >
> > > > We expose a bunch of VFS heavy operations for various security modules
> > > > and this is really not different. For xattrs we have it all centralized
> > > > in the VFS and in general all VFS related bpf kfuncs should continue
> > > > living there and be registered there. Anything that's just bpf infra
> > > > specific can go to security/bpf/kfuncs.c instead. But anyway, it's a bpf
> > > > specific helper so it's the bpf maintainer's call.
> > >
> > > Completely agree. This is vfs related kfunc and has to be
> > > in fs/bpf_fs_kfuncs.c to make sure vfs maintainers review it now
> > > and all future changes to it.
> >
> > *laughs*
> >
> > Okay, then split out the LSM specific stuff into
> > security/bpf_lsm_kfuncs.c; all the LSM macros/defines/calls should be
> > in the LSM kfuncs file.
>
> Paul,
>
> I'm sorry, but you didn't demonstrate the level of understanding
> of bpf to be trusted to maintain any piece of it.
Alexei,
You haven't demonstrated the understanding or decorum necessary to be
entrusted with any part of the LSM framework.
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
From: Alexei Starovoitov @ 2026-06-25 20:44 UTC (permalink / raw)
To: Paul Moore
Cc: David Windsor, Christian Brauner, Alexander Viro, Jan Kara,
Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Eduard, Kumar Kartikeya Dwivedi,
Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, KP Singh, Matt Bobrowski, James Morris,
Serge E . Hallyn, Mimi Zohar, Roberto Sassu, dmitry.kasatkin,
eric.snowberg, Stephen Smalley, Ondrej Mosnacek, Casey Schaufler,
Shuah Khan, LKML, Linux-Fsdevel, bpf, LSM List, linux-integrity,
selinux, open list:KERNEL SELFTEST FRAMEWORK
In-Reply-To: <CAHC9VhSXXHGRUmJ4YjQ6uEh6dbq7+h_0TwWiV+W5dUWXCTFcfg@mail.gmail.com>
On Thu, Jun 25, 2026 at 1:40 PM Paul Moore <paul@paul-moore.com> wrote:
>
> On Thu, Jun 25, 2026 at 3:58 PM Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> > On Thu, Jun 25, 2026 at 7:23 AM Christian Brauner <brauner@kernel.org> wrote:
> > > On 2026-06-23 20:12:32-04:00, Paul Moore wrote:
> > > > On Jun 18, 2026 David Windsor <dwindsor@gmail.com> wrote:
> > > >
> > > > > Add bpf_init_inode_xattr() kfunc for BPF LSM programs to atomically set
> > > > > xattrs via the inode_init_security hook using lsm_get_xattr_slot().
> > > > >
> > > > > The inode_init_security hook previously took the xattr array and count
> > > > > as two separate output parameters (struct xattr *xattrs, int
> > > > > *xattr_count), which BPF programs cannot write to. Pass the xattr state
> > > > > as a single context object (struct xattr_ctx) instead, and have
> > > > > bpf_init_inode_xattr() take that context directly. Update the existing
> > > > > in-tree callers of inode_init_security to take and forward the new
> > > > > xattr_ctx.
> > > > >
> > > > > A previous attempt [1] required a kmalloc string output protocol for
> > > > > the xattr name. Since commit 6bcdfd2cac55 ("security: Allow all LSMs to
> > > > > provide xattrs for inode_init_security hook") [2], the xattr name is no
> > > > > longer allocated; it is a static constant.
> > > > >
> > > > > Because we rely on the hook-specific ctx layout, the kfunc is
> > > > > restricted to lsm/inode_init_security. Restrict the xattr names that
> > > > > may be set via this kfunc to the bpf.* namespace.
> > > > >
> > > > > Link: https://kernsec.org/pipermail/linux-security-module-archive/2022-October/034878.html [1]
> > > > > Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6bcdfd2cac55 [2]
> > > > > Suggested-by: Song Liu <song@kernel.org>
> > > > > Signed-off-by: David Windsor <dwindsor@gmail.com>
> > > > > ---
> > > > > fs/bpf_fs_kfuncs.c | 106 +++++++++++++++++++++++++++++-
> > > > > include/linux/bpf.h | 1 +
> > > > > include/linux/bpf_lsm.h | 3 +
> > > > > include/linux/evm.h | 9 +--
> > > > > include/linux/lsm_hook_defs.h | 4 +-
> > > > > include/linux/lsm_hooks.h | 16 ++---
> > > > > include/linux/security.h | 5 ++
> > > > > kernel/bpf/bpf_lsm.c | 10 +++
> > > > > kernel/bpf/trampoline.c | 3 +
> > > > > security/bpf/hooks.c | 1 +
> > > > > security/integrity/evm/evm_main.c | 8 ++-
> > > > > security/security.c | 7 +-
> > > > > security/selinux/hooks.c | 4 +-
> > > > > security/smack/smack_lsm.c | 27 ++++----
> > > > > 14 files changed, 166 insertions(+), 38 deletions(-)
> > > >
> > > > I have a few specific comments below, inline with the patch, but I wanted
> > > > to make some general comments too.
> > > >
> > > > The kfunc additions really don't belong in the VFS kfunc file, please
> > > > create a LSM kfunc file (call it security/bpf_lsm_kfuncs.c) and add the
> > > > kfunc code to this new file.
> > >
> > > We expose a bunch of VFS heavy operations for various security modules
> > > and this is really not different. For xattrs we have it all centralized
> > > in the VFS and in general all VFS related bpf kfuncs should continue
> > > living there and be registered there. Anything that's just bpf infra
> > > specific can go to security/bpf/kfuncs.c instead. But anyway, it's a bpf
> > > specific helper so it's the bpf maintainer's call.
> >
> > Completely agree. This is vfs related kfunc and has to be
> > in fs/bpf_fs_kfuncs.c to make sure vfs maintainers review it now
> > and all future changes to it.
>
> *laughs*
>
> Okay, then split out the LSM specific stuff into
> security/bpf_lsm_kfuncs.c; all the LSM macros/defines/calls should be
> in the LSM kfuncs file.
Paul,
I'm sorry, but you didn't demonstrate the level of understanding
of bpf to be trusted to maintain any piece of it.
^ permalink raw reply
* Re: [PATCH v18 3/8] rust: implement `ForeignOwnable` for `Owned`
From: Andreas Hindborg @ 2026-06-25 19:47 UTC (permalink / raw)
To: Gary Guo, Danilo Krummrich, Lorenzo Stoakes, Vlastimil Babka,
Liam R. Howlett, Uladzislau Rezki, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Alice Ryhl,
Trevor Gross, Daniel Almeida, Tamir Duberstein, Alexandre Courbot,
Onur Özkan, Lyude Paul, Greg Kroah-Hartman,
Arve Hjønnevåg, Todd Kjos, Christian Brauner,
Carlos Llamas, Rafael J. Wysocki, Dave Ertman, Ira Weiny,
Leon Romanovsky, Paul Moore, Serge Hallyn, David Airlie,
Simona Vetter, Alexander Viro, Jan Kara, Igor Korotin,
Viresh Kumar, Nishanth Menon, Stephen Boyd, Bjorn Helgaas,
Krzysztof Wilczyński, Pavel Tikhomirov, Michal Wilczynski
Cc: Philipp Stanner, rust-for-linux, linux-kernel, linux-mm,
driver-core, linux-block, linux-security-module, dri-devel,
linux-fsdevel, linux-pm, linux-pci, linux-pwm
In-Reply-To: <DJI5ZY2TPFSW.BEKOVZYRSTQZ@garyguo.net>
"Gary Guo" <gary@garyguo.net> writes:
> On Thu Jun 25, 2026 at 11:15 AM BST, Andreas Hindborg wrote:
>> Implement `ForeignOwnable` for `Owned<T>`. This allows use of `Owned<T>` in
>> places such as the `XArray`.
>>
>> Note that `T` does not need to implement `ForeignOwnable` for `Owned<T>` to
>> implement `ForeignOwnable`.
>>
>> Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
>> ---
>> rust/kernel/owned.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>> 1 file changed, 53 insertions(+)
>>
>> diff --git a/rust/kernel/owned.rs b/rust/kernel/owned.rs
>> index 7fe9ec3e55126..9c92d4a83cc1b 100644
>> --- a/rust/kernel/owned.rs
>> +++ b/rust/kernel/owned.rs
>> @@ -15,6 +15,8 @@
>> ptr::NonNull, //
>> };
>>
>> +use kernel::types::ForeignOwnable;
>> +
>> /// Types that specify their own way of performing allocation and destruction. Typically, this trait
>> /// is implemented on types from the C side.
>> ///
>> @@ -186,3 +188,54 @@ fn drop(&mut self) {
>> unsafe { T::release(self.ptr) };
>> }
>> }
>> +
>> +// SAFETY: We derive the pointer to `T` from a valid `T`, so the returned
>> +// pointer satisfy alignment requirements of `T`.
>> +unsafe impl<T: Ownable> ForeignOwnable for Owned<T> {
>> + const FOREIGN_ALIGN: usize = core::mem::align_of::<T>();
>> +
>> + type Borrowed<'a>
>> + = &'a T
>> + where
>> + Self: 'a;
>> + type BorrowedMut<'a>
>> + = Pin<&'a mut T>
>> + where
>> + Self: 'a;
>> +
>> + #[inline]
>> + fn into_foreign(self) -> *mut kernel::ffi::c_void {
>> + let ptr = self.ptr.as_ptr().cast();
>> + core::mem::forget(self);
>> + ptr
>
> I think the pattern in `into_raw` is better:
>
> ManuallyDrop::new(self).ptr.as_ptr().cast()
>
> Or perhaps this can just use `Self::into_raw(self).as_ptr().cast()`.
>
>> + }
>> +
>> + #[inline]
>> + unsafe fn from_foreign(ptr: *mut kernel::ffi::c_void) -> Self {
>> + // INVARIANT: By the function safety contract, `ptr` was returned by `into_foreign`, which
>> + // gave up exclusive ownership of a valid, pinned `T`; we retake that ownership here.
>> + Self {
>> + // SAFETY: By function safety contract, `ptr` came from
>> + // `into_foreign` and cannot be null.
>> + ptr: unsafe { NonNull::new_unchecked(ptr.cast()) },
>> + }
>> + }
>
> Same here, could be using `Self::from_raw`.
>
> However, the current code looks correct to me regardless, so:
>
> Reviewed-by: Gary Guo <gary@garyguo.net>
I'll defer to `{into,from}_raw`. Keeping your tag.
Best regards,
Andreas Hindborg
^ permalink raw reply
* Re: [PATCH v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
From: Paul Moore @ 2026-06-25 20:40 UTC (permalink / raw)
To: David Windsor
Cc: Alexei Starovoitov, Christian Brauner, Alexander Viro, Jan Kara,
Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Eduard, Kumar Kartikeya Dwivedi,
Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, KP Singh, Matt Bobrowski, James Morris,
Serge E . Hallyn, Mimi Zohar, Roberto Sassu, dmitry.kasatkin,
eric.snowberg, Stephen Smalley, Ondrej Mosnacek, Casey Schaufler,
Shuah Khan, LKML, Linux-Fsdevel, bpf, LSM List, linux-integrity,
selinux, open list:KERNEL SELFTEST FRAMEWORK
In-Reply-To: <CAADnVQKKr5cCYTj8qS7tU-Aeda1iexYUp5aquTjYXMEL656cJQ@mail.gmail.com>
On Thu, Jun 25, 2026 at 3:58 PM Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
> On Thu, Jun 25, 2026 at 7:23 AM Christian Brauner <brauner@kernel.org> wrote:
> > On 2026-06-23 20:12:32-04:00, Paul Moore wrote:
> > > On Jun 18, 2026 David Windsor <dwindsor@gmail.com> wrote:
> > >
> > > > Add bpf_init_inode_xattr() kfunc for BPF LSM programs to atomically set
> > > > xattrs via the inode_init_security hook using lsm_get_xattr_slot().
> > > >
> > > > The inode_init_security hook previously took the xattr array and count
> > > > as two separate output parameters (struct xattr *xattrs, int
> > > > *xattr_count), which BPF programs cannot write to. Pass the xattr state
> > > > as a single context object (struct xattr_ctx) instead, and have
> > > > bpf_init_inode_xattr() take that context directly. Update the existing
> > > > in-tree callers of inode_init_security to take and forward the new
> > > > xattr_ctx.
> > > >
> > > > A previous attempt [1] required a kmalloc string output protocol for
> > > > the xattr name. Since commit 6bcdfd2cac55 ("security: Allow all LSMs to
> > > > provide xattrs for inode_init_security hook") [2], the xattr name is no
> > > > longer allocated; it is a static constant.
> > > >
> > > > Because we rely on the hook-specific ctx layout, the kfunc is
> > > > restricted to lsm/inode_init_security. Restrict the xattr names that
> > > > may be set via this kfunc to the bpf.* namespace.
> > > >
> > > > Link: https://kernsec.org/pipermail/linux-security-module-archive/2022-October/034878.html [1]
> > > > Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6bcdfd2cac55 [2]
> > > > Suggested-by: Song Liu <song@kernel.org>
> > > > Signed-off-by: David Windsor <dwindsor@gmail.com>
> > > > ---
> > > > fs/bpf_fs_kfuncs.c | 106 +++++++++++++++++++++++++++++-
> > > > include/linux/bpf.h | 1 +
> > > > include/linux/bpf_lsm.h | 3 +
> > > > include/linux/evm.h | 9 +--
> > > > include/linux/lsm_hook_defs.h | 4 +-
> > > > include/linux/lsm_hooks.h | 16 ++---
> > > > include/linux/security.h | 5 ++
> > > > kernel/bpf/bpf_lsm.c | 10 +++
> > > > kernel/bpf/trampoline.c | 3 +
> > > > security/bpf/hooks.c | 1 +
> > > > security/integrity/evm/evm_main.c | 8 ++-
> > > > security/security.c | 7 +-
> > > > security/selinux/hooks.c | 4 +-
> > > > security/smack/smack_lsm.c | 27 ++++----
> > > > 14 files changed, 166 insertions(+), 38 deletions(-)
> > >
> > > I have a few specific comments below, inline with the patch, but I wanted
> > > to make some general comments too.
> > >
> > > The kfunc additions really don't belong in the VFS kfunc file, please
> > > create a LSM kfunc file (call it security/bpf_lsm_kfuncs.c) and add the
> > > kfunc code to this new file.
> >
> > We expose a bunch of VFS heavy operations for various security modules
> > and this is really not different. For xattrs we have it all centralized
> > in the VFS and in general all VFS related bpf kfuncs should continue
> > living there and be registered there. Anything that's just bpf infra
> > specific can go to security/bpf/kfuncs.c instead. But anyway, it's a bpf
> > specific helper so it's the bpf maintainer's call.
>
> Completely agree. This is vfs related kfunc and has to be
> in fs/bpf_fs_kfuncs.c to make sure vfs maintainers review it now
> and all future changes to it.
*laughs*
Okay, then split out the LSM specific stuff into
security/bpf_lsm_kfuncs.c; all the LSM macros/defines/calls should be
in the LSM kfuncs file.
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH bpf-next v2 1/5] bpf: Verify signed loader metadata at load time
From: Daniel Borkmann @ 2026-06-25 20:37 UTC (permalink / raw)
To: Paul Moore
Cc: ast, kpsingh, James.Bottomley, bboscaccy, memxor, torvalds, bpf,
linux-security-module
In-Reply-To: <CAHC9VhTF6_VaSm0uOjW1eV05CvsaaL+2jimVuPTXHeLGEQcMPg@mail.gmail.com>
On 6/24/26 8:42 PM, Paul Moore wrote:
> On Wed, Jun 24, 2026 at 11:37 AM Daniel Borkmann <daniel@iogearbox.net> wrote:
>> On 6/24/26 5:12 PM, Paul Moore wrote:
>>> On Wed, Jun 24, 2026 at 10:03 AM Daniel Borkmann <daniel@iogearbox.net> wrote:
>> [...]
>>>> include/linux/bpf_verifier.h | 1 +
>>>> kernel/bpf/syscall.c | 76 +---------------
>>>> kernel/bpf/verifier.c | 163 ++++++++++++++++++++++++++++++++++-
>>>> 3 files changed, 165 insertions(+), 75 deletions(-)
>>>
>>> ...
>>>
>>>> diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
>>>> index b44106c8ea75..026b61d78bdb 100644
>>>> --- a/kernel/bpf/syscall.c
>>>> +++ b/kernel/bpf/syscall.c
>>>> @@ -3189,10 +3121,6 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr, struct bpf_log_at
>>>> if (err < 0)
>>>> goto free_prog;
>>>>
>>>> - err = security_bpf_prog_load(prog, attr, token, uattr.is_kernel);
>>>> - if (err)
>>>> - goto free_prog;
>>>> -
>>>> /* run eBPF verifier */
>>>> err = bpf_check(&prog, attr, uattr, attr_log);
>>>> if (err < 0)
>>>
>>> We must preserve the existing location of the call into the
>>> security_bpf_prog_load() hook as some users rely on this hook being
>>> called *before* the verifier runs.
>>
>> Keep in mind that the verifier /at this point/ of the new location did
>> _not_ verify anything. So there is no heavy-duty work happening yet at
>> security_bpf_prog_load. The work that is done before security_bpf_prog_load
>> is basically setting up the env, initializing the verifier log, and doing
>> the process_fd_array which is resolving the map/BTF objects. But it did
>> not walk any instructions etc, so semantics of the security_bpf_prog_load
>> hook did not change from a user PoV.
>
> There is still a reasonable amount of work between the existing and
> new call sites, and the existing location outside of bpf_check()
> offers an additional robustness benefit that future verifier changes
> are less likely to impact the hook. If I'm completely honest, I also
> need to consider the events of the past year and a half; I'm now much
> less inclined to support LSM hook changes in the BPF subsystem because
> I'm very concerned about our ability to revert/modify those changes in
> the future if needed. That doesn't mean I won't support LSM hook
> changes in BPF, but such changes are going to need to have a *very*
> strong advantage from a LSM perspective to offset the risk associated
> with the current BPF subsystem.
From where you sit with regards to LSMs that is a natural stance towards
all kernel code, but coming back to the LSM hook, to me this is way too
excessive that we should add *yet another* LSM hook. So, just for loading
a *single* BPF program we would then need to pass through *four* layers of
LSM hooks:
1) security_bpf (cmd=PROG_LOAD): for gating various bpf subcmds
2) security_bpf_prog_load: historical admission hook (CAP/token,
prog_type, attach point), pre-verification
3) security_bpf_prog_verify_signature: newly asked admission hook,
same role as 2), plus the BPF signature verdict
4) security_bpf_prog: gate handing the prog fd back to userspace,
verification done & signature verified
The use-cases of 2) and 3) conflate. I strongly prefer to just keep a
total of 3 LSM hooks (as-is today): 3) makes 2) incoherent given they
are the /same class/ of hook, that is, access-control admission on the
load and split only by _what_ they can see. Worse, with the split, for
a signed BPF program security_bpf_prog_load 2) admits a program whose
signature has not been checked, so a policy gating at 2) is structurally
unable to express "admit only verified" and every such policy is forced
onto 3) *anyway*. In other words, you don't get two complementary hooks,
but rather, you get one real admission hook aka 3) plus a now-degraded
/legacy/ hook 2) that can't answer the question operators actually want
to ask. So, no, we're not adding yet another LSM hook.
> Based on what I see in this patchset, the security_bpf_prog_load()
> call should remain in the current location. If you need an additional
> hook after the bpf_prog_verify_signature() call I'm happy to work with
> you on that.
See above.
> I also have to bring up the same question I asked back in your v1
> posting: have you discussed this signature approach with Alexei? Your
> patches abandon and remove KP's signature scheme in favor of what is
> effectively Blaise's signature scheme from last fall; Alexei argued
> very strongly against these changes in the past. I'd hate to spend a
> lot more time reviewing and discussing patches that Alexei is simply
> going to NACK once again.
I think last time I already stated that this is not "effectively Blaise's
signature scheme" for couple of reasons: i) we sign over the raw bytes, not
the derived hash anymore, so the hashing is only used in the context to tie
the map to the loader program, but not anymore for the signature. ii) its one
/single scheme/ and not a parallel branch, so the main loader is built upon
the updated signing scheme rather than having this as an option on the side;
in other words, this replaces the in-loader check and there's a single
PKCS#7-over-bytes path, not an 'if (signature_maps_size)' fork; and iii)
given we expose the verification result in the BPF prog, we also don't need
a new LSM hook and can just piggy back on the existing security_bpf_prog
which also has the possibility to still reject late at this point.
From where you started out back then, it was the stance that while the
original KP approach generically addresses all the use cases for loading
BPF related to relocations via the lskel loader, Blaise proposed a parallel
scheme which would only allow static programs (only insns, no maps) which
is 1% of use cases it covers for the BPF ecosystem and users are stuck on
figuring out which approach they need to go with. So when I took over the
BTF series with the extra kfunc that KP proposed, I was mainly looking at
that series trying to figure out how we can get away without pulling in BTF
complexity for the signed loader and with a compromise that would potentially
satisfy all parties under a unified signature scheme and having the kernel
side (rather than loader side) providing the hard guarantee. So I cannot
directly speak for Alexei/KP, but I think this proposal should satisfy all
parties under one roof. I've build out user space tooling in addition to
test real world BPF program to make sure they work in combination with maps
and BTF under this scheme as well as map-less BPF programs.
>>>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>>>> index 2abc79dbf281..9cd2b62da380 100644
>>>> --- a/kernel/bpf/verifier.c
>>>> +++ b/kernel/bpf/verifier.c
>>>> @@ -19758,11 +19895,28 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr,
>>>> ret = bpf_vlog_init(&env->log, attr_log->level, attr_log->ubuf, attr_log->size);
>>>> if (ret)
>>>> goto err_unlock;
>>>> + if (env->check_signature) {
>>>> + ret = bpf_prog_calc_tag(env->prog);
>>>> + if (ret < 0)
>>>> + goto skip_full_check;
>>>> + }
>>>>
>>>> ret = process_fd_array(env, attr, uattr);
>>>> if (ret)
>>>> goto skip_full_check;
>>>>
>>>> + if (env->check_signature) {
>>>> + ret = bpf_prog_verify_signature(env, attr, uattr.is_kernel);
>>>> + if (ret)
>>>> + goto skip_full_check;
>>>> + signed_map_cnt = env->used_map_cnt;
>>>> + }
>>>> +
>>>> + ret = security_bpf_prog_load(env->prog, attr, env->prog->aux->token,
>>>> + uattr.is_kernel);
>>>> + if (ret)
>>>> + goto skip_full_check;
>>>
>>> We can always create a new LSM hook for this call site, e.g.
>>> security_bpf_prog_verify_signature(...).
>>>
>>>> mark_verifier_state_clean(env);
>>>>
>>>> if (IS_ERR(btf_vmlinux)) {
>
^ permalink raw reply
* Re: [PATCH v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
From: Alexei Starovoitov @ 2026-06-25 19:58 UTC (permalink / raw)
To: Christian Brauner
Cc: Paul Moore, David Windsor, Alexander Viro, Jan Kara,
Alexei Starovoitov, Daniel Borkmann, John Fastabend,
Andrii Nakryiko, Eduard, Kumar Kartikeya Dwivedi,
Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, KP Singh, Matt Bobrowski, James Morris,
Serge E . Hallyn, Mimi Zohar, Roberto Sassu, dmitry.kasatkin,
eric.snowberg, Stephen Smalley, Ondrej Mosnacek, Casey Schaufler,
Shuah Khan, LKML, Linux-Fsdevel, bpf, LSM List, linux-integrity,
selinux, open list:KERNEL SELFTEST FRAMEWORK
In-Reply-To: <20260625-schnabel-rennmaschine-parieren-bcb352c3cf59@brauner>
On Thu, Jun 25, 2026 at 7:23 AM Christian Brauner <brauner@kernel.org> wrote:
>
> On 2026-06-23 20:12:32-04:00, Paul Moore wrote:
> > On Jun 18, 2026 David Windsor <dwindsor@gmail.com> wrote:
> >
> > > Add bpf_init_inode_xattr() kfunc for BPF LSM programs to atomically set
> > > xattrs via the inode_init_security hook using lsm_get_xattr_slot().
> > >
> > > The inode_init_security hook previously took the xattr array and count
> > > as two separate output parameters (struct xattr *xattrs, int
> > > *xattr_count), which BPF programs cannot write to. Pass the xattr state
> > > as a single context object (struct xattr_ctx) instead, and have
> > > bpf_init_inode_xattr() take that context directly. Update the existing
> > > in-tree callers of inode_init_security to take and forward the new
> > > xattr_ctx.
> > >
> > > A previous attempt [1] required a kmalloc string output protocol for
> > > the xattr name. Since commit 6bcdfd2cac55 ("security: Allow all LSMs to
> > > provide xattrs for inode_init_security hook") [2], the xattr name is no
> > > longer allocated; it is a static constant.
> > >
> > > Because we rely on the hook-specific ctx layout, the kfunc is
> > > restricted to lsm/inode_init_security. Restrict the xattr names that
> > > may be set via this kfunc to the bpf.* namespace.
> > >
> > > Link: https://kernsec.org/pipermail/linux-security-module-archive/2022-October/034878.html [1]
> > > Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6bcdfd2cac55 [2]
> > > Suggested-by: Song Liu <song@kernel.org>
> > > Signed-off-by: David Windsor <dwindsor@gmail.com>
> > > ---
> > > fs/bpf_fs_kfuncs.c | 106 +++++++++++++++++++++++++++++-
> > > include/linux/bpf.h | 1 +
> > > include/linux/bpf_lsm.h | 3 +
> > > include/linux/evm.h | 9 +--
> > > include/linux/lsm_hook_defs.h | 4 +-
> > > include/linux/lsm_hooks.h | 16 ++---
> > > include/linux/security.h | 5 ++
> > > kernel/bpf/bpf_lsm.c | 10 +++
> > > kernel/bpf/trampoline.c | 3 +
> > > security/bpf/hooks.c | 1 +
> > > security/integrity/evm/evm_main.c | 8 ++-
> > > security/security.c | 7 +-
> > > security/selinux/hooks.c | 4 +-
> > > security/smack/smack_lsm.c | 27 ++++----
> > > 14 files changed, 166 insertions(+), 38 deletions(-)
> >
> > I have a few specific comments below, inline with the patch, but I wanted
> > to make some general comments too.
> >
> > The kfunc additions really don't belong in the VFS kfunc file, please
> > create a LSM kfunc file (call it security/bpf_lsm_kfuncs.c) and add the
> > kfunc code to this new file.
>
> We expose a bunch of VFS heavy operations for various security modules
> and this is really not different. For xattrs we have it all centralized
> in the VFS and in general all VFS related bpf kfuncs should continue
> living there and be registered there. Anything that's just bpf infra
> specific can go to security/bpf/kfuncs.c instead. But anyway, it's a bpf
> specific helper so it's the bpf maintainer's call.
Completely agree. This is vfs related kfunc and has to be
in fs/bpf_fs_kfuncs.c to make sure vfs maintainers review it now
and all future changes to it.
^ permalink raw reply
* Re: [PATCH v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
From: Paul Moore @ 2026-06-25 16:06 UTC (permalink / raw)
To: Christian Brauner
Cc: David Windsor, viro, jack, ast, daniel, john.fastabend, andrii,
eddyz87, memxor, martin.lau, song, yonghong.song, jolsa, emil,
kpsingh, mattbobrowski, jmorris, serge, zohar, roberto.sassu,
dmitry.kasatkin, eric.snowberg, stephen.smalley.work, omosnace,
casey, shuah, linux-kernel, linux-fsdevel, bpf,
linux-security-module, linux-integrity, selinux, linux-kselftest
In-Reply-To: <20260625-schnabel-rennmaschine-parieren-bcb352c3cf59@brauner>
On Thu, Jun 25, 2026 at 10:23 AM Christian Brauner <brauner@kernel.org> wrote:
> On 2026-06-23 20:12:32-04:00, Paul Moore wrote:
> > On Jun 18, 2026 David Windsor <dwindsor@gmail.com> wrote:
> >
> > > Add bpf_init_inode_xattr() kfunc for BPF LSM programs to atomically set
> > > xattrs via the inode_init_security hook using lsm_get_xattr_slot().
> > >
> > > The inode_init_security hook previously took the xattr array and count
> > > as two separate output parameters (struct xattr *xattrs, int
> > > *xattr_count), which BPF programs cannot write to. Pass the xattr state
> > > as a single context object (struct xattr_ctx) instead, and have
> > > bpf_init_inode_xattr() take that context directly. Update the existing
> > > in-tree callers of inode_init_security to take and forward the new
> > > xattr_ctx.
> > >
> > > A previous attempt [1] required a kmalloc string output protocol for
> > > the xattr name. Since commit 6bcdfd2cac55 ("security: Allow all LSMs to
> > > provide xattrs for inode_init_security hook") [2], the xattr name is no
> > > longer allocated; it is a static constant.
> > >
> > > Because we rely on the hook-specific ctx layout, the kfunc is
> > > restricted to lsm/inode_init_security. Restrict the xattr names that
> > > may be set via this kfunc to the bpf.* namespace.
> > >
> > > Link: https://kernsec.org/pipermail/linux-security-module-archive/2022-October/034878.html [1]
> > > Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6bcdfd2cac55 [2]
> > > Suggested-by: Song Liu <song@kernel.org>
> > > Signed-off-by: David Windsor <dwindsor@gmail.com>
> > > ---
> > > fs/bpf_fs_kfuncs.c | 106 +++++++++++++++++++++++++++++-
> > > include/linux/bpf.h | 1 +
> > > include/linux/bpf_lsm.h | 3 +
> > > include/linux/evm.h | 9 +--
> > > include/linux/lsm_hook_defs.h | 4 +-
> > > include/linux/lsm_hooks.h | 16 ++---
> > > include/linux/security.h | 5 ++
> > > kernel/bpf/bpf_lsm.c | 10 +++
> > > kernel/bpf/trampoline.c | 3 +
> > > security/bpf/hooks.c | 1 +
> > > security/integrity/evm/evm_main.c | 8 ++-
> > > security/security.c | 7 +-
> > > security/selinux/hooks.c | 4 +-
> > > security/smack/smack_lsm.c | 27 ++++----
> > > 14 files changed, 166 insertions(+), 38 deletions(-)
> >
> > I have a few specific comments below, inline with the patch, but I wanted
> > to make some general comments too.
> >
> > The kfunc additions really don't belong in the VFS kfunc file, please
> > create a LSM kfunc file (call it security/bpf_lsm_kfuncs.c) and add the
> > kfunc code to this new file.
>
> We expose a bunch of VFS heavy operations for various security modules
> and this is really not different. For xattrs we have it all centralized
> in the VFS and in general all VFS related bpf kfuncs should continue
> living there and be registered there.
This is really LSM specific code dealing with more LSM bits than
anything else, it belongs in security/bpf_lsm_kfuncs.c.
--
paul-moore.com
^ permalink raw reply
* Re: [PATCH] LSM: check if lsmprop_to_secctx call is supported by LSM
From: Sebastian Bockholt @ 2026-06-25 15:24 UTC (permalink / raw)
To: Casey Schaufler, Sebastian Bockholt, linux-security-module
Cc: serge, jmorris, paul
In-Reply-To: <3a6208ae-ed80-4859-8c41-76010fad3f0d@schaufler-ca.com>
On Wed Jun 24, 2026 at 9:36 PM CEST, Casey Schaufler wrote:
> On 6/24/2026 10:44 AM, Sebastian Bockholt wrote:
>> On Fri Jun 19, 2026 at 7:44 PM CEST, Casey Schaufler wrote:
>>> If you want to help with the multiple LSM support, there's still
>>> plenty of work to do. Let me know.
>> This is my first time trying to contribute to the kernel. If this is the wrong
>> mailing list or wrong format to discuss this, please tell me directly.
>
> You have come to the right place.
>
Thank you and very much appreciated.
>>> If the BPF LSM (the BPF LSM infrastructure, not the eBPF programs)
>>> is going to support security contexts you need to mark it
>>> LSM_FLAGS_EXCLUSIVE.
>> [...]
>>
>>> Until then your choices are:
>>>
>>> - Make the BPF LSM exclusive
>>> - Do not use any of the security context or secid based hooks
>>>
>> I am not trying to load any BPF myself but I am debugging issues when using
>> auditd and apparmor in parallel.
>
> Where does BPF appear in your LSM order?
>
> % cat /sys/kernel/security/lsm
>
> If bpf shows up ahead of apparmor you will see this problem.
>
You were right:
% cat /sys/kernel/security/lsm
capability,landlock,yama,bpf,apparmor
Reordering the LSM order to capability,landlock,yama,apparmor,bpf fixed
the issue.
Thank you
>> As soon as I try to load audit rules from
>> userspace our logs get spammed with "error in audit_log_subj_ctx" messages.
>> According to my analysis, the function call chain leading to the bug is:
>>
>> 1. audit_log_subj_ctx defined in kernel/audit.c
>> // the only LSM enabled is apparmor -> audit_subj_secctx_cnt == 1
>> // confirmed using bpftrace
>> if (audit_subj_secctx_cnt < 2) {
>> error = security_lsmprop_to_secctx(prop, &ctx, LSM_ID_UNDEF);
>> if (error < 0) {
>> if (error != -EINVAL)
>> goto error_path; // produces err msgs in logs
>> return 0;
>> }
>> audit_log_format(ab, " subj=%s", ctx.context);
>> security_release_secctx(&ctx);
>> }
>>
>> 2. security_lsmprop_to_secctx defined in security/security.c
>> // lsm_for_each_hook iterates over all registered LSMs
>> // lsm_id == LSM_ID_UNDEF -> the first lsmprop_to_secctx hook is used
>> // tracing the following probes using bpftrace
>> // kretprobe:apparmor_lsmprop_to_secctx
>> // kretprobe:selinux_lsmprop_to_secctx
>> // kretprobe:smack_lsmprop_to_secctx
>> // kretprobe:bpf_lsm_lsmprop_to_secctx
>> // kretprobe:security_lsmprop_to_scctx
>> // bpf_lsm_lsmprop_to_secctx hook is executed and returns -EOPNOTSUPP
>> lsm_for_each_hook(scall, lsmprop_to_secctx) {
>> if (lsmid != LSM_ID_UNDEF && lsmid != scall->hl->lsmid->id)
>> continue;
>> return scall->hl->hook.lsmprop_to_secctx(prop, cp);
>> }
>>
>> 3. bpf_lsm_lsmprop_to_secctx
>> is defined through #include <linux/lsm_hook_defs.h> and returns
>> -EOPNOTSUPP default. The return value is propagated up the call stack
>> up to security_lsmprop_to_secctx and then to audit_log_subj_ctx.
>> audit_log_subj_ctx checks for error return values and prints the
>> audit_panic "error in audit_log_subj_ctx"
>>
>> My patch could check for any errors or lsmprop_to_secctx but since some might
>> be useful to check by another function in the call stack, i decided to only
>> check if the hook is supported by the LSM.
^ permalink raw reply
* Re: [PATCH v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
From: Christian Brauner @ 2026-06-25 14:23 UTC (permalink / raw)
To: Paul Moore
Cc: David Windsor, viro, brauner, jack, ast, daniel, john.fastabend,
andrii, eddyz87, memxor, martin.lau, song, yonghong.song, jolsa,
emil, kpsingh, mattbobrowski, jmorris, serge, zohar,
roberto.sassu, dmitry.kasatkin, eric.snowberg,
stephen.smalley.work, omosnace, casey, shuah, linux-kernel,
linux-fsdevel, bpf, linux-security-module, linux-integrity,
selinux, linux-kselftest
In-Reply-To: <75d39fd9847cca915d704235264ab474@paul-moore.com>
On 2026-06-23 20:12:32-04:00, Paul Moore wrote:
> On Jun 18, 2026 David Windsor <dwindsor@gmail.com> wrote:
>
> > Add bpf_init_inode_xattr() kfunc for BPF LSM programs to atomically set
> > xattrs via the inode_init_security hook using lsm_get_xattr_slot().
> >
> > The inode_init_security hook previously took the xattr array and count
> > as two separate output parameters (struct xattr *xattrs, int
> > *xattr_count), which BPF programs cannot write to. Pass the xattr state
> > as a single context object (struct xattr_ctx) instead, and have
> > bpf_init_inode_xattr() take that context directly. Update the existing
> > in-tree callers of inode_init_security to take and forward the new
> > xattr_ctx.
> >
> > A previous attempt [1] required a kmalloc string output protocol for
> > the xattr name. Since commit 6bcdfd2cac55 ("security: Allow all LSMs to
> > provide xattrs for inode_init_security hook") [2], the xattr name is no
> > longer allocated; it is a static constant.
> >
> > Because we rely on the hook-specific ctx layout, the kfunc is
> > restricted to lsm/inode_init_security. Restrict the xattr names that
> > may be set via this kfunc to the bpf.* namespace.
> >
> > Link: https://kernsec.org/pipermail/linux-security-module-archive/2022-October/034878.html [1]
> > Link: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=6bcdfd2cac55 [2]
> > Suggested-by: Song Liu <song@kernel.org>
> > Signed-off-by: David Windsor <dwindsor@gmail.com>
> > ---
> > fs/bpf_fs_kfuncs.c | 106 +++++++++++++++++++++++++++++-
> > include/linux/bpf.h | 1 +
> > include/linux/bpf_lsm.h | 3 +
> > include/linux/evm.h | 9 +--
> > include/linux/lsm_hook_defs.h | 4 +-
> > include/linux/lsm_hooks.h | 16 ++---
> > include/linux/security.h | 5 ++
> > kernel/bpf/bpf_lsm.c | 10 +++
> > kernel/bpf/trampoline.c | 3 +
> > security/bpf/hooks.c | 1 +
> > security/integrity/evm/evm_main.c | 8 ++-
> > security/security.c | 7 +-
> > security/selinux/hooks.c | 4 +-
> > security/smack/smack_lsm.c | 27 ++++----
> > 14 files changed, 166 insertions(+), 38 deletions(-)
>
> I have a few specific comments below, inline with the patch, but I wanted
> to make some general comments too.
>
> The kfunc additions really don't belong in the VFS kfunc file, please
> create a LSM kfunc file (call it security/bpf_lsm_kfuncs.c) and add the
> kfunc code to this new file.
We expose a bunch of VFS heavy operations for various security modules
and this is really not different. For xattrs we have it all centralized
in the VFS and in general all VFS related bpf kfuncs should continue
living there and be registered there. Anything that's just bpf infra
specific can go to security/bpf/kfuncs.c instead. But anyway, it's a bpf
specific helper so it's the bpf maintainer's call.
^ permalink raw reply
* Re: [PATCH v18 4/8] rust: page: convert to `Ownable`
From: Gary Guo @ 2026-06-25 13:32 UTC (permalink / raw)
To: Andreas Hindborg, Danilo Krummrich, Lorenzo Stoakes,
Vlastimil Babka, Liam R. Howlett, Uladzislau Rezki, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Alice Ryhl, Trevor Gross, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, Lyude Paul,
Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
Christian Brauner, Carlos Llamas, Rafael J. Wysocki, Dave Ertman,
Ira Weiny, Leon Romanovsky, Paul Moore, Serge Hallyn,
David Airlie, Simona Vetter, Alexander Viro, Jan Kara,
Igor Korotin, Viresh Kumar, Nishanth Menon, Stephen Boyd,
Bjorn Helgaas, Krzysztof Wilczyński, Pavel Tikhomirov,
Michal Wilczynski
Cc: Philipp Stanner, rust-for-linux, linux-kernel, linux-mm,
driver-core, linux-block, linux-security-module, dri-devel,
linux-fsdevel, linux-pm, linux-pci, linux-pwm, Asahi Lina
In-Reply-To: <20260625-unique-ref-v18-4-4e06b5896d47@kernel.org>
On Thu Jun 25, 2026 at 11:15 AM BST, Andreas Hindborg wrote:
> From: Asahi Lina <lina@asahilina.net>
>
> This allows Page references to be returned as borrowed references,
> without necessarily owning the struct page.
>
> Remove `BorrowedPage` and update users to use `Owned<Page>`.
>
> Signed-off-by: Asahi Lina <lina@asahilina.net>
> [ Andreas: Fix formatting and add a safety comment, update users. ]
> Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
Nice to see `BorrowedPage` going away.
Reviewed-by: Gary Guo <gary@garyguo.net>
> ---
> drivers/android/binder/page_range.rs | 10 +--
> rust/kernel/alloc/allocator.rs | 19 +++---
> rust/kernel/alloc/allocator/iter.rs | 6 +-
> rust/kernel/page.rs | 122 +++++++++--------------------------
> 4 files changed, 46 insertions(+), 111 deletions(-)
^ permalink raw reply
* Re: [PATCH v18 3/8] rust: implement `ForeignOwnable` for `Owned`
From: Gary Guo @ 2026-06-25 13:29 UTC (permalink / raw)
To: Andreas Hindborg, Danilo Krummrich, Lorenzo Stoakes,
Vlastimil Babka, Liam R. Howlett, Uladzislau Rezki, Miguel Ojeda,
Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin,
Alice Ryhl, Trevor Gross, Daniel Almeida, Tamir Duberstein,
Alexandre Courbot, Onur Özkan, Lyude Paul,
Greg Kroah-Hartman, Arve Hjønnevåg, Todd Kjos,
Christian Brauner, Carlos Llamas, Rafael J. Wysocki, Dave Ertman,
Ira Weiny, Leon Romanovsky, Paul Moore, Serge Hallyn,
David Airlie, Simona Vetter, Alexander Viro, Jan Kara,
Igor Korotin, Viresh Kumar, Nishanth Menon, Stephen Boyd,
Bjorn Helgaas, Krzysztof Wilczyński, Pavel Tikhomirov,
Michal Wilczynski
Cc: Philipp Stanner, rust-for-linux, linux-kernel, linux-mm,
driver-core, linux-block, linux-security-module, dri-devel,
linux-fsdevel, linux-pm, linux-pci, linux-pwm
In-Reply-To: <20260625-unique-ref-v18-3-4e06b5896d47@kernel.org>
On Thu Jun 25, 2026 at 11:15 AM BST, Andreas Hindborg wrote:
> Implement `ForeignOwnable` for `Owned<T>`. This allows use of `Owned<T>` in
> places such as the `XArray`.
>
> Note that `T` does not need to implement `ForeignOwnable` for `Owned<T>` to
> implement `ForeignOwnable`.
>
> Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
> ---
> rust/kernel/owned.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 53 insertions(+)
>
> diff --git a/rust/kernel/owned.rs b/rust/kernel/owned.rs
> index 7fe9ec3e55126..9c92d4a83cc1b 100644
> --- a/rust/kernel/owned.rs
> +++ b/rust/kernel/owned.rs
> @@ -15,6 +15,8 @@
> ptr::NonNull, //
> };
>
> +use kernel::types::ForeignOwnable;
> +
> /// Types that specify their own way of performing allocation and destruction. Typically, this trait
> /// is implemented on types from the C side.
> ///
> @@ -186,3 +188,54 @@ fn drop(&mut self) {
> unsafe { T::release(self.ptr) };
> }
> }
> +
> +// SAFETY: We derive the pointer to `T` from a valid `T`, so the returned
> +// pointer satisfy alignment requirements of `T`.
> +unsafe impl<T: Ownable> ForeignOwnable for Owned<T> {
> + const FOREIGN_ALIGN: usize = core::mem::align_of::<T>();
> +
> + type Borrowed<'a>
> + = &'a T
> + where
> + Self: 'a;
> + type BorrowedMut<'a>
> + = Pin<&'a mut T>
> + where
> + Self: 'a;
> +
> + #[inline]
> + fn into_foreign(self) -> *mut kernel::ffi::c_void {
> + let ptr = self.ptr.as_ptr().cast();
> + core::mem::forget(self);
> + ptr
I think the pattern in `into_raw` is better:
ManuallyDrop::new(self).ptr.as_ptr().cast()
Or perhaps this can just use `Self::into_raw(self).as_ptr().cast()`.
> + }
> +
> + #[inline]
> + unsafe fn from_foreign(ptr: *mut kernel::ffi::c_void) -> Self {
> + // INVARIANT: By the function safety contract, `ptr` was returned by `into_foreign`, which
> + // gave up exclusive ownership of a valid, pinned `T`; we retake that ownership here.
> + Self {
> + // SAFETY: By function safety contract, `ptr` came from
> + // `into_foreign` and cannot be null.
> + ptr: unsafe { NonNull::new_unchecked(ptr.cast()) },
> + }
> + }
Same here, could be using `Self::from_raw`.
However, the current code looks correct to me regardless, so:
Reviewed-by: Gary Guo <gary@garyguo.net>
Best,
Gary
> +
> + #[inline]
> + unsafe fn borrow<'a>(ptr: *mut kernel::ffi::c_void) -> Self::Borrowed<'a> {
> + // SAFETY: By function safety requirements, `ptr` is valid for use as a
> + // reference for `'a`.
> + unsafe { &*ptr.cast() }
> + }
> +
> + #[inline]
> + unsafe fn borrow_mut<'a>(ptr: *mut kernel::ffi::c_void) -> Self::BorrowedMut<'a> {
> + // SAFETY: By function safety requirements, `ptr` is valid for use as a
> + // unique reference for `'a`.
> + let inner = unsafe { &mut *ptr.cast() };
> +
> + // SAFETY: We never move out of inner, and we do not hand out mutable
> + // references when `T: !Unpin`.
> + unsafe { Pin::new_unchecked(inner) }
> + }
> +}
^ permalink raw reply
* Re: [PATCH] Documentation: landlock: Document fs.resolve_unix audit blocker
From: Günther Noack @ 2026-06-25 12:31 UTC (permalink / raw)
To: Doehyun Baek
Cc: Mickaël Salaün, Jonathan Corbet, Shuah Khan,
Sebastian Andrzej Siewior, linux-security-module, linux-doc,
linux-kernel
In-Reply-To: <20260625092819.1870049-1-doehyunbaek@gmail.com>
On Thu, Jun 25, 2026 at 09:28:19AM +0000, Doehyun Baek wrote:
> The Landlock audit code can emit fs.resolve_unix as a filesystem blocker
> for pathname UNIX socket resolution denials, but the admin guide's blockers
> list did not mention it.
>
> Add the missing blocker name and ABI version to keep the audit
> documentation in sync with the emitted records.
>
> Fixes: ae97330d1bd6 ("landlock: Control pathname UNIX domain socket resolution by path")
> Signed-off-by: Doehyun Baek <doehyunbaek@gmail.com>
> ---
> Documentation/admin-guide/LSM/landlock.rst | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/admin-guide/LSM/landlock.rst b/Documentation/admin-guide/LSM/landlock.rst
> index 314052bbeb0a..8eb85c9381ff 100644
> --- a/Documentation/admin-guide/LSM/landlock.rst
> +++ b/Documentation/admin-guide/LSM/landlock.rst
> @@ -52,6 +52,7 @@ AUDIT_LANDLOCK_ACCESS
> - fs.refer (ABI 2+)
> - fs.truncate (ABI 3+)
> - fs.ioctl_dev (ABI 5+)
> + - fs.resolve_unix (ABI 9+)
>
> **net.*** - Network access rights (ABI 4+):
> - net.bind_tcp - TCP port binding was denied
>
> base-commit: ab9de95c9cf952332ab79453b4b5d1bfca8e514f
> --
> 2.43.0
>
Thanks, good catch!
Reviewed-by: Günther Noack <gnoack@google.com>
^ permalink raw reply
* Re: [PATCH] landlock: Documentation wording cleanups
From: Günther Noack @ 2026-06-25 12:29 UTC (permalink / raw)
To: Mickaël Salaün
Cc: linux-doc, linux-security-module, Alejandro Colomar,
Alejandro Colomar
In-Reply-To: <20260516190112.4924-1-gnoack3000@gmail.com>
On Sat, May 16, 2026 at 09:01:12PM +0200, Günther Noack wrote:
> Documentation cleanups suggested by Alejandro Colomar,
> which we have also applied in the man pages.
>
> Link: https://lore.kernel.org/all/agW4yMK6CinJGqXt@devuan/
> Suggested-by: Alejandro Colomar <alx@kernel.org>
> Signed-off-by: Günther Noack <gnoack3000@gmail.com>
> ---
> include/uapi/linux/landlock.h | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h
> index 10a346e55e95..48c12ddf1108 100644
> --- a/include/uapi/linux/landlock.h
> +++ b/include/uapi/linux/landlock.h
> @@ -255,16 +255,16 @@ struct landlock_net_port_attr {
> * :manpage:`connect(2)` as well as calls to :manpage:`sendmsg(2)` with an
> * explicit recipient address.
> *
> - * This access right only applies to connections to UNIX server sockets which
> + * This access right applies only to connections to UNIX server sockets which
> * were created outside of the newly created Landlock domain (e.g. from within
> * a parent domain or from an unrestricted process). Newly created UNIX
> * servers within the same Landlock domain continue to be accessible. In this
> * regard, %LANDLOCK_ACCESS_FS_RESOLVE_UNIX has the same semantics as the
> * ``LANDLOCK_SCOPE_*`` flags.
> *
> - * If a resolve attempt is denied, the operation returns an ``EACCES`` error,
> - * in line with other filesystem access rights (but different to denials for
> - * abstract UNIX domain sockets).
> + * If a resolution attempt is denied, the operation returns an ``EACCES``
> + * error, in line with other filesystem access rights (but different to
> + * denials for abstract UNIX domain sockets).
> *
> * This access right is available since the ninth version of the Landlock ABI.
> *
> --
> 2.54.0
>
Friendly ping, Mickaël!
This is only a minor change, but keeps the man pages and kernel docs wording in line.
—Günther
^ permalink raw reply
* Re: [stable/linux-6.12.y 0/2] Backport Fix incorrect overlayfs mmap() and mprotect() LSM access controls
From: Greg KH @ 2026-06-25 11:31 UTC (permalink / raw)
To: Cai Xinchen
Cc: viro, brauner, jack, miklos, amir73il, paul, jmorris, serge,
stephen.smalley.work, omosnace, bboscaccy, linux-fsdevel,
linux-kernel, linux-unionfs, linux-security-module, selinux, bpf,
lujialin4
In-Reply-To: <20260622031509.2663919-1-caixinchen1@huawei.com>
On Mon, Jun 22, 2026 at 11:15:07AM +0800, Cai Xinchen wrote:
> Backport the patch series
> "Fix incorrect overlayfs mmap() and mprotect() LSM access controls" [1]
> to 6.12 lts
>
> I test selinux-testsuite[2] overlay test, it pass 135 tests.
>
> [1] https://lore.kernel.org/all/20260403030848.731867-5-paul@paul-moore.com/
> [2] https://github.com/SELinuxProject/selinux-testsuite
Again, upstream git ids are needed. Please redo all of these and
resend.
thanks,
greg k-h
^ permalink raw reply
* Re: [stable/linux-6.18.y 2/2] selinux: fix overlayfs mmap() and mprotect() access checks
From: Greg KH @ 2026-06-25 11:06 UTC (permalink / raw)
To: Cai Xinchen
Cc: viro, brauner, jack, miklos, amir73il, paul, jmorris, serge,
stephen.smalley.work, omosnace, bboscaccy, linux-fsdevel,
linux-kernel, linux-unionfs, linux-security-module, selinux, bpf,
lujialin4
In-Reply-To: <20260622031416.2663747-3-caixinchen1@huawei.com>
On Mon, Jun 22, 2026 at 11:14:16AM +0800, Cai Xinchen wrote:
> From: Paul Moore <paul@paul-moore.com>
>
> The existing SELinux security model for overlayfs is to allow access if
> the current task is able to access the top level file (the "user" file)
> and the mounter's credentials are sufficient to access the lower
> level file (the "backing" file). Unfortunately, the current code does
> not properly enforce these access controls for both mmap() and mprotect()
> operations on overlayfs filesystems.
>
> This patch makes use of the newly created security_mmap_backing_file()
> LSM hook to provide the missing backing file enforcement for mmap()
> operations, and leverages the backing file API and new LSM blob to
> provide the necessary information to properly enforce the mprotect()
> access controls.
>
> Cc: stable@vger.kernel.org
> Acked-by: Amir Goldstein <amir73il@gmail.com>
> Signed-off-by: Paul Moore <paul@paul-moore.com>
> Signed-off-by: Cai Xinchen <caixinchen1@huawei.com>
> ---
> security/selinux/hooks.c | 242 ++++++++++++++++++++++--------
> security/selinux/include/objsec.h | 11 ++
> 2 files changed, 189 insertions(+), 64 deletions(-)
Again, what is the git id?
thanks,
greg k-h
^ permalink raw reply
* Re: [stable/linux-6.18.y 1/2] lsm: add backing_file LSM hooks
From: Greg KH @ 2026-06-25 11:06 UTC (permalink / raw)
To: Cai Xinchen
Cc: viro, brauner, jack, miklos, amir73il, paul, jmorris, serge,
stephen.smalley.work, omosnace, bboscaccy, linux-fsdevel,
linux-kernel, linux-unionfs, linux-security-module, selinux, bpf,
lujialin4
In-Reply-To: <20260622031416.2663747-2-caixinchen1@huawei.com>
On Mon, Jun 22, 2026 at 11:14:15AM +0800, Cai Xinchen wrote:
> From: Paul Moore <paul@paul-moore.com>
>
> Mainline declares lsm_backing_file_cache in security/lsm.h. Linux 6.18.y
> does not have security/lsm_init.c or security/lsm.h; the cache variable
> is defined locally as static struct kmem_cache *lsm_backing_file_cache in
> security/security.c.
>
> Original commit message:
What is the original git commit id?
ANd put the "changes" down in the signed-off-by area, like other
backports normally do please.
thanks,
greg k-h
^ permalink raw reply
* [PATCH v18 5/8] rust: rename `AlwaysRefCounted` to `RefCounted`.
From: Andreas Hindborg @ 2026-06-25 10:15 UTC (permalink / raw)
To: Danilo Krummrich, Lorenzo Stoakes, Vlastimil Babka,
Liam R. Howlett, Uladzislau Rezki, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Alice Ryhl,
Trevor Gross, Daniel Almeida, Tamir Duberstein, Alexandre Courbot,
Onur Özkan, Lyude Paul, Greg Kroah-Hartman,
Arve Hjønnevåg, Todd Kjos, Christian Brauner,
Carlos Llamas, Rafael J. Wysocki, Dave Ertman, Ira Weiny,
Leon Romanovsky, Paul Moore, Serge Hallyn, David Airlie,
Simona Vetter, Alexander Viro, Jan Kara, Igor Korotin,
Viresh Kumar, Nishanth Menon, Stephen Boyd, Bjorn Helgaas,
Krzysztof Wilczyński, Pavel Tikhomirov, Michal Wilczynski
Cc: Andreas Hindborg, Philipp Stanner, rust-for-linux, linux-kernel,
linux-mm, driver-core, linux-block, linux-security-module,
dri-devel, linux-fsdevel, linux-pm, linux-pci, linux-pwm,
Oliver Mangold, Viresh Kumar, Igor Korotin
In-Reply-To: <20260625-unique-ref-v18-0-4e06b5896d47@kernel.org>
From: Oliver Mangold <oliver.mangold@pm.me>
There are types where it may both be reference counted in some cases and
owned in others. In such cases, obtaining `ARef<T>` from `&T` would be
unsound as it allows creation of `ARef<T>` copy from `&Owned<T>`.
Therefore, we split `AlwaysRefCounted` into `RefCounted` (which `ARef<T>`
would require) and a marker trait to indicate that the type is always
reference counted (and not `Ownable`) so the `&T` -> `ARef<T>` conversion
is possible.
- Rename `AlwaysRefCounted` to `RefCounted`.
- Add a new unsafe trait `AlwaysRefCounted`.
- Implement the new trait `AlwaysRefCounted` for the newly renamed
`RefCounted` implementations. This leaves functionality of existing
implementers of `AlwaysRefCounted` intact.
Suggested-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Signed-off-by: Oliver Mangold <oliver.mangold@pm.me>
[ Andreas: Updated commit message and rebase on rust-next (7.2) ]
Acked-by: Igor Korotin <igor.korotin.linux@gmail.com>
Acked-by: Danilo Krummrich <dakr@kernel.org>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Gary Guo <gary@garyguo.net>
Co-developed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
---
rust/kernel/auxiliary.rs | 10 +++++++-
rust/kernel/block/mq/request.rs | 19 +++++++++-----
rust/kernel/cred.rs | 16 ++++++++++--
rust/kernel/device.rs | 12 +++++++--
rust/kernel/device/property.rs | 11 ++++++--
rust/kernel/drm/device.rs | 9 +++++--
rust/kernel/drm/gem/mod.rs | 16 +++++++++---
rust/kernel/fs/file.rs | 23 ++++++++++++++---
rust/kernel/i2c.rs | 13 +++++++---
rust/kernel/mm.rs | 22 +++++++++++++---
rust/kernel/mm/mmput_async.rs | 12 +++++++--
rust/kernel/opp.rs | 16 +++++++++---
rust/kernel/owned.rs | 2 +-
rust/kernel/pci.rs | 10 +++++++-
rust/kernel/pid_namespace.rs | 15 +++++++++--
rust/kernel/platform.rs | 10 +++++++-
rust/kernel/pwm.rs | 12 +++++++--
rust/kernel/sync/aref.rs | 57 +++++++++++++++++++++++++----------------
rust/kernel/task.rs | 13 ++++++++--
rust/kernel/types.rs | 12 ++++++---
rust/kernel/usb.rs | 17 +++++++++---
21 files changed, 255 insertions(+), 72 deletions(-)
diff --git a/rust/kernel/auxiliary.rs b/rust/kernel/auxiliary.rs
index c42928d5a2393..854525289c8b4 100644
--- a/rust/kernel/auxiliary.rs
+++ b/rust/kernel/auxiliary.rs
@@ -19,6 +19,10 @@
to_result, //
},
prelude::*,
+ sync::aref::{
+ AlwaysRefCounted,
+ RefCounted, //
+ },
types::{
ForLt,
ForeignOwnable,
@@ -344,7 +348,7 @@ unsafe impl<Ctx: device::DeviceContext> device::AsBusDevice<Ctx> for Device<Ctx>
kernel::impl_device_context_into_aref!(Device);
// SAFETY: Instances of `Device` are always reference-counted.
-unsafe impl crate::sync::aref::AlwaysRefCounted for Device {
+unsafe impl RefCounted for Device {
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
unsafe { bindings::get_device(self.as_ref().as_raw()) };
@@ -363,6 +367,10 @@ unsafe fn dec_ref(obj: NonNull<Self>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<Device>` from a
+// `&Device`.
+unsafe impl AlwaysRefCounted for Device {}
+
impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> {
fn as_ref(&self) -> &device::Device<Ctx> {
// SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid
diff --git a/rust/kernel/block/mq/request.rs b/rust/kernel/block/mq/request.rs
index ce3e30c81cb5e..8dad15ae4cfb0 100644
--- a/rust/kernel/block/mq/request.rs
+++ b/rust/kernel/block/mq/request.rs
@@ -9,7 +9,11 @@
block::mq::Operations,
error::Result,
sync::{
- aref::{ARef, AlwaysRefCounted},
+ aref::{
+ ARef,
+ AlwaysRefCounted,
+ RefCounted, //
+ },
atomic::Relaxed,
Refcount,
},
@@ -229,11 +233,10 @@ unsafe impl<T: Operations> Send for Request<T> {}
// mutate `self` are internally synchronized`
unsafe impl<T: Operations> Sync for Request<T> {}
-// SAFETY: All instances of `Request<T>` are reference counted. This
-// implementation of `AlwaysRefCounted` ensure that increments to the ref count
-// keeps the object alive in memory at least until a matching reference count
-// decrement is executed.
-unsafe impl<T: Operations> AlwaysRefCounted for Request<T> {
+// SAFETY: All instances of `Request<T>` are reference counted. This implementation of `RefCounted`
+// ensure that increments to the ref count keeps the object alive in memory at least until a
+// matching reference count decrement is executed.
+unsafe impl<T: Operations> RefCounted for Request<T> {
fn inc_ref(&self) {
self.wrapper_ref().refcount().inc();
}
@@ -255,3 +258,7 @@ unsafe fn dec_ref(obj: core::ptr::NonNull<Self>) {
}
}
}
+
+// SAFETY: We currently do not implement `Ownable`, thus it is okay to obtain an `ARef<Request>`
+// from a `&Request` (but this will change in the future).
+unsafe impl<T: Operations> AlwaysRefCounted for Request<T> {}
diff --git a/rust/kernel/cred.rs b/rust/kernel/cred.rs
index ffa156b9df377..b17736a9adcd5 100644
--- a/rust/kernel/cred.rs
+++ b/rust/kernel/cred.rs
@@ -8,7 +8,15 @@
//!
//! Reference: <https://www.kernel.org/doc/html/latest/security/credentials.html>
-use crate::{bindings, sync::aref::AlwaysRefCounted, task::Kuid, types::Opaque};
+use crate::{
+ bindings,
+ sync::aref::RefCounted,
+ task::Kuid,
+ types::{
+ AlwaysRefCounted,
+ Opaque, //
+ }, //
+};
/// Wraps the kernel's `struct cred`.
///
@@ -76,7 +84,7 @@ pub fn euid(&self) -> Kuid {
}
// SAFETY: The type invariants guarantee that `Credential` is always ref-counted.
-unsafe impl AlwaysRefCounted for Credential {
+unsafe impl RefCounted for Credential {
#[inline]
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference means that the refcount is nonzero.
@@ -90,3 +98,7 @@ unsafe fn dec_ref(obj: core::ptr::NonNull<Credential>) {
unsafe { bindings::put_cred(obj.cast().as_ptr()) };
}
}
+
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<Credential>` from a
+// `&Credential`.
+unsafe impl AlwaysRefCounted for Credential {}
diff --git a/rust/kernel/device.rs b/rust/kernel/device.rs
index 645afc49a27d6..2e90f6a06fd05 100644
--- a/rust/kernel/device.rs
+++ b/rust/kernel/device.rs
@@ -8,8 +8,12 @@
bindings,
fmt,
prelude::*,
- sync::aref::ARef,
+ sync::aref::{
+ ARef,
+ RefCounted, //
+ },
types::{
+ AlwaysRefCounted,
ForeignOwnable,
Opaque, //
}, //
@@ -448,7 +452,7 @@ pub fn name(&self) -> &CStr {
kernel::impl_device_context_into_aref!(Device);
// SAFETY: Instances of `Device` are always reference-counted.
-unsafe impl crate::sync::aref::AlwaysRefCounted for Device {
+unsafe impl RefCounted for Device {
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
unsafe { bindings::get_device(self.as_raw()) };
@@ -460,6 +464,10 @@ unsafe fn dec_ref(obj: ptr::NonNull<Self>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<Device>` from a
+// `&Device`.
+unsafe impl AlwaysRefCounted for Device {}
+
// SAFETY: As by the type invariant `Device` can be sent to any thread.
unsafe impl Send for Device {}
diff --git a/rust/kernel/device/property.rs b/rust/kernel/device/property.rs
index 5aead835fbbc0..cee7e25013689 100644
--- a/rust/kernel/device/property.rs
+++ b/rust/kernel/device/property.rs
@@ -14,7 +14,10 @@
fmt,
prelude::*,
str::{CStr, CString},
- sync::aref::ARef,
+ sync::aref::{
+ ARef,
+ AlwaysRefCounted, //
+ },
types::Opaque,
};
@@ -360,7 +363,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
}
// SAFETY: Instances of `FwNode` are always reference-counted.
-unsafe impl crate::sync::aref::AlwaysRefCounted for FwNode {
+unsafe impl crate::sync::aref::RefCounted for FwNode {
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference guarantees that the
// refcount is non-zero.
@@ -374,6 +377,10 @@ unsafe fn dec_ref(obj: ptr::NonNull<Self>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<FwNode>` from a
+// `&FwNode`.
+unsafe impl AlwaysRefCounted for FwNode {}
+
enum Node<'a> {
Borrowed(&'a FwNode),
Owned(ARef<FwNode>),
diff --git a/rust/kernel/drm/device.rs b/rust/kernel/drm/device.rs
index 403fc35353c74..368742a258376 100644
--- a/rust/kernel/drm/device.rs
+++ b/rust/kernel/drm/device.rs
@@ -15,7 +15,8 @@
prelude::*,
sync::aref::{
ARef,
- AlwaysRefCounted, //
+ AlwaysRefCounted,
+ RefCounted, //
},
types::Opaque,
workqueue::{
@@ -227,7 +228,7 @@ fn deref(&self) -> &Self::Target {
// SAFETY: DRM device objects are always reference counted and the get/put functions
// satisfy the requirements.
-unsafe impl<T: drm::Driver> AlwaysRefCounted for Device<T> {
+unsafe impl<T: drm::Driver> RefCounted for Device<T> {
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
unsafe { bindings::drm_dev_get(self.as_raw()) };
@@ -242,6 +243,10 @@ unsafe fn dec_ref(obj: NonNull<Self>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<Device>` from a
+// `&Device`.
+unsafe impl<T: drm::Driver> AlwaysRefCounted for Device<T> {}
+
impl<T: drm::Driver> AsRef<device::Device> for Device<T> {
fn as_ref(&self) -> &device::Device {
// SAFETY: `bindings::drm_device::dev` is valid as long as the DRM device itself is valid,
diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs
index 01b5bd47a3332..30d3718578fe8 100644
--- a/rust/kernel/drm/gem/mod.rs
+++ b/rust/kernel/drm/gem/mod.rs
@@ -17,7 +17,7 @@
prelude::*,
sync::aref::{
ARef,
- AlwaysRefCounted, //
+ RefCounted, //
},
types::Opaque,
};
@@ -29,7 +29,7 @@
#[cfg(CONFIG_RUST_DRM_GEM_SHMEM_HELPER)]
pub mod shmem;
-/// A macro for implementing [`AlwaysRefCounted`] for any GEM object type.
+/// A macro for implementing [`RefCounted`] for any GEM object type.
///
/// Since all GEM objects use the same refcounting scheme.
#[macro_export]
@@ -42,7 +42,7 @@ impl $( <$( $tparam_id:ident ),+> )? for $type:ty
)?
) => {
// SAFETY: All GEM objects are refcounted.
- unsafe impl $( <$( $tparam_id ),+> )? $crate::sync::aref::AlwaysRefCounted for $type
+ unsafe impl $( <$( $tparam_id ),+> )? $crate::sync::aref::RefCounted for $type
where
Self: IntoGEMObject,
$( $( $bind_param : $bind_trait ),+ )?
@@ -61,6 +61,14 @@ unsafe fn dec_ref(obj: core::ptr::NonNull<Self>) {
unsafe { bindings::drm_gem_object_put(obj) };
}
}
+
+ // SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<$type>` from a
+ // `&$type`.
+ unsafe impl $( <$( $tparam_id ),+> )? $crate::sync::aref::AlwaysRefCounted for $type
+ where
+ Self: IntoGEMObject,
+ $( $( $bind_param : $bind_trait ),+ )?
+ {}
};
}
#[cfg_attr(not(CONFIG_RUST_DRM_GEM_SHMEM_HELPER), allow(unused))]
@@ -98,7 +106,7 @@ fn close(_obj: &<Self::Driver as drm::Driver>::Object, _file: &DriverFile<Self>)
}
/// Trait that represents a GEM object subtype
-pub trait IntoGEMObject: Sized + super::private::Sealed + AlwaysRefCounted {
+pub trait IntoGEMObject: Sized + super::private::Sealed + RefCounted {
/// Returns a reference to the raw `drm_gem_object` structure, which must be valid as long as
/// this owning object is valid.
fn as_raw(&self) -> *mut bindings::drm_gem_object;
diff --git a/rust/kernel/fs/file.rs b/rust/kernel/fs/file.rs
index 23ee689bd2400..720e57418358d 100644
--- a/rust/kernel/fs/file.rs
+++ b/rust/kernel/fs/file.rs
@@ -12,8 +12,15 @@
cred::Credential,
error::{code::*, to_result, Error, Result},
fmt,
- sync::aref::{ARef, AlwaysRefCounted},
- types::{NotThreadSafe, Opaque},
+ sync::aref::{
+ ARef,
+ RefCounted, //
+ },
+ types::{
+ AlwaysRefCounted,
+ NotThreadSafe,
+ Opaque, //
+ }, //
};
use core::ptr;
@@ -197,7 +204,7 @@ unsafe impl Sync for File {}
// SAFETY: The type invariants guarantee that `File` is always ref-counted. This implementation
// makes `ARef<File>` own a normal refcount.
-unsafe impl AlwaysRefCounted for File {
+unsafe impl RefCounted for File {
#[inline]
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference means that the refcount is nonzero.
@@ -212,6 +219,10 @@ unsafe fn dec_ref(obj: ptr::NonNull<File>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<File>` from a
+// `&File`.
+unsafe impl AlwaysRefCounted for File {}
+
/// Wraps the kernel's `struct file`. Not thread safe.
///
/// This type represents a file that is not known to be safe to transfer across thread boundaries.
@@ -233,7 +244,7 @@ pub struct LocalFile {
// SAFETY: The type invariants guarantee that `LocalFile` is always ref-counted. This implementation
// makes `ARef<LocalFile>` own a normal refcount.
-unsafe impl AlwaysRefCounted for LocalFile {
+unsafe impl RefCounted for LocalFile {
#[inline]
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference means that the refcount is nonzero.
@@ -249,6 +260,10 @@ unsafe fn dec_ref(obj: ptr::NonNull<LocalFile>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<LocalFile>` from a
+// `&LocalFile`.
+unsafe impl AlwaysRefCounted for LocalFile {}
+
impl LocalFile {
/// Constructs a new `struct file` wrapper from a file descriptor.
///
diff --git a/rust/kernel/i2c.rs b/rust/kernel/i2c.rs
index 624b971ca8b0b..02b2c9220eb11 100644
--- a/rust/kernel/i2c.rs
+++ b/rust/kernel/i2c.rs
@@ -18,7 +18,8 @@
prelude::*,
sync::aref::{
ARef,
- AlwaysRefCounted, //
+ AlwaysRefCounted,
+ RefCounted, //
},
types::Opaque, //
};
@@ -424,7 +425,7 @@ pub fn get(index: i32) -> Result<ARef<Self>> {
kernel::impl_device_context_into_aref!(I2cAdapter);
// SAFETY: Instances of `I2cAdapter` are always reference-counted.
-unsafe impl AlwaysRefCounted for I2cAdapter {
+unsafe impl RefCounted for I2cAdapter {
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
unsafe { bindings::i2c_get_adapter(self.index()) };
@@ -435,6 +436,9 @@ unsafe fn dec_ref(obj: NonNull<Self>) {
unsafe { bindings::i2c_put_adapter(obj.as_ref().as_raw()) }
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<Device>` from an
+// `&I2cAdapter`.
+unsafe impl AlwaysRefCounted for I2cAdapter {}
/// The i2c board info representation
///
@@ -500,7 +504,7 @@ unsafe impl<Ctx: device::DeviceContext> device::AsBusDevice<Ctx> for I2cClient<C
kernel::impl_device_context_into_aref!(I2cClient);
// SAFETY: Instances of `I2cClient` are always reference-counted.
-unsafe impl AlwaysRefCounted for I2cClient {
+unsafe impl RefCounted for I2cClient {
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
unsafe { bindings::get_device(self.as_ref().as_raw()) };
@@ -511,6 +515,9 @@ unsafe fn dec_ref(obj: NonNull<Self>) {
unsafe { bindings::put_device(&raw mut (*obj.as_ref().as_raw()).dev) }
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<Device>` from an
+// `&I2cClient`.
+unsafe impl AlwaysRefCounted for I2cClient {}
impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for I2cClient<Ctx> {
fn as_ref(&self) -> &device::Device<Ctx> {
diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs
index 4764d7b68f2a7..83ed94fca14ca 100644
--- a/rust/kernel/mm.rs
+++ b/rust/kernel/mm.rs
@@ -13,8 +13,15 @@
use crate::{
bindings,
- sync::aref::{ARef, AlwaysRefCounted},
- types::{NotThreadSafe, Opaque},
+ sync::aref::{
+ ARef,
+ RefCounted, //
+ },
+ types::{
+ AlwaysRefCounted,
+ NotThreadSafe,
+ Opaque, //
+ }, //
};
use core::{ops::Deref, ptr::NonNull};
@@ -55,7 +62,7 @@ unsafe impl Send for Mm {}
unsafe impl Sync for Mm {}
// SAFETY: By the type invariants, this type is always refcounted.
-unsafe impl AlwaysRefCounted for Mm {
+unsafe impl RefCounted for Mm {
#[inline]
fn inc_ref(&self) {
// SAFETY: The pointer is valid since self is a reference.
@@ -69,6 +76,9 @@ unsafe fn dec_ref(obj: NonNull<Self>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<Mm>` from a `&Mm`.
+unsafe impl AlwaysRefCounted for Mm {}
+
/// A wrapper for the kernel's `struct mm_struct`.
///
/// This type is like [`Mm`], but with non-zero `mm_users`. It can only be used when `mm_users` can
@@ -91,7 +101,7 @@ unsafe impl Send for MmWithUser {}
unsafe impl Sync for MmWithUser {}
// SAFETY: By the type invariants, this type is always refcounted.
-unsafe impl AlwaysRefCounted for MmWithUser {
+unsafe impl RefCounted for MmWithUser {
#[inline]
fn inc_ref(&self) {
// SAFETY: The pointer is valid since self is a reference.
@@ -105,6 +115,10 @@ unsafe fn dec_ref(obj: NonNull<Self>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<MmWithUser>` from a
+// `&MmWithUser`.
+unsafe impl AlwaysRefCounted for MmWithUser {}
+
// Make all `Mm` methods available on `MmWithUser`.
impl Deref for MmWithUser {
type Target = Mm;
diff --git a/rust/kernel/mm/mmput_async.rs b/rust/kernel/mm/mmput_async.rs
index b8d2f051225c7..8fbc396e46028 100644
--- a/rust/kernel/mm/mmput_async.rs
+++ b/rust/kernel/mm/mmput_async.rs
@@ -10,7 +10,11 @@
use crate::{
bindings,
mm::MmWithUser,
- sync::aref::{ARef, AlwaysRefCounted},
+ sync::aref::{
+ ARef,
+ RefCounted, //
+ },
+ types::AlwaysRefCounted,
};
use core::{ops::Deref, ptr::NonNull};
@@ -34,7 +38,7 @@ unsafe impl Send for MmWithUserAsync {}
unsafe impl Sync for MmWithUserAsync {}
// SAFETY: By the type invariants, this type is always refcounted.
-unsafe impl AlwaysRefCounted for MmWithUserAsync {
+unsafe impl RefCounted for MmWithUserAsync {
#[inline]
fn inc_ref(&self) {
// SAFETY: The pointer is valid since self is a reference.
@@ -48,6 +52,10 @@ unsafe fn dec_ref(obj: NonNull<Self>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<MmWithUserAsync>`
+// from a `&MmWithUserAsync`.
+unsafe impl AlwaysRefCounted for MmWithUserAsync {}
+
// Make all `MmWithUser` methods available on `MmWithUserAsync`.
impl Deref for MmWithUserAsync {
type Target = MmWithUser;
diff --git a/rust/kernel/opp.rs b/rust/kernel/opp.rs
index 62e44676125d1..b8db6bdefd077 100644
--- a/rust/kernel/opp.rs
+++ b/rust/kernel/opp.rs
@@ -16,8 +16,14 @@
ffi::{c_char, c_ulong},
prelude::*,
str::CString,
- sync::aref::{ARef, AlwaysRefCounted},
- types::Opaque,
+ sync::aref::{
+ ARef,
+ RefCounted, //
+ },
+ types::{
+ AlwaysRefCounted,
+ Opaque, //
+ }, //
};
#[cfg(CONFIG_CPU_FREQ)]
@@ -1041,7 +1047,7 @@ unsafe impl Send for OPP {}
unsafe impl Sync for OPP {}
/// SAFETY: The type invariants guarantee that [`OPP`] is always refcounted.
-unsafe impl AlwaysRefCounted for OPP {
+unsafe impl RefCounted for OPP {
#[inline]
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference means that the refcount is nonzero.
@@ -1055,6 +1061,10 @@ unsafe fn dec_ref(obj: ptr::NonNull<Self>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<OPP>` from an
+// `&OPP`.
+unsafe impl AlwaysRefCounted for OPP {}
+
impl OPP {
/// Creates an owned reference to a [`OPP`] from a valid pointer.
///
diff --git a/rust/kernel/owned.rs b/rust/kernel/owned.rs
index 9c92d4a83cc1b..e79936c00002c 100644
--- a/rust/kernel/owned.rs
+++ b/rust/kernel/owned.rs
@@ -27,7 +27,7 @@
///
/// Note: The underlying object is not required to provide internal reference counting, because it
/// represents a unique, owned reference. If reference counting (on the Rust side) is required,
-/// [`AlwaysRefCounted`](crate::sync::aref::AlwaysRefCounted) should be implemented.
+/// [`RefCounted`](crate::types::RefCounted) should be implemented.
///
/// # Examples
///
diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
index 5071cae6543fd..ea9ef99cecb07 100644
--- a/rust/kernel/pci.rs
+++ b/rust/kernel/pci.rs
@@ -19,6 +19,10 @@
},
prelude::*,
str::CStr,
+ sync::aref::{
+ AlwaysRefCounted,
+ RefCounted, //
+ },
types::Opaque,
ThisModule, //
};
@@ -481,7 +485,7 @@ unsafe impl<Ctx: device::DeviceContext> device::AsBusDevice<Ctx> for Device<Ctx>
impl<'a> crate::dma::Device<'a> for Device<device::Core<'a>> {}
// SAFETY: Instances of `Device` are always reference-counted.
-unsafe impl crate::sync::aref::AlwaysRefCounted for Device {
+unsafe impl RefCounted for Device {
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
unsafe { bindings::pci_dev_get(self.as_raw()) };
@@ -493,6 +497,10 @@ unsafe fn dec_ref(obj: NonNull<Self>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<Device>` from a
+// `&Device`.
+unsafe impl AlwaysRefCounted for Device {}
+
impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> {
fn as_ref(&self) -> &device::Device<Ctx> {
// SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid
diff --git a/rust/kernel/pid_namespace.rs b/rust/kernel/pid_namespace.rs
index 979a9718f153d..067f68b99e8c5 100644
--- a/rust/kernel/pid_namespace.rs
+++ b/rust/kernel/pid_namespace.rs
@@ -7,7 +7,14 @@
//! C header: [`include/linux/pid_namespace.h`](srctree/include/linux/pid_namespace.h) and
//! [`include/linux/pid.h`](srctree/include/linux/pid.h)
-use crate::{bindings, sync::aref::AlwaysRefCounted, types::Opaque};
+use crate::{
+ bindings,
+ sync::aref::RefCounted,
+ types::{
+ AlwaysRefCounted,
+ Opaque, //
+ }, //
+};
use core::ptr;
/// Wraps the kernel's `struct pid_namespace`. Thread safe.
@@ -41,7 +48,7 @@ pub unsafe fn from_ptr<'a>(ptr: *const bindings::pid_namespace) -> &'a Self {
}
// SAFETY: Instances of `PidNamespace` are always reference-counted.
-unsafe impl AlwaysRefCounted for PidNamespace {
+unsafe impl RefCounted for PidNamespace {
#[inline]
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference means that the refcount is nonzero.
@@ -55,6 +62,10 @@ unsafe fn dec_ref(obj: ptr::NonNull<PidNamespace>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<PidNamespace>` from
+// a `&PidNamespace`.
+unsafe impl AlwaysRefCounted for PidNamespace {}
+
// SAFETY:
// - `PidNamespace::dec_ref` can be called from any thread.
// - It is okay to send ownership of `PidNamespace` across thread boundaries.
diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs
index 9b362e0495d32..0ba676445b06d 100644
--- a/rust/kernel/platform.rs
+++ b/rust/kernel/platform.rs
@@ -27,6 +27,10 @@
},
of,
prelude::*,
+ sync::aref::{
+ AlwaysRefCounted,
+ RefCounted, //
+ },
types::Opaque,
ThisModule, //
};
@@ -518,7 +522,7 @@ pub fn optional_irq_by_name(&self, name: &CStr) -> Result<IrqRequest<'_>> {
impl<'a> crate::dma::Device<'a> for Device<device::Core<'a>> {}
// SAFETY: Instances of `Device` are always reference-counted.
-unsafe impl crate::sync::aref::AlwaysRefCounted for Device {
+unsafe impl RefCounted for Device {
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference guarantees that the refcount is non-zero.
unsafe { bindings::get_device(self.as_ref().as_raw()) };
@@ -530,6 +534,10 @@ unsafe fn dec_ref(obj: NonNull<Self>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<Device>` from a
+// `&Device`.
+unsafe impl AlwaysRefCounted for Device {}
+
impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> {
fn as_ref(&self) -> &device::Device<Ctx> {
// SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid
diff --git a/rust/kernel/pwm.rs b/rust/kernel/pwm.rs
index 6c9d667009ef7..2d1cd74dd98e1 100644
--- a/rust/kernel/pwm.rs
+++ b/rust/kernel/pwm.rs
@@ -13,7 +13,11 @@
devres,
error::{self, to_result},
prelude::*,
- sync::aref::{ARef, AlwaysRefCounted},
+ sync::aref::{
+ ARef,
+ AlwaysRefCounted,
+ RefCounted, //
+ },
types::Opaque, //
};
use core::{
@@ -629,7 +633,7 @@ pub fn new<'a>(
}
// SAFETY: Implements refcounting for `Chip` using the embedded `struct device`.
-unsafe impl<T: PwmOps> AlwaysRefCounted for Chip<T> {
+unsafe impl<T: PwmOps> RefCounted for Chip<T> {
#[inline]
fn inc_ref(&self) {
// SAFETY: `self.0.get()` points to a valid `pwm_chip` because `self` exists.
@@ -647,6 +651,10 @@ unsafe fn dec_ref(obj: NonNull<Chip<T>>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<Chip<T>>` from a
+// `&Chip<T>`.
+unsafe impl<T: PwmOps> AlwaysRefCounted for Chip<T> {}
+
// SAFETY: `Chip` is a wrapper around `*mut bindings::pwm_chip`. The underlying C
// structure's state is managed and synchronized by the kernel's device model
// and PWM core locking mechanisms. Therefore, it is safe to move the `Chip`
diff --git a/rust/kernel/sync/aref.rs b/rust/kernel/sync/aref.rs
index 3bd5eb8a1a526..fb7466a362741 100644
--- a/rust/kernel/sync/aref.rs
+++ b/rust/kernel/sync/aref.rs
@@ -24,11 +24,9 @@
ptr::NonNull, //
};
-/// Types that are _always_ reference counted.
+/// Types that are internally reference counted.
///
/// It allows such types to define their own custom ref increment and decrement functions.
-/// Additionally, it allows users to convert from a shared reference `&T` to an owned reference
-/// [`ARef<T>`].
///
/// This is usually implemented by wrappers to existing structures on the C side of the code. For
/// Rust code, the recommendation is to use [`Arc`](crate::sync::Arc) to create reference-counted
@@ -45,9 +43,8 @@
/// at least until matching decrements are performed.
///
/// Implementers must also ensure that all instances are reference-counted. (Otherwise they
-/// won't be able to honour the requirement that [`AlwaysRefCounted::inc_ref`] keep the object
-/// alive.)
-pub unsafe trait AlwaysRefCounted {
+/// won't be able to honour the requirement that [`RefCounted::inc_ref`] keep the object alive.)
+pub unsafe trait RefCounted {
/// Increments the reference count on the object.
fn inc_ref(&self);
@@ -60,11 +57,27 @@ pub unsafe trait AlwaysRefCounted {
/// Callers must ensure that there was a previous matching increment to the reference count,
/// and that the object is no longer used after its reference count is decremented (as it may
/// result in the object being freed), unless the caller owns another increment on the refcount
- /// (e.g., it calls [`AlwaysRefCounted::inc_ref`] twice, then calls
- /// [`AlwaysRefCounted::dec_ref`] once).
+ /// (e.g., it calls [`RefCounted::inc_ref`] twice, then calls [`RefCounted::dec_ref`] once).
unsafe fn dec_ref(obj: NonNull<Self>);
}
+/// Always reference-counted type.
+///
+/// It allows deriving a counted reference [`ARef<T>`] from a `&T`.
+///
+/// This provides some convenience, but it allows "escaping" borrow checks on `&T`. As it
+/// complicates attempts to ensure that a reference to T is unique, it is optional to provide for
+/// [`RefCounted`] types. See *Safety* below.
+///
+/// # Safety
+///
+/// Implementers must ensure that no safety invariants are violated by upgrading an `&T` to an
+/// [`ARef<T>`]. In particular that implies [`AlwaysRefCounted`] and [`crate::types::Ownable`]
+/// cannot be implemented for the same type, as this would allow violating the uniqueness guarantee
+/// of [`crate::types::Owned<T>`] by dereferencing it into an `&T` and obtaining an [`ARef`] from
+/// that.
+pub unsafe trait AlwaysRefCounted: RefCounted {}
+
/// An owned reference to an always-reference-counted object.
///
/// The object's reference count is automatically decremented when an instance of [`ARef`] is
@@ -75,7 +88,7 @@ pub unsafe trait AlwaysRefCounted {
///
/// The pointer stored in `ptr` is non-null and valid for the lifetime of the [`ARef`] instance. In
/// particular, the [`ARef`] instance owns an increment on the underlying object's reference count.
-pub struct ARef<T: AlwaysRefCounted> {
+pub struct ARef<T: RefCounted> {
ptr: NonNull<T>,
_p: PhantomData<T>,
}
@@ -84,19 +97,19 @@ pub struct ARef<T: AlwaysRefCounted> {
// it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally, it needs
// `T` to be `Send` because any thread that has an `ARef<T>` may ultimately access `T` using a
// mutable reference, for example, when the reference count reaches zero and `T` is dropped.
-unsafe impl<T: AlwaysRefCounted + Sync + Send> Send for ARef<T> {}
+unsafe impl<T: RefCounted + Sync + Send> Send for ARef<T> {}
// SAFETY: It is safe to send `&ARef<T>` to another thread when the underlying `T` is `Sync`
// because it effectively means sharing `&T` (which is safe because `T` is `Sync`); additionally,
// it needs `T` to be `Send` because any thread that has a `&ARef<T>` may clone it and get an
// `ARef<T>` on that thread, so the thread may ultimately access `T` using a mutable reference, for
// example, when the reference count reaches zero and `T` is dropped.
-unsafe impl<T: AlwaysRefCounted + Sync + Send> Sync for ARef<T> {}
+unsafe impl<T: RefCounted + Sync + Send> Sync for ARef<T> {}
// Even if `T` is pinned, pointers to `T` can still move.
-impl<T: AlwaysRefCounted> Unpin for ARef<T> {}
+impl<T: RefCounted> Unpin for ARef<T> {}
-impl<T: AlwaysRefCounted> ARef<T> {
+impl<T: RefCounted> ARef<T> {
/// Creates a new instance of [`ARef`].
///
/// It takes over an increment of the reference count on the underlying object.
@@ -125,12 +138,12 @@ pub unsafe fn from_raw(ptr: NonNull<T>) -> Self {
///
/// ```
/// use core::ptr::NonNull;
- /// use kernel::sync::aref::{ARef, AlwaysRefCounted};
+ /// use kernel::sync::aref::{ARef, RefCounted};
///
/// struct Empty {}
///
/// # // SAFETY: TODO.
- /// unsafe impl AlwaysRefCounted for Empty {
+ /// unsafe impl RefCounted for Empty {
/// fn inc_ref(&self) {}
/// unsafe fn dec_ref(_obj: NonNull<Self>) {}
/// }
@@ -148,7 +161,7 @@ pub fn into_raw(me: Self) -> NonNull<T> {
}
}
-impl<T: AlwaysRefCounted> Clone for ARef<T> {
+impl<T: RefCounted> Clone for ARef<T> {
fn clone(&self) -> Self {
self.inc_ref();
// SAFETY: We just incremented the refcount above.
@@ -156,7 +169,7 @@ fn clone(&self) -> Self {
}
}
-impl<T: AlwaysRefCounted> Deref for ARef<T> {
+impl<T: RefCounted> Deref for ARef<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
@@ -173,7 +186,7 @@ fn from(b: &T) -> Self {
}
}
-impl<T: AlwaysRefCounted> Drop for ARef<T> {
+impl<T: RefCounted> Drop for ARef<T> {
fn drop(&mut self) {
// SAFETY: The type invariants guarantee that the `ARef` owns the reference we're about to
// decrement.
@@ -183,19 +196,19 @@ fn drop(&mut self) {
impl<T, U> PartialEq<ARef<U>> for ARef<T>
where
- T: AlwaysRefCounted + PartialEq<U>,
- U: AlwaysRefCounted,
+ T: RefCounted + PartialEq<U>,
+ U: RefCounted,
{
#[inline]
fn eq(&self, other: &ARef<U>) -> bool {
T::eq(&**self, &**other)
}
}
-impl<T: AlwaysRefCounted + Eq> Eq for ARef<T> {}
+impl<T: RefCounted + Eq> Eq for ARef<T> {}
impl<T, U> PartialEq<&'_ U> for ARef<T>
where
- T: AlwaysRefCounted + PartialEq<U>,
+ T: RefCounted + PartialEq<U>,
{
#[inline]
fn eq(&self, other: &&U) -> bool {
diff --git a/rust/kernel/task.rs b/rust/kernel/task.rs
index 38273f4eedb51..6259430b0ca31 100644
--- a/rust/kernel/task.rs
+++ b/rust/kernel/task.rs
@@ -10,7 +10,12 @@
pid_namespace::PidNamespace,
prelude::*,
sync::aref::ARef,
- types::{NotThreadSafe, Opaque},
+ types::{
+ AlwaysRefCounted,
+ NotThreadSafe,
+ Opaque,
+ RefCounted, //
+ },
};
use core::{
ops::Deref,
@@ -347,7 +352,7 @@ pub fn group_leader(&self) -> &Task {
}
// SAFETY: The type invariants guarantee that `Task` is always refcounted.
-unsafe impl crate::sync::aref::AlwaysRefCounted for Task {
+unsafe impl RefCounted for Task {
#[inline]
fn inc_ref(&self) {
// SAFETY: The existence of a shared reference means that the refcount is nonzero.
@@ -361,6 +366,10 @@ unsafe fn dec_ref(obj: ptr::NonNull<Self>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<Task>` from a
+// `&Task`.
+unsafe impl AlwaysRefCounted for Task {}
+
impl PartialEq for Task {
#[inline]
fn eq(&self, other: &Self) -> bool {
diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
index c41eab0ec983c..5ef763717e59a 100644
--- a/rust/kernel/types.rs
+++ b/rust/kernel/types.rs
@@ -15,9 +15,15 @@
pub mod for_lt;
pub use for_lt::ForLt;
-pub use crate::owned::{
- Ownable,
- Owned, //
+pub use crate::{
+ owned::{
+ Ownable,
+ Owned, //
+ },
+ sync::aref::{
+ AlwaysRefCounted,
+ RefCounted, //
+ }, //
};
/// Used to transfer ownership to and from foreign (non-Rust) languages.
diff --git a/rust/kernel/usb.rs b/rust/kernel/usb.rs
index 7aff0c82d0afc..59350c6b0df2a 100644
--- a/rust/kernel/usb.rs
+++ b/rust/kernel/usb.rs
@@ -18,7 +18,10 @@
to_result, //
},
prelude::*,
- sync::aref::AlwaysRefCounted,
+ sync::aref::{
+ AlwaysRefCounted,
+ RefCounted, //
+ },
types::Opaque,
ThisModule, //
};
@@ -392,7 +395,7 @@ fn as_ref(&self) -> &Device {
}
// SAFETY: Instances of `Interface` are always reference-counted.
-unsafe impl AlwaysRefCounted for Interface {
+unsafe impl RefCounted for Interface {
fn inc_ref(&self) {
// SAFETY: The invariants of `Interface` guarantee that `self.as_raw()`
// returns a valid `struct usb_interface` pointer, for which we will
@@ -406,6 +409,10 @@ unsafe fn dec_ref(obj: NonNull<Self>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<Interface>` from a
+// `&Interface`.
+unsafe impl AlwaysRefCounted for Interface {}
+
// SAFETY: A `Interface` is always reference-counted and can be released from any thread.
unsafe impl Send for Interface {}
@@ -443,7 +450,7 @@ fn as_raw(&self) -> *mut bindings::usb_device {
kernel::impl_device_context_into_aref!(Device);
// SAFETY: Instances of `Device` are always reference-counted.
-unsafe impl AlwaysRefCounted for Device {
+unsafe impl RefCounted for Device {
fn inc_ref(&self) {
// SAFETY: The invariants of `Device` guarantee that `self.as_raw()`
// returns a valid `struct usb_device` pointer, for which we will
@@ -457,6 +464,10 @@ unsafe fn dec_ref(obj: NonNull<Self>) {
}
}
+// SAFETY: We do not implement `Ownable`, thus it is okay to obtain an `ARef<Device>` from a
+// `&Device`.
+unsafe impl AlwaysRefCounted for Device {}
+
impl<Ctx: device::DeviceContext> AsRef<device::Device<Ctx>> for Device<Ctx> {
fn as_ref(&self) -> &device::Device<Ctx> {
// SAFETY: By the type invariant of `Self`, `self.as_raw()` is a pointer to a valid
--
2.51.2
^ permalink raw reply related
* [PATCH v18 1/8] rust: alloc: add `KBox::into_non_null`
From: Andreas Hindborg @ 2026-06-25 10:15 UTC (permalink / raw)
To: Danilo Krummrich, Lorenzo Stoakes, Vlastimil Babka,
Liam R. Howlett, Uladzislau Rezki, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Alice Ryhl,
Trevor Gross, Daniel Almeida, Tamir Duberstein, Alexandre Courbot,
Onur Özkan, Lyude Paul, Greg Kroah-Hartman,
Arve Hjønnevåg, Todd Kjos, Christian Brauner,
Carlos Llamas, Rafael J. Wysocki, Dave Ertman, Ira Weiny,
Leon Romanovsky, Paul Moore, Serge Hallyn, David Airlie,
Simona Vetter, Alexander Viro, Jan Kara, Igor Korotin,
Viresh Kumar, Nishanth Menon, Stephen Boyd, Bjorn Helgaas,
Krzysztof Wilczyński, Pavel Tikhomirov, Michal Wilczynski
Cc: Andreas Hindborg, Philipp Stanner, rust-for-linux, linux-kernel,
linux-mm, driver-core, linux-block, linux-security-module,
dri-devel, linux-fsdevel, linux-pm, linux-pci, linux-pwm
In-Reply-To: <20260625-unique-ref-v18-0-4e06b5896d47@kernel.org>
Add a method to consume a `Box<T, A>` and return a `NonNull<T>`. This
is a convenience wrapper around `Self::into_raw` for callers that need
a `NonNull` pointer rather than a raw pointer.
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Gary Guo <gary@garyguo.net>
---
rust/kernel/alloc/kbox.rs | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/rust/kernel/alloc/kbox.rs b/rust/kernel/alloc/kbox.rs
index 35d1e015848dd..d534e8adcf7b3 100644
--- a/rust/kernel/alloc/kbox.rs
+++ b/rust/kernel/alloc/kbox.rs
@@ -211,6 +211,15 @@ pub fn leak<'a>(b: Self) -> &'a mut T {
// which points to an initialized instance of `T`.
unsafe { &mut *Box::into_raw(b) }
}
+
+ /// Consumes the `Box<T,A>` and returns a `NonNull<T>`.
+ ///
+ /// Like [`Self::into_raw`], but returns a `NonNull`.
+ #[inline]
+ pub fn into_non_null(b: Self) -> NonNull<T> {
+ // SAFETY: `KBox::into_raw` returns a valid pointer.
+ unsafe { NonNull::new_unchecked(Self::into_raw(b)) }
+ }
}
impl<T, A> Box<MaybeUninit<T>, A>
--
2.51.2
^ permalink raw reply related
* [PATCH v18 3/8] rust: implement `ForeignOwnable` for `Owned`
From: Andreas Hindborg @ 2026-06-25 10:15 UTC (permalink / raw)
To: Danilo Krummrich, Lorenzo Stoakes, Vlastimil Babka,
Liam R. Howlett, Uladzislau Rezki, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Alice Ryhl,
Trevor Gross, Daniel Almeida, Tamir Duberstein, Alexandre Courbot,
Onur Özkan, Lyude Paul, Greg Kroah-Hartman,
Arve Hjønnevåg, Todd Kjos, Christian Brauner,
Carlos Llamas, Rafael J. Wysocki, Dave Ertman, Ira Weiny,
Leon Romanovsky, Paul Moore, Serge Hallyn, David Airlie,
Simona Vetter, Alexander Viro, Jan Kara, Igor Korotin,
Viresh Kumar, Nishanth Menon, Stephen Boyd, Bjorn Helgaas,
Krzysztof Wilczyński, Pavel Tikhomirov, Michal Wilczynski
Cc: Andreas Hindborg, Philipp Stanner, rust-for-linux, linux-kernel,
linux-mm, driver-core, linux-block, linux-security-module,
dri-devel, linux-fsdevel, linux-pm, linux-pci, linux-pwm
In-Reply-To: <20260625-unique-ref-v18-0-4e06b5896d47@kernel.org>
Implement `ForeignOwnable` for `Owned<T>`. This allows use of `Owned<T>` in
places such as the `XArray`.
Note that `T` does not need to implement `ForeignOwnable` for `Owned<T>` to
implement `ForeignOwnable`.
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
---
rust/kernel/owned.rs | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/rust/kernel/owned.rs b/rust/kernel/owned.rs
index 7fe9ec3e55126..9c92d4a83cc1b 100644
--- a/rust/kernel/owned.rs
+++ b/rust/kernel/owned.rs
@@ -15,6 +15,8 @@
ptr::NonNull, //
};
+use kernel::types::ForeignOwnable;
+
/// Types that specify their own way of performing allocation and destruction. Typically, this trait
/// is implemented on types from the C side.
///
@@ -186,3 +188,54 @@ fn drop(&mut self) {
unsafe { T::release(self.ptr) };
}
}
+
+// SAFETY: We derive the pointer to `T` from a valid `T`, so the returned
+// pointer satisfy alignment requirements of `T`.
+unsafe impl<T: Ownable> ForeignOwnable for Owned<T> {
+ const FOREIGN_ALIGN: usize = core::mem::align_of::<T>();
+
+ type Borrowed<'a>
+ = &'a T
+ where
+ Self: 'a;
+ type BorrowedMut<'a>
+ = Pin<&'a mut T>
+ where
+ Self: 'a;
+
+ #[inline]
+ fn into_foreign(self) -> *mut kernel::ffi::c_void {
+ let ptr = self.ptr.as_ptr().cast();
+ core::mem::forget(self);
+ ptr
+ }
+
+ #[inline]
+ unsafe fn from_foreign(ptr: *mut kernel::ffi::c_void) -> Self {
+ // INVARIANT: By the function safety contract, `ptr` was returned by `into_foreign`, which
+ // gave up exclusive ownership of a valid, pinned `T`; we retake that ownership here.
+ Self {
+ // SAFETY: By function safety contract, `ptr` came from
+ // `into_foreign` and cannot be null.
+ ptr: unsafe { NonNull::new_unchecked(ptr.cast()) },
+ }
+ }
+
+ #[inline]
+ unsafe fn borrow<'a>(ptr: *mut kernel::ffi::c_void) -> Self::Borrowed<'a> {
+ // SAFETY: By function safety requirements, `ptr` is valid for use as a
+ // reference for `'a`.
+ unsafe { &*ptr.cast() }
+ }
+
+ #[inline]
+ unsafe fn borrow_mut<'a>(ptr: *mut kernel::ffi::c_void) -> Self::BorrowedMut<'a> {
+ // SAFETY: By function safety requirements, `ptr` is valid for use as a
+ // unique reference for `'a`.
+ let inner = unsafe { &mut *ptr.cast() };
+
+ // SAFETY: We never move out of inner, and we do not hand out mutable
+ // references when `T: !Unpin`.
+ unsafe { Pin::new_unchecked(inner) }
+ }
+}
--
2.51.2
^ permalink raw reply related
* [PATCH v18 0/8] rust: add `Ownable` trait and `Owned` type
From: Andreas Hindborg @ 2026-06-25 10:15 UTC (permalink / raw)
To: Danilo Krummrich, Lorenzo Stoakes, Vlastimil Babka,
Liam R. Howlett, Uladzislau Rezki, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Alice Ryhl,
Trevor Gross, Daniel Almeida, Tamir Duberstein, Alexandre Courbot,
Onur Özkan, Lyude Paul, Greg Kroah-Hartman,
Arve Hjønnevåg, Todd Kjos, Christian Brauner,
Carlos Llamas, Rafael J. Wysocki, Dave Ertman, Ira Weiny,
Leon Romanovsky, Paul Moore, Serge Hallyn, David Airlie,
Simona Vetter, Alexander Viro, Jan Kara, Igor Korotin,
Viresh Kumar, Nishanth Menon, Stephen Boyd, Bjorn Helgaas,
Krzysztof Wilczyński, Pavel Tikhomirov, Michal Wilczynski
Cc: Andreas Hindborg, Philipp Stanner, rust-for-linux, linux-kernel,
linux-mm, driver-core, linux-block, linux-security-module,
dri-devel, linux-fsdevel, linux-pm, linux-pci, linux-pwm,
Asahi Lina, Oliver Mangold, Viresh Kumar, Boqun Feng, Asahi Lina,
Igor Korotin, Andreas Hindborg
Add a new trait `Ownable` and type `Owned` for types that specify their
own way of performing allocation and destruction. This is useful for
types from the C side.
Implement `ForeignOwnable` for `Owned`.
Convert `Page` to be `Ownable` and add a `from_raw` method.
Add the trait `OwnableRefCounted` that allows conversion between
`ARef` and `Owned`. This is analogous to conversion between `Arc` and
`UniqueArc`.
Patches 1-4 implement `Ownable` and applies it to `Page`. These patches
can be merged on their own.
Patches 5-7 add `Ownable` -> `ARef` interop and can be merged later if
consensus on their shape cannot be reached.
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
---
Changes in v18:
- Rebase on `rust-next` (2026-06-24).
- Drop the `'static` bound on `ForeignOwnable for Owned` (Gary).
- Make `Ownable::release` take a raw pointer instead of `&mut self` (Alice, Sashiko).
- Drop `types::ARef` re-export (Alice).
- Drop unneeded `#[repr(transparent)]` on `Owned` (Gary).
- Fix `FOREIGN_ALIGN` for `Owned` to report the pointee alignment (Sashiko).
- Remove `BorrowedPage`; use `&Page` directly (Alice).
- Update Rust Binder for the `Owned<Page>` conversion (Alice).
- Update `pwm.rs` for the `RefCounted`/`AlwaysRefCounted` split (Sashiko).
- Fix documentation nits: missing `// INVARIANT:` comments, stale `Page` docs, and a stray `mut` (Sashiko).
- Expand the `use` statements touched by the rename patch to the multi-line style (Onur).
- Link to v17: https://msgid.link/20260604-unique-ref-v17-0-7b4c3d2930b9@kernel.org
Changes in v17:
- Rebase on v7.1-rc2.
- Reorder patches so that `Ownable` can merge without `OwnableRefCounted` (Alice).
- Add `#[inline]` directives to short functions added by the series (Gary).
- Link to v16: https://msgid.link/20260224-unique-ref-v16-0-c21afcb118d3@kernel.org
Changes in v16:
- Simplify pointer to reference cast in `Page::from_raw`.
- Use `NonNull<Page>` rather than `Owned<Page>` for `BorrowedPage` internals.
- Use "convertible to reference" wording when converting pointers to references.
- Fix formatting for `Page::from_raw` docs.
- Leave imports alone when adding safety comment to aref example.
- Use `KBox::into_nonnull` for examples.
- Add patch for `KBox::into_nonnull`.
- Change invariants and safety comments of `Ownable` and make the trait safe.
- Make `Ownable::release` take a mutable reference.
- Fix error handling in example for `Ownable`
- Link to v15: https://msgid.link/20260220-unique-ref-v15-0-893ed86b06cc@kernel.org
Changes in v15:
- Update series with original SoB's.
- Rename `AlwaysRefCounted` in `kernel::usb`.
- Rename `Owned::get_pin_mut` to `Owned::as_pin_mut`.
- Link to v14: https://msgid.link/20260204-unique-ref-v14-0-17cb29ebacbb@kernel.org
Changes in v14:
- Rebase on v6.19-rc7.
- Rewrite cover letter.
- Update documentation and safety comments based on v13 feedback.
- Update commit messages.
- Reorder implementation blocks in owned.rs.
- Update example in owned.rs to use try operator rather than `expect`.
- Reformat use statements.
- Add patch: rust: page: convert to `Ownable`.
- Add patch: rust: implement `ForeignOwnable` for `Owned`.
- Add patch: rust: page: add `from_raw()`.
- Link to v13: https://lore.kernel.org/r/20251117-unique-ref-v13-0-b5b243df1250@pm.me
Changes in v13:
- Rebase onto v6.18-rc1 (Andreas's work).
- Documentation and style fixes contributed by Andreas
- Link to v12: https://lore.kernel.org/r/20251001-unique-ref-v12-0-fa5c31f0c0c4@pm.me
Changes in v12:
-
- Rebase onto v6.17-rc1 (Andreas's work).
- moved kernel/types/ownable.rs to kernel/owned.rs
- Drop OwnableMut, make DerefMut depend on Unpin instead. I understood
ML discussion as that being okay, but probably needs further scrunity.
- Lots of more documentation changes suggested by reviewers.
- Usage example for Ownable/Owned.
- Link to v11: https://lore.kernel.org/r/20250618-unique-ref-v11-0-49eadcdc0aa6@pm.me
Changes in v11:
- Rework of documentation. I tried to honor all requests for changes "in
spirit" plus some clearifications and corrections of my own.
- Dropping `SimpleOwnedRefCounted` by request from Alice, as it creates a
potentially problematic blanket implementation (which a derive macro that
could be created later would not have).
- Dropping Miguel's "kbuild: provide `RUSTC_HAS_DO_NOT_RECOMMEND` symbol"
patch, as it is not needed anymore after dropping `SimpleOwnedRefCounted`.
(I can add it again, if it is considered useful anyway).
- Link to v10: https://lore.kernel.org/r/20250502-unique-ref-v10-0-25de64c0307f@pm.me
Changes in v10:
- Moved kernel/ownable.rs to kernel/types/ownable.rs
- Fixes in documentation / comments as suggested by Andreas Hindborg
- Added Reviewed-by comment for Andreas Hindborg
- Fix rustfmt of pid_namespace.rs
- Link to v9: https://lore.kernel.org/r/20250325-unique-ref-v9-0-e91618c1de26@pm.me
Changes in v9:
- Rebase onto v6.14-rc7
- Move Ownable/OwnedRefCounted/Ownable, etc., into separate module
- Documentation fixes to Ownable/OwnableMut/OwnableRefCounted
- Add missing SAFETY documentation to ARef example
- Link to v8: https://lore.kernel.org/r/20250313-unique-ref-v8-0-3082ffc67a31@pm.me
Changes in v8:
- Fix Co-developed-by and Suggested-by tags as suggested by Miguel and Boqun
- Some small documentation fixes in Owned/Ownable patch
- removing redundant trait constraint on DerefMut for Owned as suggested by Boqun Feng
- make SimpleOwnedRefCounted no longer implement RefCounted as suggested by Boqun Feng
- documentation for RefCounted as suggested by Boqun Feng
- Link to v7: https://lore.kernel.org/r/20250310-unique-ref-v7-0-4caddb78aa05@pm.me
Changes in v7:
- Squash patch to make Owned::from_raw/into_raw public into parent
- Added Signed-off-by to other people's commits
- Link to v6: https://lore.kernel.org/r/20250310-unique-ref-v6-0-1ff53558617e@pm.me
Changes in v6:
- Changed comments/formatting as suggested by Miguel Ojeda
- Included and used new config flag RUSTC_HAS_DO_NOT_RECOMMEND,
thus no changes to types.rs will be needed when the attribute
becomes available.
- Fixed commit message for Owned patch.
- Link to v5: https://lore.kernel.org/r/20250307-unique-ref-v5-0-bffeb633277e@pm.me
Changes in v5:
- Rebase the whole thing on top of the Ownable/Owned traits by Asahi Lina.
- Rename AlwaysRefCounted to RefCounted and make AlwaysRefCounted a
marker trait instead to allow to obtain an ARef<T> from an &T,
which (as Alice pointed out) is unsound when combined with UniqueRef/Owned.
- Change the Trait design and naming to implement this feature,
UniqueRef/UniqueRefCounted is dropped in favor of Ownable/Owned and
OwnableRefCounted is used to provide the functions to convert
between Owned and ARef.
- Link to v4: https://lore.kernel.org/r/20250305-unique-ref-v4-1-a8fdef7b1c2c@pm.me
Changes in v4:
- Just a minor change in naming by request from Andreas Hindborg,
try_shared_to_unique() -> try_from_shared(),
unique_to_shared() -> into_shared(),
which is more in line with standard Rust naming conventions.
- Link to v3: https://lore.kernel.org/r/Z8Wuud2UQX6Yukyr@mango
To: Danilo Krummrich <dakr@kernel.org>
To: Lorenzo Stoakes <ljs@kernel.org>
To: Vlastimil Babka <vbabka@kernel.org>
To: "Liam R. Howlett" <liam@infradead.org>
To: Uladzislau Rezki <urezki@gmail.com>
To: Miguel Ojeda <ojeda@kernel.org>
To: Boqun Feng <boqun@kernel.org>
To: Gary Guo <gary@garyguo.net>
To: Björn Roy Baron <bjorn3_gh@protonmail.com>
To: Benno Lossin <lossin@kernel.org>
To: Andreas Hindborg <a.hindborg@kernel.org>
To: Alice Ryhl <aliceryhl@google.com>
To: Trevor Gross <tmgross@umich.edu>
To: Daniel Almeida <daniel.almeida@collabora.com>
To: Tamir Duberstein <tamird@kernel.org>
To: Alexandre Courbot <acourbot@nvidia.com>
To: Onur Özkan <work@onurozkan.dev>
To: Lyude Paul <lyude@redhat.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: Arve Hjønnevåg <arve@android.com>
To: Todd Kjos <tkjos@android.com>
To: Christian Brauner <brauner@kernel.org>
To: Carlos Llamas <cmllamas@google.com>
To: "Rafael J. Wysocki" <rafael@kernel.org>
To: Dave Ertman <david.m.ertman@intel.com>
To: Ira Weiny <ira.weiny@intel.com>
To: Leon Romanovsky <leon@kernel.org>
To: Paul Moore <paul@paul-moore.com>
To: Serge Hallyn <sergeh@kernel.org>
To: David Airlie <airlied@gmail.com>
To: Simona Vetter <simona@ffwll.ch>
To: Alexander Viro <viro@zeniv.linux.org.uk>
To: Jan Kara <jack@suse.cz>
To: Igor Korotin <igor.korotin@linux.dev>
To: Viresh Kumar <vireshk@kernel.org>
To: Nishanth Menon <nm@ti.com>
To: Stephen Boyd <sboyd@kernel.org>
To: Bjorn Helgaas <bhelgaas@google.com>
To: Krzysztof Wilczyński <kwilczynski@kernel.org>
To: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
To: Michal Wilczynski <m.wilczynski@samsung.com>
Cc: Philipp Stanner <phasta@kernel.org>
Cc: rust-for-linux@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: linux-mm@kvack.org
Cc: driver-core@lists.linux.dev
Cc: linux-block@vger.kernel.org
Cc: linux-security-module@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
Cc: linux-fsdevel@vger.kernel.org
Cc: linux-pm@vger.kernel.org
Cc: linux-pci@vger.kernel.org
Cc: linux-pwm@vger.kernel.org
---
Andreas Hindborg (3):
rust: alloc: add `KBox::into_non_null`
rust: implement `ForeignOwnable` for `Owned`
rust: page: add `from_raw()`
Asahi Lina (2):
rust: types: Add Ownable/Owned types
rust: page: convert to `Ownable`
Oliver Mangold (3):
rust: rename `AlwaysRefCounted` to `RefCounted`.
rust: Add missing SAFETY documentation for `ARef` example
rust: Add `OwnableRefCounted`
drivers/android/binder/page_range.rs | 10 +-
rust/kernel/alloc/allocator.rs | 19 +-
rust/kernel/alloc/allocator/iter.rs | 6 +-
rust/kernel/alloc/kbox.rs | 9 +
rust/kernel/auxiliary.rs | 10 +-
rust/kernel/block/mq/request.rs | 19 +-
rust/kernel/cred.rs | 16 +-
rust/kernel/device.rs | 12 +-
rust/kernel/device/property.rs | 11 +-
rust/kernel/drm/device.rs | 9 +-
rust/kernel/drm/gem/mod.rs | 16 +-
rust/kernel/fs/file.rs | 23 ++-
rust/kernel/i2c.rs | 13 +-
rust/kernel/lib.rs | 1 +
rust/kernel/mm.rs | 22 ++-
rust/kernel/mm/mmput_async.rs | 12 +-
rust/kernel/opp.rs | 16 +-
rust/kernel/owned.rs | 371 +++++++++++++++++++++++++++++++++++
rust/kernel/page.rs | 136 +++++--------
rust/kernel/pci.rs | 10 +-
rust/kernel/pid_namespace.rs | 15 +-
rust/kernel/platform.rs | 10 +-
rust/kernel/pwm.rs | 12 +-
rust/kernel/sync/aref.rs | 82 +++++---
rust/kernel/task.rs | 13 +-
rust/kernel/types.rs | 12 ++
rust/kernel/usb.rs | 17 +-
27 files changed, 721 insertions(+), 181 deletions(-)
---
base-commit: 43a393185e33e573a374c1d4f7ddf6481484ef8d
change-id: 20250305-unique-ref-29fcd675f9e9
Best regards,
--
Andreas Hindborg <a.hindborg@kernel.org>
^ permalink raw reply
* [PATCH v18 6/8] rust: Add missing SAFETY documentation for `ARef` example
From: Andreas Hindborg @ 2026-06-25 10:15 UTC (permalink / raw)
To: Danilo Krummrich, Lorenzo Stoakes, Vlastimil Babka,
Liam R. Howlett, Uladzislau Rezki, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Alice Ryhl,
Trevor Gross, Daniel Almeida, Tamir Duberstein, Alexandre Courbot,
Onur Özkan, Lyude Paul, Greg Kroah-Hartman,
Arve Hjønnevåg, Todd Kjos, Christian Brauner,
Carlos Llamas, Rafael J. Wysocki, Dave Ertman, Ira Weiny,
Leon Romanovsky, Paul Moore, Serge Hallyn, David Airlie,
Simona Vetter, Alexander Viro, Jan Kara, Igor Korotin,
Viresh Kumar, Nishanth Menon, Stephen Boyd, Bjorn Helgaas,
Krzysztof Wilczyński, Pavel Tikhomirov, Michal Wilczynski
Cc: Andreas Hindborg, Philipp Stanner, rust-for-linux, linux-kernel,
linux-mm, driver-core, linux-block, linux-security-module,
dri-devel, linux-fsdevel, linux-pm, linux-pci, linux-pwm,
Oliver Mangold
In-Reply-To: <20260625-unique-ref-v18-0-4e06b5896d47@kernel.org>
From: Oliver Mangold <oliver.mangold@pm.me>
SAFETY comment in rustdoc example was just 'TODO'. Fixed.
Signed-off-by: Oliver Mangold <oliver.mangold@pm.me>
Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com>
Co-developed-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Andreas Hindborg <a.hindborg@kernel.org>
---
rust/kernel/sync/aref.rs | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/rust/kernel/sync/aref.rs b/rust/kernel/sync/aref.rs
index fb7466a362741..d0865aeb9371b 100644
--- a/rust/kernel/sync/aref.rs
+++ b/rust/kernel/sync/aref.rs
@@ -142,7 +142,9 @@ pub unsafe fn from_raw(ptr: NonNull<T>) -> Self {
///
/// struct Empty {}
///
- /// # // SAFETY: TODO.
+ /// // SAFETY: The `RefCounted` implementation for `Empty` does not count references and never
+ /// // frees the underlying object. Thus we can act as owning an increment on the refcount for
+ /// // the object that we pass to the newly created `ARef`.
/// unsafe impl RefCounted for Empty {
/// fn inc_ref(&self) {}
/// unsafe fn dec_ref(_obj: NonNull<Self>) {}
@@ -150,7 +152,7 @@ pub unsafe fn from_raw(ptr: NonNull<T>) -> Self {
///
/// let mut data = Empty {};
/// let ptr = NonNull::<Empty>::new(&mut data).unwrap();
- /// # // SAFETY: TODO.
+ /// // SAFETY: We keep `data` around longer than the `ARef`.
/// let data_ref: ARef<Empty> = unsafe { ARef::from_raw(ptr) };
/// let raw_ptr: NonNull<Empty> = ARef::into_raw(data_ref);
///
--
2.51.2
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox