linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] fs/exec: require argv[0] presence in do_execveat_common()
@ 2022-01-26  4:39 Ariadne Conill
  2022-01-26  6:42 ` Kees Cook
  2022-01-26 13:27 ` Rich Felker
  0 siblings, 2 replies; 14+ messages in thread
From: Ariadne Conill @ 2022-01-26  4:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: linux-fsdevel, Eric Biederman, Kees Cook, Alexander Viro, Ariadne Conill

The first argument to argv when used with execv family of calls is
required to be the name of the program being executed, per POSIX.

By validating this in do_execveat_common(), we can prevent execution
of shellcode which invokes execv(2) family syscalls with argc < 1,
a scenario which is disallowed by POSIX, thus providing a mitigation
against CVE-2021-4034 and similar bugs in the future.

The use of -EFAULT for this case is similar to other systems, such
as FreeBSD and OpenBSD.

Interestingly, Michael Kerrisk opened an issue about this in 2008,
but there was no consensus to support fixing this issue then.
Hopefully now that CVE-2021-4034 shows practical exploitative use
of this bug in a shellcode, we can reconsider.

Signed-off-by: Ariadne Conill <ariadne@dereferenced.org>
---
 fs/exec.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/fs/exec.c b/fs/exec.c
index 79f2c9483302..de0b832473ed 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1897,8 +1897,10 @@ static int do_execveat_common(int fd, struct filename *filename,
 	}
 
 	retval = count(argv, MAX_ARG_STRINGS);
-	if (retval < 0)
+	if (retval < 1) {
+		retval = -EFAULT;
 		goto out_free;
+	}
 	bprm->argc = retval;
 
 	retval = count(envp, MAX_ARG_STRINGS);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread
* Re: [PATCH] fs/exec: require argv[0] presence in do_execveat_common()
@ 2022-01-26 15:02 Alexey Dobriyan
  2022-01-27  0:00 ` Kees Cook
  0 siblings, 1 reply; 14+ messages in thread
From: Alexey Dobriyan @ 2022-01-26 15:02 UTC (permalink / raw)
  To: ariadne, keescook; +Cc: linux-kernel, linux-fsdevel, ebiederm, viro

>	execve("...", NULL, NULL);

I personally wrote a program which relies on execve(NULL) to succeed.
It wasn't an exploit, it was test program against IMA-like kernel
"only whitelisted executables can run" feature.

Test copies and "corrupts" itself by appending \0 to the end, then tries
to reexec itself with execve("/proc/self/exe", NULL, NULL);
main() if run with argc==0 exits with specific error code.

Appending \0 breaks checksum so working kernel protection scheme must
not allow it, therefore if execve(NULL) succeeded, than the parent
process doing test hard fails.

Also appending \0 doesn't break ELF structure. In other words,
if executable A is working (and it is working because it is running)
then A||\0 is valid executable as well and will run too.

This is independent from filesystem layout, libc, kernel, dynamic
libraries, compile options and what not.

Now QNX doesn't allow execve(NULL) and I don't remember if I changed it
to the next simplest variant and I don't work anymore at that company,
so I can't check :^)

	execve("/proc/self/exe", (char*[]){"Alexey", NULL}, NULL);

P.S.:

	> tptacek 5 minutes ago | root | parent | next [–]
	> There is not.

	Yes, there is!

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2022-02-01 20:54 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-26  4:39 [PATCH] fs/exec: require argv[0] presence in do_execveat_common() Ariadne Conill
2022-01-26  6:42 ` Kees Cook
2022-01-26  7:28   ` Kees Cook
2022-01-26 11:18     ` Ariadne Conill
2022-01-26 12:33       ` Heikki Kallasjoki
2022-01-26 23:57         ` Kees Cook
2022-01-27  0:20           ` Eric W. Biederman
2022-01-26 16:59     ` David Laight
2022-01-26 13:27 ` Rich Felker
2022-01-26 14:46   ` Christian Brauner
2022-01-26 17:37   ` Ariadne Conill
2022-02-01 20:54   ` hypervis0r
2022-01-26 15:02 Alexey Dobriyan
2022-01-27  0:00 ` Kees Cook

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).