[Toybox] cpio -d patch...
Rob Landley
rob at landley.net
Tue Mar 11 04:53:36 PDT 2014
Trying to tie off the loose ends for a long-overdue release, and
Isaac's cpio -d patch is half-finished in my tree.
The problem with the original patch is that "mkdir -pm 500
one/two/three" should work creating a read only "three" under a
read/write "one/two". If "one" is read only it fails to create "two".
Thus the original mkpath logic was that the supplied mode only applied
to the _last_ directory component, and the others just used the umask.
But the version of the function moved to lib isn't doing that, which
breaks mkpath.
So I took another stab at this (the patch to break out the mkpath.c
logic so cpio -d can use it), and got a clean version that creates
everything _except_ the last directory. (The idea was to avoid passing
in a mode at all, because the mode only varies for the last directory.)
Unfortunately, that didn't help because the logic to create _just_ the
last directory (with the "verbose" option and error checking) was about
as large as the whole recursive loop it factored out. I.E. genericizing
this particular way bloats mkdir significantly...
What I _could_ do is is have it mkpath the whole thing with the umode,
and then chmod the last path after creation. But I hate ever doing
anything twice in the filesystem because that's where security
exploitable race conditions come from: letting the directory be world
writeable for a fraction of a section when it shouldn't have been. So
if it's going to have certain permissions, it should be atomically
_created_ with those permissions.
By the way, if you notice those games with 0777&~toys.umask, that's
because mkdir has TOYFLAG_UMASK in its NEWTOY() flags, which tells
main() to set the umask to 0 (and save the old umask in toys.umask).
That way when we create things, we get the permission we actually
request rather than a filtered subset, allowing things like mkdir -m to
work properly. I note that toys/pending/cpio.c is _not_ doing that, nor
is it calling umask(0) itself, meaning it's allowing umask to filter
the permissions of everything it creates rather than producing output
with the actual modes recorded in the archive. Is this intentional?
(The kernel's initramfs logic requires you to have a directory creation
entry before any file using that directory. Files created in
nonexistent directories are silently ignored. I haven't checked ot see
what rpm does.)
This is why this one's taken so long: there turn out to be several
subtly wrong ways to do it...
Rob
1394538816.0
More information about the Toybox
mailing list