[Toybox] Android sitrep
Rob Landley
rob at landley.net
Wed Oct 23 00:26:27 PDT 2019
On 10/17/19 4:09 PM, Denys Nykula wrote:
>> the tar "no ../ files outside this directory" check is
>> false positiving on "./" for some reason, gotta track that down.
>
> Here's a reproducible toy tar crash, might or might not be connected.
I wasn't seeing a segfault.
> git clone https://github.com/landley/toybox
> wget http://musl.cc/x86_64-linux-musl-native.tgz
> rm -r root.tar toybox/root x86_64-linux-musl-native
> (cd toybox; make defconfig root)
> toybox/toybox tar xf x86_64-linux-musl-native.tgz
> (cd toybox/root/*/*fs; ../../../toybox tar c *)>root.tar
> cd x86_64-linux-musl-native &&../toybox/toybox tar xvf ../root.tar
> # ...
> # tar: can't remove: bin: Is a directory
> # tar: can't remove: lib: Is a directory
> # tar: 'usr/' not under '/path/to/x86_64-linux-musl-native'
Hmmm, the usr->. is confusing it because "usr" _isn't_ under that directory, it
_is_ that directory. (It's not a child of it, it's the thing itself.)
That's... technically correct? Although it's more a NOP than an error in this
corner case.
> # Segmentation fault
Sigh. Reproduced.
It's because sbin is a circular symlink: you have sbin -> usr/sbin and usr -> .
so the link points back to itself. This makes xabspath() return null and I'm
calling it in a mode where the "x" part doesn't error_exit for that, but didn't
handle it myself. :P
Huh. What _is_ the right behavior for this? There's _kinda_ some conflicting
assumptions in these two filesystems. :)
> First two errors are correct, refusing to overwrite an existing dir with
> a symlink and moving on, remembering to make a bad exit code later. But
> then you hit an existing symlink to a dir. Other implementations replace
> the symlink with the dir and keep unpacking files there. Toy tar doesn't
> overwrite, says odd message, starts extracting children of a dir that
> hasn't been created, and crashes. Full output below.
That's not why it crashes, it crashes because it couldn't resolve the absolute
path and I called an xfunction() in a mode that didn't error_exit() and then
didn't handle the error myself. :)
Probably something like:
--- a/toys/posix/tar.c
+++ b/toys/posix/tar.c
@@ -392,7 +392,11 @@ static int dirflush(char *name)
// Barf if name not in TT.cwd
if (name) {
- ss = s = xabspath(name, -1);
+ if (!(ss = s = xabspath(name, -1))) {
+ error_msg("'%s' bad symlink", name);
+
+ return 1;
+ }
if (TT.cwd[1] && (!strstart(&ss, TT.cwd) || *ss!='/')) {
error_msg("'%s' not under '%s'", name, TT.cwd);
free(s);
The question is, what behavior do you want? If sbin points to usr/sbin and usr
points to . then sbin points to sbin and you _can't_ extract stuff under it.
What behavior do you expect here?
It looks like the gnu/dammit tar is deleting the usr symlink and replacing it
with a directory. I can do that for directories I guess? (Fiddle, fiddle...)
Yes, it looks like it's _always_ replacing a symlink with a directory when
extract says a directory should be there. Which is a little awkward because the
"is this target under here" test comes _before_ it looks at _what_ should go
there, so I need to rearrange things a bit when I'm more awake.
Rob
More information about the Toybox
mailing list