[Toybox] tar --null

Rob Landley rob at landley.net
Tue Jul 26 11:07:43 PDT 2022


On 7/25/22 17:00, enh wrote:
> so even if you do manage to break it ... we'll need to work around that at some
> point before we can sync AOSP anyway. (and i know the folks who invented and
> maintain asan, so i'm not worried even if you do find anything.)

If you LDFLAGS=--static with NDK 25 it goes:

ld: error: attempted static link of dynamic object
/home/android/android-ndk-r25/toolchains/llvm/prebuilt/linux-x86_64/lib64/clang/14.0.6/lib/linux/libclang_rt.asan-x86_64-android.so
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)

And on gcc it goes:

cc: error: cannot specify -static with -fsanitize=address

> asan's that too (unless you tell it not to be). like i said: no C/C++ programmer
> should be without it :-)

Unless they want to statically link.

>     That's a long running thing where I need
>     to see if I've missed any allocation lifetimes after running real world scripts
>     through it. I can police filehandles via /proc/self/fds but not heap objects...)
> 
> (fwiw, bionic has an fdsan/fdtrack system for this kind of thing, but it's not
> on for "random executables" by default. well, fd*san* is, but that's correctness
> not leaks. fdtrack is only enabled in system_server, aka "the giant monolith"
> which suffers most from a tragedy of the commons as far as leaks are concerned.)

The kernel can tell me which filehandles a process has open, that's the easy
part. The problem is the heap is maintained internally by libc, and libc has a
history of refusing to give you data about what it's doing internally because
they don't trust unwashed programmers. (See the recent thread over "number of
bytes available in a FILE * buffer so man 3 fileno doesn't drop data handing
over the context"...)

> again, don't worry about it --- if you want to do something, build with gcc and
> clang.

The only working musl clang I have is hexagon (I tried to build it more
generically against musl, ala https://landley.net/notes-2021.html#28-07-2021 but
the compiler-rt package was just horrific). The clang packaged up in devuan's
repo is 11 and they're up to 14 now, and last time I downloaded llvm.org's
prebuilt binary tarball it did not go well (I forget why) and they weren't
responsive to being poked, although it's been a while...

Mostly I wanted llvm.org to provide a "-cc" link so the NDK would provide a
"-cc" link. I even had a simple kernel patch to just "build with cc and
autodetect whether it's llvm or gcc", which the kernel guys completely ignored:

  https://lkml.iu.edu/hypermail/linux/kernel/2202.0/01505.html

And instead added truly insane "LLVM=1" magic that overrides what else you tell
it on the command line. (And means that if we ever get a third compiler, it's
STILL not generic! They just went from "always netscape" to "special case
netscape AND special case internet explorer".)

> it's not common that we have "our clang is so new that..." issues, and
> it's likely we can test and send you patches in less time than you'd have wasted
> doing "mostly fine" NDK builds.

Yeah but I'm trying to understand the territory.

>     Alas, AOSP hasn't got an obvious mkroot equivalent where I can get JUST build a
>     quick boot to shell prompt test. It's "set that thing running and go to lunch"
>     territory, and not something you can usefully do on battery either...
> 
> yeah, _that's_ a bit more of a loss. but tbh you can probably fake most of our
> differences by just being in a chroot with /bin/sh pointing to mksh :-)

Not the glibc vs bionic ones, nor the clang vs gcc ones. And I'm trying to point
/bin/sh to toysh. :)

> if that was where you were going with your question about "what filesystems are
> allowed?", i can try harder to get a canonical answer (or at least just tell you
> what we're currently using on Pixel and/or cuttlefish!).

There are a bunch of questions that are easy to ask and easy for a human to
eyeball the answers to, and just NASTY to automate in a regression test.
Especially without the lazy fallback to "run the debian one and run the toybox
one and compare their output" which is not how the test suite works at a design
level. (If I want android to build under android, it can't depend on debian
being there.)

"How much space should this file be using" involves knowing the UNITS on
stat->st_blocks, and while I'd love to do $(($(stat -c %B*%b"))) and have it
calculate the right size, the problem is toybox stat is hardwired to return
'512' for %B because I don't know how to query it. Linux DEFINES the size as
512, to the point "man 2 stat" even says:

     blkcnt_t  st_blocks;      /* Number of 512B blocks allocated */

MacOS uses a different value, but how do I query it? Linux doesn't provide a WAY
to query it because it was hardwired for the first 30 years of the platform and
everything since is a multiple of that block size (power of 2) so they just
never changed the plumbing. They didn't need to: blksize_t is "long" under the
covers so it's limited to 2.1 terabytes/file on 32 bit and on 64 bit... um,
1<<(64+9) would be 1<<73 which is... 8 zettabytes? Or 4 if it's signed? More
data than humanity has currently recorded in its entire history, I expect. The
unit granularity has not been an issue, is what I'm saying. Smaller VFS
granularity is actually slightly nicer for mmap() so it can always round UP to
DRAM page size instead of potentially having to round the other way on storage
with large erase block sizes...)

I looked for a stat field potentially RETURNING 512, but on devuan
statfs->f_bsize and statfs->f_frsize are both 4096 in the check I just did,
neither returns "512" since that was the universal hard disk block size until a
little over a decade ago so it was never NOT 512 until recently-ish:

  https://lwn.net/Articles/322777/

And they just layered bigger virtual aggregate blocks on top of the 512.

As for where the 512 comes from in Linux, digging down into what sets
stat->st_blocks, fs/stat.c copies it from struct kstat *stat->blocks which is
populated by calling vfs_stat() which is a wrapper for vfs_fstatat() which calls
vfs_statx() which calls vfs_getattr() which calls vfs_getattr_nosec() which
calls inode->i_op->getattr() followed by generic_fillattr() which copies it from
inode->i_blocks. So either way it comes from whatever units the individual
filesystem is using. So changing it would involve a flag day touching all
filesystem drivers: wheee.

Anyway, I can change the test to statfs -c %B and do math, but I need a way to
query what size MacOS uses that I can stick in portability.h, and that's still
not going to fix the mac VFS bug we found with multiple truncates allocating space.

>     Rob

Still Rob


More information about the Toybox mailing list