lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Tue, 22 Mar 2022 19:24:48 +0100
From:   Willy Tarreau <w@....eu>
To:     Nick Desaulniers <ndesaulniers@...gle.com>
Cc:     Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
        GNU/Weeb Mailing List <gwml@...r.gnuweeb.org>,
        llvm@...ts.linux.dev
Subject: Re: [RFC PATCH v2 2/8] tools/nolibc: Remove .global _start from the
 entry point code

On Tue, Mar 22, 2022 at 11:07:17AM -0700, Nick Desaulniers wrote:
> > First, the usual static printf("hello world!\n"):
> >
> >   $ ll hello-*libc
> >   -rwxrwxr-x 1 willy dev 719232 Mar 22 18:50 hello-glibc*
> >   -rwxrwxr-x 1 willy dev   1248 Mar 22 18:51 hello-nolibc*
> 
> ! What! Are those both statically linked?

Yes:

  $ file hello-nolibc 
  hello-nolibc: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped

  (rebuilding without stripping)
  $ nm --size hello-nolibc 
  000000000000000f T main
  0000000000000053 t u64toa_r
  0000000000000280 t printf.constprop.0
  $ nm hello-nolibc 
  00000000004013c5 R __bss_start
  00000000004013c5 R _edata
  00000000004013c8 R _end
  00000000004000bf W _start
  00000000004000b0 T main
  0000000000400130 t printf.constprop.0
  00000000004000dd t u64toa_r

> > This one supports ~30-40 simple commands (mount/unmount, mknod, ls, ln),
> > a tar extractor, multi-level braces, and boolean expression evaluation,
> > variable expansion, and a config file parser to script all this. The code
> > is 20 years old and is really ugly (even uglier than you think). But that
> > gives an idea. 20 years ago the init was much simpler and 800 bytes (my
> > constraint was for single floppies containing kernel+rootfs) and strings
> > were manually merged by tails and put in .text to drop .rodata.
> 
> Oh, so nolibc has been around for a while then?

Not exactly. Over time I collected some of my stuff out of preinit to
make more reusable code for other tools, and eventually created a separate
project for it 5 years ago [1]. I then changed my mind a few times on how
to arrange all this and over time it became a bit easier to use. One day
Paul asked how to make less invasive static binaries for rcutorture and I
found that it was the perfect match so we agreed to integrate it there. It
was still a single file by then. And as usual when some code starts to get
more exposure it receives more contribs and feature requests ;-)

> ld.lld will do string merging in that fashion at -O2 (the linker can
> accept and optimization level).  I did have a kernel patch for that
> somewhere, need to update it for CC_OPTIMIZE_FOR_SIZE...

Ah I didn't know, that's good to know!

> I guess the tradeoff with strings in .text is that now the strings
> themselves are r+x and not just r?

Yes but when you're writing a small shell to allow you to manually
mount your rootfs from the kernel, you don't really care if someone
might try to use some of your strings as code gadgets for ROP exploits :-)

I would really not want to see this used for general programs, but it
does fit well with hacking stuff for initramfs, and what lies in the
selftests directory in general I guess.

What I particularly like is that I don't need a full toolchain, so if
I can build a kernel with the bare-metal compilers from kernel.org then
I know I can also build my initramfs that's packaged in it using the
exact same compiler. This significantly simplifies the build process.

Willy

[1] https://github.com/wtarreau/nolibc

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ