[PATCH 2/3] proc: query LSMs for introspective mem access (if PROC_MEM_FORCE_ALWAYS)

Lorenzo Stoakes (ARM) ljs at kernel.org
Tue Aug 25 14:02:57 UTC 2026


On Mon, Aug 24, 2026 at 07:28:24PM +0200, Jann Horn wrote:
> On Fri, Aug 21, 2026 at 9:00 PM Lorenzo Stoakes (ARM) <ljs at kernel.org> wrote:
> > On Tue, Aug 18, 2026 at 09:51:06PM +0200, Jann Horn wrote:
> > > If the system is running with PROC_MEM_FORCE_ALWAYS, LSMs currently have no
> > > good opportunity to block a process from overwriting read-only code in its
> > > own address space through FOLL_FORCE writes via /proc/self/mem.
> > > The security_ptrace_access_check() LSM hook is bypassed when a process
> > > opens /proc/self/mem because this is considered "introspection".
> > >
> > > This causes a hole in SELinux EXECMEM enforcement, which tries to ensure
> > > that a process cannot create executable anonymous pages.
> > >
> > > PROC_MEM_FORCE_PTRACE prevents that and ensures that such FOLL_FORCE
> > > accesses are only possible when the LSM allows ptrace() attachment; but it
> > > is unclear how quickly PROC_MEM_FORCE_PTRACE can be deployed in
> > > environments running lots of third-party code, such as Android.
> > >
> > > So, introduce a new LSM hook that can forbid FOLL_FORCE specifically for
> > > such "introspective" accesses.
> > >
> > > Signed-off-by: Jann Horn <jannh at google.com>
>
> > > @@ -886,6 +890,8 @@ static bool proc_mem_foll_force(struct file *file, struct mm_struct *mm)
> > >               }
> > >               return ptrace_active;
> > >       default:
> > > +             if (priv->introspection)
> > > +                     return security_introspect_mem_foll_force(file->f_cred) == 0;
> >
> > As per 3/3 I wonder if you need an additional parameter to cover the fd -> some
> > other process case?
> >
> > Like:
> >         if (priv->owned_by_owner) {
> >                 const bool is_remote = current->mm != priv->mm;
> >
> >                 return !security_fd_from_owner_mem_foll_force(file->f_cred,
> >                                 is_remote);
> >         }
> >
> > (I'm not sure how LSM hooks are supposed to look :)
>
> We could do that if we wanted to treat cases differently based on the
> identity of the writer, but I think in general that's not a good idea.
>
> In general, if you send an FD to some daemon, and the daemon writes
> into the FD, this should not cause access control decisions based on
> the identity of the daemon, because it can cause "confused deputy"
> bugs - the daemon might think it is just writing log output into a
> normal file, or something like that.

Ack yup, variations of a theme of this, I think I was overly confused by
the fd-passing stuff vs. the key reason for the series.

In general the thing LGTM other than the naming so a respin should be good!

>
> > > diff --git a/security/security.c b/security/security.c
> > > index 71aea8fdf014..d0f790a534eb 100644
> > > --- a/security/security.c
> > > +++ b/security/security.c
> > > @@ -595,6 +595,21 @@ int security_ptrace_traceme(struct task_struct *parent)
> > >       return call_int_hook(ptrace_traceme, parent);
> > >  }
> > >
> > > +/**
> > > + * security_introspect_mem_foll_force() - Check if introspective FOLL_FORCE is allowed
> > > + * @subject: credentials of the process accessing its own memory
> > > + *
> > > + * Check if FOLL_FORCE is allowed for a process accessing its own memory, which
> > > + * bypasses the security_ptrace_access_check() hook.
> >
> > This should be updated to also explicitly mention the fd case. As surely in that
> > case this is not true? Unless I'm missing something.
>
> Yeah, I'll clarify this comment.

--
Cheers, Lorenzo



More information about the Linux-security-module-archive mailing list