From: Greg KH <gregkh@linuxfoundation.org>
To: Vegard Nossum <vegard.nossum@oracle.com>
Cc: stable@vger.kernel.org, Kees Cook <keescook@chromium.org>,
Ariadne Conill <ariadne@dereferenced.org>,
Michael Kerrisk <mtk.manpages@gmail.com>,
Matthew Wilcox <willy@infradead.org>,
Christian Brauner <brauner@kernel.org>,
Rich Felker <dalias@libc.org>,
Eric Biederman <ebiederm@xmission.com>,
Alexander Viro <viro@zeniv.linux.org.uk>,
linux-fsdevel@vger.kernel.org, Andy Lutomirski <luto@kernel.org>
Subject: Re: [PATCH 4.9.y] exec: Force single empty string when argv is empty
Date: Fri, 3 Jun 2022 16:50:53 +0200 [thread overview]
Message-ID: <YpofzcMaOWneccCp@kroah.com> (raw)
In-Reply-To: <20220601101226.1498-1-vegard.nossum@oracle.com>
On Wed, Jun 01, 2022 at 12:12:26PM +0200, Vegard Nossum wrote:
> From: Kees Cook <keescook@chromium.org>
>
> commit dcd46d897adb70d63e025f175a00a89797d31a43 upstream.
>
> Quoting[1] Ariadne Conill:
>
> "In several other operating systems, it is a hard requirement that the
> second argument to execve(2) be the name of a program, thus prohibiting
> a scenario where argc < 1. POSIX 2017 also recommends this behaviour,
> but it is not an explicit requirement[2]:
>
> The argument arg0 should point to a filename string that is
> associated with the process being started by one of the exec
> functions.
> ...
> Interestingly, Michael Kerrisk opened an issue about this in 2008[3],
> but there was no consensus to support fixing this issue then.
> Hopefully now that CVE-2021-4034 shows practical exploitative use[4]
> of this bug in a shellcode, we can reconsider.
>
> This issue is being tracked in the KSPP issue tracker[5]."
>
> While the initial code searches[6][7] turned up what appeared to be
> mostly corner case tests, trying to that just reject argv == NULL
> (or an immediately terminated pointer list) quickly started tripping[8]
> existing userspace programs.
>
> The next best approach is forcing a single empty string into argv and
> adjusting argc to match. The number of programs depending on argc == 0
> seems a smaller set than those calling execve with a NULL argv.
>
> Account for the additional stack space in bprm_stack_limits(). Inject an
> empty string when argc == 0 (and set argc = 1). Warn about the case so
> userspace has some notice about the change:
>
> process './argc0' launched './argc0' with NULL argv: empty string added
>
> Additionally WARN() and reject NULL argv usage for kernel threads.
>
> [1] https://lore.kernel.org/lkml/20220127000724.15106-1-ariadne@dereferenced.org/
> [2] https://pubs.opengroup.org/onlinepubs/9699919799/functions/exec.html
> [3] https://bugzilla.kernel.org/show_bug.cgi?id=8408
> [4] https://www.qualys.com/2022/01/25/cve-2021-4034/pwnkit.txt
> [5] https://github.com/KSPP/linux/issues/176
> [6] https://codesearch.debian.net/search?q=execve%5C+*%5C%28%5B%5E%2C%5D%2B%2C+*NULL&literal=0
> [7] https://codesearch.debian.net/search?q=execlp%3F%5Cs*%5C%28%5B%5E%2C%5D%2B%2C%5Cs*NULL&literal=0
> [8] https://lore.kernel.org/lkml/20220131144352.GE16385@xsang-OptiPlex-9020/
>
> Reported-by: Ariadne Conill <ariadne@dereferenced.org>
> Reported-by: Michael Kerrisk <mtk.manpages@gmail.com>
> Cc: Matthew Wilcox <willy@infradead.org>
> Cc: Christian Brauner <brauner@kernel.org>
> Cc: Rich Felker <dalias@libc.org>
> Cc: Eric Biederman <ebiederm@xmission.com>
> Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> Cc: linux-fsdevel@vger.kernel.org
> Cc: stable@vger.kernel.org
> Signed-off-by: Kees Cook <keescook@chromium.org>
> Acked-by: Christian Brauner <brauner@kernel.org>
> Acked-by: Ariadne Conill <ariadne@dereferenced.org>
> Acked-by: Andy Lutomirski <luto@kernel.org>
> Link: https://lore.kernel.org/r/20220201000947.2453721-1-keescook@chromium.org
> [vegard: fixed conflicts due to missing
> 886d7de631da71e30909980fdbf318f7caade262^- and
> 3950e975431bc914f7e81b8f2a2dbdf2064acb0f^- and
> 655c16a8ce9c15842547f40ce23fd148aeccc074]
> Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com>
> ---
> fs/exec.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> This has been tested in both argc == 0 and argc >= 1 cases, but I would
> still appreciate a review given the differences with mainline. If it's
> considered too risky I'm also fine with dropping it -- just wanted to
> make sure this didn't fall through the cracks, as it does block a real
> (albeit old by now) exploit.
>
> diff --git a/fs/exec.c b/fs/exec.c
> index 482a8b4f41a5b..19f8b075d3b6b 100644
> --- a/fs/exec.c
> +++ b/fs/exec.c
> @@ -1758,6 +1758,9 @@ static int do_execveat_common(int fd, struct filename *filename,
> goto out_unmark;
>
> bprm->argc = count(argv, MAX_ARG_STRINGS);
> + if (bprm->argc == 0)
> + pr_warn_once("process '%s' launched '%s' with NULL argv: empty string added\n",
> + current->comm, bprm->filename);
> if ((retval = bprm->argc) < 0)
> goto out;
>
> @@ -1782,6 +1785,20 @@ static int do_execveat_common(int fd, struct filename *filename,
> if (retval < 0)
> goto out;
>
> + /*
> + * When argv is empty, add an empty string ("") as argv[0] to
> + * ensure confused userspace programs that start processing
> + * from argv[1] won't end up walking envp. See also
> + * bprm_stack_limits().
> + */
> + if (bprm->argc == 0) {
> + const char *argv[] = { "", NULL };
> + retval = copy_strings_kernel(1, argv, bprm);
> + if (retval < 0)
> + goto out;
> + bprm->argc = 1;
> + }
> +
> retval = exec_binprm(bprm);
> if (retval < 0)
> goto out;
> --
> 2.35.1.46.g38062e73e0
>
All now queued up, thanks.
greg k-h
prev parent reply other threads:[~2022-06-03 14:51 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-02 12:43 FAILED: patch "[PATCH] exec: Force single empty string when argv is empty" failed to apply to 4.9-stable tree gregkh
2022-06-01 10:12 ` [PATCH 4.9.y] exec: Force single empty string when argv is empty Vegard Nossum
2022-06-03 14:50 ` Greg KH [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=YpofzcMaOWneccCp@kroah.com \
--to=gregkh@linuxfoundation.org \
--cc=ariadne@dereferenced.org \
--cc=brauner@kernel.org \
--cc=dalias@libc.org \
--cc=ebiederm@xmission.com \
--cc=keescook@chromium.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=luto@kernel.org \
--cc=mtk.manpages@gmail.com \
--cc=stable@vger.kernel.org \
--cc=vegard.nossum@oracle.com \
--cc=viro@zeniv.linux.org.uk \
--cc=willy@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.