From: Kees Cook <keescook@chromium.org>
To: Fangrui Song <maskray@google.com>
Cc: Pedro Falcato <pedro.falcato@gmail.com>,
Rich Felker <dalias@libc.org>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Eric Biederman <ebiederm@xmission.com>,
sam@gentoo.org, linux-fsdevel@vger.kernel.org,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
linux-hardening@vger.kernel.org
Subject: Re: [PATCH v2] binfmt_elf: Allow .bss in any interp PT_LOAD
Date: Fri, 11 Nov 2022 12:13:19 -0800 [thread overview]
Message-ID: <202211111211.93ED8B4B@keescook> (raw)
In-Reply-To: <20221111074234.xm5a6ota7ppdsto5@google.com>
On Thu, Nov 10, 2022 at 11:42:34PM -0800, Fangrui Song wrote:
> (+ sam@gentoo.org from Pedro Falcato's patch)
>
> On 2022-11-10, Kees Cook wrote:
> > Traditionally, only the final PT_LOAD for load_elf_interp() supported
> > having p_memsz > p_filesz. Recently, lld's construction of musl's
> > libc.so on PowerPC64 started having two PT_LOAD program headers with
> > p_memsz > p_filesz.
> >
> > As the least invasive change possible, check for p_memsz > p_filesz for
> > each PT_LOAD in load_elf_interp.
> >
> > Reported-by: Rich Felker <dalias@libc.org>
> > Link: https://maskray.me/blog/2022-11-05-lld-musl-powerpc64
> > Cc: Pedro Falcato <pedro.falcato@gmail.com>
> > Cc: Fangrui Song <maskray@google.com>
> > Cc: Alexander Viro <viro@zeniv.linux.org.uk>
> > Cc: Eric Biederman <ebiederm@xmission.com>
> > Cc: linux-fsdevel@vger.kernel.org
> > Cc: linux-mm@kvack.org
> > Signed-off-by: Kees Cook <keescook@chromium.org>
> > ---
> > v2: I realized we need to retain the final padding call.
> > v1: https://lore.kernel.org/linux-hardening/20221111055747.never.202-kees@kernel.org/
> > ---
> > fs/binfmt_elf.c | 18 ++++++++++++++----
> > 1 file changed, 14 insertions(+), 4 deletions(-)
> >
> > diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
> > index 528e2ac8931f..0a24bbbef1d6 100644
> > --- a/fs/binfmt_elf.c
> > +++ b/fs/binfmt_elf.c
> > @@ -673,15 +673,25 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
> > last_bss = k;
> > bss_prot = elf_prot;
> > }
> > +
> > + /*
> > + * Clear any p_memsz > p_filesz area up to the end
> > + * of the page to wipe anything left over from the
> > + * loaded file contents.
> > + */
> > + if (last_bss > elf_bss && padzero(elf_bss))
>
> Missing {
>
> But after fixing this, I get a musl ld.so error.
>
> > + error = -EFAULT;
> > + goto out;
> > + }
> > }
> > }
> >
> > /*
> > - * Now fill out the bss section: first pad the last page from
> > - * the file up to the page boundary, and zero it from elf_bss
> > - * up to the end of the page.
> > + * Finally, pad the last page from the file up to the page boundary,
> > + * and zero it from elf_bss up to the end of the page, if this did
> > + * not already happen with the last PT_LOAD.
> > */
> > - if (padzero(elf_bss)) {
> > + if (last_bss == elf_bss && padzero(elf_bss)) {
> > error = -EFAULT;
> > goto out;
> > }
> > --
> > 2.34.1
> >
>
> I added a new section to https://maskray.me/blog/2022-11-05-lld-musl-powerpc64
> Copying here:
>
> To test that the kernel ELF loader can handle more RW `PT_LOAD` program headers, we can create an executable with more RW `PT_LOAD` program headers with `p_filesz < p_memsz`.
> We can place a read-only section after `.bss` followed by a `SHT_NOBITS` `SHF_ALLOC|SHF_WRITE` section. The read-only section will form a read-only `PT_LOAD` while the RW section will form a RW `PT_LOAD`.
>
> ```text
> #--- a.c
> #include <assert.h>
> #include <stdio.h>
>
> extern const char toc[];
> char nobits0[0] __attribute__((section(".nobits0")));
> char nobits1[0] __attribute__((section(".nobits1")));
>
> int main(void) {
> assert(toc[4096-1] == 0);
> for (int i = 0; i < 1024; i++)
> assert(nobits0[i] == 0);
> nobits0[0] = nobits0[1024-1] = 1;
> for (int i = 0; i < 4096; i++)
> assert(nobits1[i] == 0);
> nobits1[0] = nobits1[4096-1] = 1;
>
> puts("hello");
> }
>
> #--- toc.s
> .section .toc,"aw",@nobits
> .globl toc
> toc:
> .space 4096
>
> .section .ro0,"a"; .byte 255
> .section .nobits0,"aw",@nobits; .space 1024
> .section .ro1,"a"; .byte 255
> .section .nobits1,"aw",@nobits; .space 4096
>
> #--- a.lds
> SECTIONS { .ro0 : {} .nobits0 : {} .ro1 : {} .nobits1 : {} } INSERT AFTER .bss;
> ```
>
> ```sh
> split-file a.txt a
> path/to/musl-gcc -Wl,--dynamic-linker=/lib/libc.so a/a.c a/a.lds -o toy
> ```
>
> split-file is a utility in llvm-project.
Where is a.txt? Also, it'd be nice to have this without needing the
musl-gcc.
--
Kees Cook
next prev parent reply other threads:[~2022-11-11 20:14 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-11 6:13 [PATCH v2] binfmt_elf: Allow .bss in any interp PT_LOAD Kees Cook
2022-11-11 7:42 ` Fangrui Song
2022-11-11 20:13 ` Kees Cook [this message]
2022-11-11 20:27 ` Fangrui Song
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=202211111211.93ED8B4B@keescook \
--to=keescook@chromium.org \
--cc=dalias@libc.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=maskray@google.com \
--cc=pedro.falcato@gmail.com \
--cc=sam@gentoo.org \
--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.