[Toybox] [PATCH] Support diff --no-dereference

enh enh at google.com
Fri Aug 23 04:33:14 PDT 2024


On Fri, Aug 23, 2024 at 3:32 AM Rob Landley <rob at landley.net> wrote:
>
> On 8/22/24 08:23, enh via Toybox wrote:
> > +  int s = sizeof(toybuf)/2;
> > +
> > +  TT.is_symlink = 1;
> > +  for (i = 0; i < 2; i++) {
> > +    TT.link[i].name = toybuf + i * s;
> > +    TT.link[i].len = readlink0(files[i], TT.link[i].name, s);
> >
> > should probably use xreadlink() and free() instead? toybuf is big
> > enough to be safe for _one_ path on linux, but not two.
>
> Eh, no arbitrary buffer is "enough". PATH_MAX is slowly getting phased out, and
> even posix-2008 requires arbitrary depth for "rm" because:
>
> $ for ((i=0;i<10000;i++)); do mv a b; mkdir a; mv b a/a; done

i thought in practice though linux couldn't cope with longer paths?

if not, every call to readlink0()/readlinkat0() looks problematic.
plus there's one lone call to readlink() in main.c that's using libbuf
rather than toybuf (although "you put your toybox binary symlinks more
than 4096 bytes deep" sounds like "please stop shooting at your feet"
to me!).

> And rm -rf has to be able to cope with that. (Note that's _in_ a long path when
> it does a mkdir, it's extending from the TOP. Plus "mount" could always splice
> PATH_MAX to PATH_MAX...)
>
> Meanwhile, symlinks are inherently problematic because the kernel's recursion
> counter resolving them is per-link so if your $PWD has a few links in it and
> then you go into another /path/from/root that also has symlinks in it you can
> run out of dereferences without ever hitting anything _like_ recursion.
>
> What we really need is loop detection, which is tricksy because dereferencing
> "ln -s . potato" isn't a loop. Loops only happen when you follow a symlink to an
> absolute path...
>
> Anyway, a 256 byte buffer would handle 99% of the cases, and this is likely to
> handle all the ones we'd ever actually hit. If we want a proper fix what we need
> is to teach readlink0() to dynamically allocate a buffer, and THAT has the
> problem that the kernel API returns "error" for buffer not big enough without
> telling us how big a buffer we NEED, so you have to iteratively guess...

that's what xreadlink() already does :-)

> Rob
> _______________________________________________
> Toybox mailing list
> Toybox at lists.landley.net
> http://lists.landley.net/listinfo.cgi/toybox-landley.net


More information about the Toybox mailing list