[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <202407051425.32AF9D2@keescook>
Date: Fri, 5 Jul 2024 14:44:03 -0700
From: Kees Cook <kees@...nel.org>
To: Mickaël Salaün <mic@...ikod.net>
Cc: Al Viro <viro@...iv.linux.org.uk>,
Christian Brauner <brauner@...nel.org>,
Linus Torvalds <torvalds@...ux-foundation.org>,
Paul Moore <paul@...l-moore.com>, Theodore Ts'o <tytso@....edu>,
Alejandro Colomar <alx@...nel.org>,
Aleksa Sarai <cyphar@...har.com>,
Andrew Morton <akpm@...ux-foundation.org>,
Andy Lutomirski <luto@...nel.org>, Arnd Bergmann <arnd@...db.de>,
Casey Schaufler <casey@...aufler-ca.com>,
Christian Heimes <christian@...hon.org>,
Dmitry Vyukov <dvyukov@...gle.com>,
Eric Biggers <ebiggers@...nel.org>,
Eric Chiang <ericchiang@...gle.com>,
Fan Wu <wufan@...ux.microsoft.com>,
Florian Weimer <fweimer@...hat.com>,
Geert Uytterhoeven <geert@...ux-m68k.org>,
James Morris <jamorris@...ux.microsoft.com>,
Jan Kara <jack@...e.cz>, Jann Horn <jannh@...gle.com>,
Jeff Xu <jeffxu@...gle.com>, Jonathan Corbet <corbet@....net>,
Jordan R Abrahams <ajordanr@...gle.com>,
Lakshmi Ramasubramanian <nramas@...ux.microsoft.com>,
Luca Boccassi <bluca@...ian.org>,
Luis Chamberlain <mcgrof@...nel.org>,
"Madhavan T . Venkataraman" <madvenka@...ux.microsoft.com>,
Matt Bobrowski <mattbobrowski@...gle.com>,
Matthew Garrett <mjg59@...f.ucam.org>,
Matthew Wilcox <willy@...radead.org>,
Miklos Szeredi <mszeredi@...hat.com>,
Mimi Zohar <zohar@...ux.ibm.com>,
Nicolas Bouchinet <nicolas.bouchinet@....gouv.fr>,
Scott Shell <scottsh@...rosoft.com>, Shuah Khan <shuah@...nel.org>,
Stephen Rothwell <sfr@...b.auug.org.au>,
Steve Dower <steve.dower@...hon.org>,
Steve Grubb <sgrubb@...hat.com>,
Thibaut Sautereau <thibaut.sautereau@....gouv.fr>,
Vincent Strubel <vincent.strubel@....gouv.fr>,
Xiaoming Ni <nixiaoming@...wei.com>,
Yin Fengwei <fengwei.yin@...el.com>,
kernel-hardening@...ts.openwall.com, linux-api@...r.kernel.org,
linux-fsdevel@...r.kernel.org, linux-integrity@...r.kernel.org,
linux-kernel@...r.kernel.org, linux-security-module@...r.kernel.org
Subject: Re: [RFC PATCH v19 2/5] security: Add new SHOULD_EXEC_CHECK and
SHOULD_EXEC_RESTRICT securebits
On Fri, Jul 05, 2024 at 07:54:16PM +0200, Mickaël Salaün wrote:
> On Thu, Jul 04, 2024 at 05:18:04PM -0700, Kees Cook wrote:
> > On Thu, Jul 04, 2024 at 09:01:34PM +0200, Mickaël Salaün wrote:
> > > Such a secure environment can be achieved with an appropriate access
> > > control policy (e.g. mount's noexec option, file access rights, LSM
> > > configuration) and an enlighten ld.so checking that libraries are
> > > allowed for execution e.g., to protect against illegitimate use of
> > > LD_PRELOAD.
> > >
> > > Scripts may need some changes to deal with untrusted data (e.g. stdin,
> > > environment variables), but that is outside the scope of the kernel.
> >
> > If the threat model includes an attacker sitting at a shell prompt, we
> > need to be very careful about how process perform enforcement. E.g. even
> > on a locked down system, if an attacker has access to LD_PRELOAD or a
>
> LD_PRELOAD should be OK once ld.so will be patched to check the
> libraries. We can still imagine a debug library used to bypass security
> checks, but in this case the issue would be that this library is
> executable in the first place.
Ah yes, that's fair: the shell would discover the malicious library
while using AT_CHECK during resolution of the LD_PRELOAD.
> > seccomp wrapper (which you both mention here), it would be possible to
> > run commands where the resulting process is tricked into thinking it
> > doesn't have the bits set.
>
> As explained in the UAPI comments, all parent processes need to be
> trusted. This meeans that their code is trusted, their seccomp filters
> are trusted, and that they are patched, if needed, to check file
> executability.
But we have launchers that apply arbitrary seccomp policy, e.g. minijail
on Chrome OS, or even systemd on regular distros. In theory, this should
be handled via other ACLs.
> > But this would be exactly true for calling execveat(): LD_PRELOAD or
> > seccomp policy could have it just return 0.
>
> If an attacker is allowed/able to load an arbitrary seccomp filter on a
> process, we cannot trust this process.
>
> >
> > While I like AT_CHECK, I do wonder if it's better to do the checks via
> > open(), as was originally designed with O_MAYEXEC. Because then
> > enforcement is gated by the kernel -- the process does not get a file
> > descriptor _at all_, no matter what LD_PRELOAD or seccomp tricks it into
> > doing.
>
> Being able to check a path name or a file descriptor (with the same
> syscall) is more flexible and cover more use cases.
If flexibility costs us reliability, I think that flexibility is not
a benefit.
> The execveat(2)
> interface, including current and future flags, is dedicated to file
> execution. I then think that using execveat(2) for this kind of check
> makes more sense, and will easily evolve with this syscall.
Yeah, I do recognize that is feels much more natural, but I remain
unhappy about how difficult it will become to audit a system for safety
when the check is strictly per-process opt-in, and not enforced by the
kernel for a given process tree. But, I think this may have always been
a fiction in my mind. :)
> > And this thinking also applies to faccessat() too: if a process can be
> > tricked into thinking the access check passed, it'll happily interpret
> > whatever. :( But not being able to open the fd _at all_ when O_MAYEXEC
> > is being checked seems substantially safer to me...
>
> If attackers can filter execveat(2), they can also filter open(2) and
> any other syscalls. In all cases, that would mean an issue in the
> security policy.
Hm, as in, make a separate call to open(2) without O_MAYEXEC, and pass
that fd back to the filtered open(2) that did have O_MAYEXEC. Yes, true.
I guess it does become morally equivalent.
Okay. Well, let me ask about usability. Right now, a process will need
to do:
- should I use AT_CHECK? (check secbit)
- if yes: perform execveat(AT_CHECK)
Why not leave the secbit test up to the kernel, and then the program can
just unconditionally call execveat(AT_CHECK)?
Though perhaps the issue here is that an execveat() EINVAL doesn't
tell the program if AT_CHECK is unimplemented or if something else
went wrong, and the secbit prctl() will give the correct signal about
AT_CHECK availability?
--
Kees Cook
Powered by blists - more mailing lists