Re: [GIT PULL] Add trusted_for(2) (was O_MAYEXEC)

From: Kees Cook
Date: Mon Apr 04 2022 - 19:02:44 EST


On Mon, Apr 04, 2022 at 02:28:19PM -0700, Linus Torvalds wrote:
> Now, what I *think* you mean is
>
> (1) user-space executable loaders want to be able to test the *same*
> policy as the kernel does for execve()

Right. The script interpreter wants to ask "if this file were actually
an ELF going through execve(), would the kernel allow it?"

> (2) access(path, EXECVE_OK) will do the same permission checks as
> "execve()" would do for that path

Maybe. I defer to Mickaël here, but my instinct is to avoid creating an
API that can be accidentally misused. I'd like this to be fd-only based,
since that removes path name races. (e.g. trusted_for() required an fd.)

> (3) if you already have the fd open, use "faccess(fd, NULL,
> F_OK_TO_EXECUTE, AT_EMPTY_PATH)"

Yes, specifically faccessat2(). (And continuing the race thought above,
yes, there could still be races if the content of the file could be
changed, but that case is less problematic under real-world conditions.)

> (4) maybe we want to add a flag for the "euid vs real uid", and that
> would be in the "flags" field, since that changes the actual *lookup*
> semantics
>
> Note that that (4) is something that some normal user space has wanted
> in the past too (GNU libcs has a "eaccess()" thing for "effective uid
> access").

I think this already exists as AT_EACCESS? It was added with
faccessat2() itself, if I'm reading the history correctly.

And I just need to say that the thought of setuid script interpreters
still makes me sad. :)

> - I really want the exact semantics very clearly defined. I think
> it's ok to say "exact same security check as for 'execve()'", but even
> then we need to have that discussion about
>
> (a) "what about suid bits that user space cannot react to"

What do you mean here? Do you mean setid bits on the file itself?

> (b) that whole "effective vs real" discussion

I think this is handled with AT_EACCESS?

--
Kees Cook