From: Kees Cook <keescook@chromium.org>
To: "Eric W. Biederman" <ebiederm@xmission.com>
Cc: "Alexander Viro" <viro@zeniv.linux.org.uk>,
"Christian Brauner" <brauner@kernel.org>,
linux-fsdevel@vger.kernel.org, linux-mm@kvack.org,
"Sebastian Ott" <sebott@redhat.com>,
"Thomas Weißschuh" <linux@weissschuh.net>,
"Pedro Falcato" <pedro.falcato@gmail.com>,
linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org
Subject: Re: [PATCH v3 3/4] binfmt_elf: Provide prot bits as context for padzero() errors
Date: Thu, 28 Sep 2023 17:51:38 -0700 [thread overview]
Message-ID: <202309281750.FA45C0DBB@keescook> (raw)
In-Reply-To: <87y1gr8j51.fsf@email.froward.int.ebiederm.org>
On Wed, Sep 27, 2023 at 03:18:34PM -0500, Eric W. Biederman wrote:
> Kees Cook <keescook@chromium.org> writes:
>
> > Errors with padzero() should be caught unless we're expecting a
> > pathological (non-writable) segment. Report -EFAULT only when PROT_WRITE
> > is present.
> >
> > Additionally add some more documentation to padzero(), elf_map(), and
> > elf_load().
>
> I wonder if this might be easier to just perform the PROT_WRITE
> test in elf_load, and to completely skip padzero of PROT_WRITE
> is not present.
Yeah, actually, after moving load_elf_library() to elf_load(), there's
only 1 caller of padzero... :P
I'll work on that.
-Kees
>
> Eric
>
> > Cc: Eric Biederman <ebiederm@xmission.com>
> > Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> > Cc: Christian Brauner <brauner@kernel.org>
> > Cc: linux-fsdevel@vger.kernel.org
> > Cc: linux-mm@kvack.org
> > Suggested-by: Eric Biederman <ebiederm@xmission.com>
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> > ---
> > fs/binfmt_elf.c | 33 +++++++++++++++++++++++----------
> > 1 file changed, 23 insertions(+), 10 deletions(-)
> >
> > diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> > index 0214d5a949fc..b939cfe3215c 100644
> > --- a/fs/binfmt_elf.c
> > +++ b/fs/binfmt_elf.c
> > @@ -110,19 +110,21 @@ static struct linux_binfmt elf_format = {
> >
> > #define BAD_ADDR(x) (unlikely((unsigned long)(x) >= TASK_SIZE))
> >
> > -/* We need to explicitly zero any fractional pages
> > - after the data section (i.e. bss). This would
> > - contain the junk from the file that should not
> > - be in memory
> > +/*
> > + * We need to explicitly zero any trailing portion of the page that follows
> > + * p_filesz when it ends before the page ends (e.g. bss), otherwise this
> > + * memory will contain the junk from the file that should not be present.
> > */
> > -static int padzero(unsigned long elf_bss)
> > +static int padzero(unsigned long address, int prot)
> > {
> > unsigned long nbyte;
> >
> > - nbyte = ELF_PAGEOFFSET(elf_bss);
> > + nbyte = ELF_PAGEOFFSET(address);
> > if (nbyte) {
> > nbyte = ELF_MIN_ALIGN - nbyte;
> > - if (clear_user((void __user *) elf_bss, nbyte))
> > + /* Only report errors when the segment is writable. */
> > + if (clear_user((void __user *)address, nbyte) &&
> > + prot & PROT_WRITE)
> > return -EFAULT;
> > }
> > return 0;
> > @@ -348,6 +350,11 @@ create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
> > return 0;
> > }
> >
> > +/*
> > + * Map "eppnt->p_filesz" bytes from "filep" offset "eppnt->p_offset"
> > + * into memory at "addr". (Note that p_filesz is rounded up to the
> > + * next page, so any extra bytes from the file must be wiped.)
> > + */
> > static unsigned long elf_map(struct file *filep, unsigned long addr,
> > const struct elf_phdr *eppnt, int prot, int type,
> > unsigned long total_size)
> > @@ -387,6 +394,11 @@ static unsigned long elf_map(struct file *filep, unsigned long addr,
> > return(map_addr);
> > }
> >
> > +/*
> > + * Map "eppnt->p_filesz" bytes from "filep" offset "eppnt->p_offset"
> > + * into memory at "addr". Memory from "p_filesz" through "p_memsz"
> > + * rounded up to the next page is zeroed.
> > + */
> > static unsigned long elf_load(struct file *filep, unsigned long addr,
> > const struct elf_phdr *eppnt, int prot, int type,
> > unsigned long total_size)
> > @@ -405,7 +417,8 @@ static unsigned long elf_load(struct file *filep, unsigned long addr,
> > eppnt->p_memsz;
> >
> > /* Zero the end of the last mapped page */
> > - padzero(zero_start);
> > + if (padzero(zero_start, prot))
> > + return -EFAULT;
> > }
> > } else {
> > map_addr = zero_start = ELF_PAGESTART(addr);
> > @@ -712,7 +725,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
> > * the file up to the page boundary, and zero it from elf_bss
> > * up to the end of the page.
> > */
> > - if (padzero(elf_bss)) {
> > + if (padzero(elf_bss, bss_prot)) {
> > error = -EFAULT;
> > goto out;
> > }
> > @@ -1407,7 +1420,7 @@ static int load_elf_library(struct file *file)
> > goto out_free_ph;
> >
> > elf_bss = eppnt->p_vaddr + eppnt->p_filesz;
> > - if (padzero(elf_bss)) {
> > + if (padzero(elf_bss, PROT_WRITE)) {
> > error = -EFAULT;
> > goto out_free_ph;
> > }
--
Kees Cook
next prev parent reply other threads:[~2023-09-29 0:51 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-09-27 3:42 [PATCH v3 0/4] binfmt_elf: Support segments with 0 filesz and misaligned starts Kees Cook
2023-09-27 3:42 ` [PATCH v3 1/4] " Kees Cook
2023-09-27 3:42 ` [PATCH v3 2/4] binfmt_elf: elf_bss no longer used by load_elf_binary() Kees Cook
2023-09-27 3:42 ` [PATCH v3 3/4] binfmt_elf: Provide prot bits as context for padzero() errors Kees Cook
2023-09-27 20:18 ` Eric W. Biederman
2023-09-29 0:51 ` Kees Cook [this message]
2023-09-27 3:42 ` [PATCH v3 4/4] binfmt_elf: Use elf_load() for interpreter Kees Cook
2023-09-27 20:25 ` [PATCH v3 0/4] binfmt_elf: Support segments with 0 filesz and misaligned starts Eric W. Biederman
2023-09-28 12:55 ` Sebastian Ott
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=202309281750.FA45C0DBB@keescook \
--to=keescook@chromium.org \
--cc=brauner@kernel.org \
--cc=ebiederm@xmission.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-hardening@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=linux@weissschuh.net \
--cc=pedro.falcato@gmail.com \
--cc=sebott@redhat.com \
--cc=viro@zeniv.linux.org.uk \
/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.