[PATCH v3 1/2] lsm: add backing_file LSM hooks
Paul Moore
paul at paul-moore.com
Tue Mar 31 02:13:49 UTC 2026
On Mon, Mar 30, 2026 at 4:35 AM Amir Goldstein <amir73il at gmail.com> wrote:
> On Fri, Mar 27, 2026 at 11:05 PM Paul Moore <paul at paul-moore.com> wrote:
> >
> > Stacked filesystems such as overlayfs do not currently provide the
> > necessary mechanisms for LSMs to properly enforce access controls on the
> > mmap() and mprotect() operations. In order to resolve this gap, a LSM
> > security blob is being added to the backing_file struct and the following
> > new LSM hooks are being created ...
...
> > diff --git a/fs/file_table.c b/fs/file_table.c
> > index aaa5faaace1e..0bdc26cae138 100644
> > --- a/fs/file_table.c
> > +++ b/fs/file_table.c
> > @@ -50,6 +50,7 @@ struct backing_file {
> > struct path user_path;
> > freeptr_t bf_freeptr;
> > };
> > + void *security;
>
> This needs ifdef SECURITY
Yep. That will require some other changes, but I should be able to
keep those fairly limited.
> and the name should be user_security
I'd strongly prefer to keep it as "security" both because "void
*security" is a very common pattern in the kernel when adding LSM
blobs to structs, and we don't know what each and every LSM may need
to store in the backing_file LSM blob.
> > +void *backing_file_security(const struct file *f)
> > +{
> > + return backing_file(f)->security;
> > +}
>
> I prefer the name backing_file_user_security()
>
> Terminology here is very confusing but when saying
> "backing file" it is more natural that one is referring to the
> backing xfs file with overlayfs has opened.
>
> The "backing file" already has an LSM blob f->f_security
> which is fair the call it the "backing file's LSM blob" ...
>From a LSM dev's perspective, I would call file->f_security blob a
file's LSM blob regardless of if the file is a user or backing file;
the backing_file->security blob would be a backing file LSM blob. If
you look at what the SELinux code does, specifically in the
__file_has_perm() and __file_map_prot_check() functions (newly added
in this patchset), you'll see this supported by the code: the
file->f_security field is basically handled the same regardless of if
it is a user or backing file whereas the backing_file->security field
is handled very differently because it is a backing file.
While I think it makes sense to match the accessor function's name to
the struct field, ultimately I care more about the struct field's
name. If you really feel strongly about changing
backing_file_security() to backing_file_user_security() I can live
with that so long as we keep backing_file->security intact.
> > @@ -73,8 +79,11 @@ static inline void file_free(struct file *f)
> > percpu_counter_dec(&nr_files);
> > put_cred(f->f_cred);
> > if (unlikely(f->f_mode & FMODE_BACKING)) {
> > - path_put(backing_file_user_path(f));
> > - kmem_cache_free(bfilp_cachep, backing_file(f));
> > + struct backing_file *ff = backing_file(f);
> > +
> > + security_backing_file_free(&ff->security);
> > + path_put(&ff->user_path);
> > + kmem_cache_free(bfilp_cachep, ff);
>
> Not directly related to your patch, but as this is growing, IMO
> this would look cleaner with backing_file_free() inline helper
> (see attached path).
Sure, I'll include your patch in the patchset. I'll also fix the
comment style in the patch to match C style in the rest of the file
(I'll note the change in the metadata).
> > } else {
> > kmem_cache_free(filp_cachep, f);
> > }
> > @@ -290,7 +299,8 @@ struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred)
> > * This is only for kernel internal use, and the allocate file must not be
> > * installed into file tables or such.
> > */
> > -struct file *alloc_empty_backing_file(int flags, const struct cred *cred)
> > +struct file *alloc_empty_backing_file(int flags, const struct cred *cred,
> > + const struct file *user_file)
> > {
> > struct backing_file *ff;
> > int error;
> > @@ -306,6 +316,11 @@ struct file *alloc_empty_backing_file(int flags, const struct cred *cred)
> > }
> >
> > ff->file.f_mode |= FMODE_BACKING | FMODE_NOACCOUNT;
> > + error = security_backing_file_alloc(&ff->security, user_file);
> > + if (unlikely(error)) {
> > + fput(&ff->file);
> > + return ERR_PTR(error);
> > + }
> > return &ff->file;
> > }
>
> There is an API issue here.
> in order to call fput() we must ensure that user_security was initialized to
> NULL (or allocated).
>
> I don't think that we want security_backing_file_alloc() to provide this
> semantic and the current patch does not implement it.
>
> Furthermore, user_path is also not initialized in the error case.
>
> Attached UNTESTED fixup patch to suggest a cleanup with
> init_backing_file() helper.
>
> It also changes the variable and helper name to user_security
> and plays some trick to avoid many ifdef SECURITY.
> Feel free to take whichever bits you like with/without attribution.
I think I've got a cleaner approach than what you've proposed, let me
code it up, test it all, and I'll post a new revision of the patchset
soon.
--
paul-moore.com
More information about the Linux-security-module-archive
mailing list