Discussion:
[Toybox] [landley/toybox] cp -R --preserve timing (#66)
Rob Landley
2017-05-04 03:06:04 UTC
Permalink
cp -R --preserve copies the content of a folder, before copying
owner/permissions.
You can't create things with arbitrary ownership, and writing to
something with an suid bit removes the suid bit.
This can be problematic if the copy is canceled.
For instance, if we have
/a 1000 1000 0755
/a/b 2000 2000 0755
/a 0 0 0775
/a/b 2000 2000 0755
The "cp" might command might be behind a daemon-wall, which leads to an
unrecoverable state.
You can run cp as root but can't run cleanup as root?
For instance, in Android, vold uses cp -R --preserve to move data from
internal to external storage and back.
vold runs as root, this means that if the copy is stopped during the
migration, /data/media will contain a root-owned directory. This means
this folder won't ever be removable or writable ever, unless the user
does a factory reset.
This sounds like a bug in vold. (What's a vold?)

https://www.slideshare.net/wiliwe/android-storage-vold

Android volume daemon. Ok.

Part of the reason I did that was to minimize the likelihood of symlink
attacks where you cp -a and somebody drops a symlink to a new file it
wants you to overwrite. If they can't write to the directory until
you're done with it, they can't do that. So it creates directories
belonging to the user and non-world-writeable, copies the contents into
them, and then does the chown/chmod to the final ownership and
permissions on the way out. (This also avoids the problem of writing
files into a read-only directory.)

I could instead open the files O_EXCL but cp historically doesn't do
that, and has defined behavior for "cp file /dev/ttyS0" and so on where
it does O_TRUNC and then writes, so if you have a removable disk it
images it and if you have hardlinks it updates all copies.

I'm fine with changing how it works, just explaining why I did it in the
first place.

Elliott: any opinions on the right place to fix this?

Rob
enh
2017-05-04 05:07:32 UTC
Permalink
Post by Rob Landley
cp -R --preserve copies the content of a folder, before copying
owner/permissions.
You can't create things with arbitrary ownership, and writing to
something with an suid bit removes the suid bit.
This can be problematic if the copy is canceled.
For instance, if we have
/a 1000 1000 0755
/a/b 2000 2000 0755
We'll have a point in time where during cp -R --preserve as root, we
/a 0 0 0775
/a/b 2000 2000 0755
The "cp" might command might be behind a daemon-wall, which leads to an
unrecoverable state.
You can run cp as root but can't run cleanup as root?
yeah, i'm not sure how you'd actually hit this with vold. here's a fragment
of the relevant calling code:

// Step 2: clean up any stale data
if (execRm(toPath, 10, 10) != OK) {
goto fail;
}

// Step 3: perform actual copy
if (execCp(fromPath, toPath, 20, 60) != OK) {
goto copy_fail;
}

if you have repro steps, [file a bug](
https://source.android.com/source/report-bugs).
Post by Rob Landley
For instance, in Android, vold uses cp -R --preserve to move data from
internal to external storage and back.
vold runs as root, this means that if the copy is stopped during the
migration, /data/media will contain a root-owned directory. This means
this folder won't ever be removable or writable ever, unless the user
does a factory reset.
This sounds like a bug in vold. (What's a vold?)
https://www.slideshare.net/wiliwe/android-storage-vold
Android volume daemon. Ok.
Part of the reason I did that was to minimize the likelihood of symlink
attacks where you cp -a and somebody drops a symlink to a new file it
wants you to overwrite. If they can't write to the directory until
you're done with it, they can't do that. So it creates directories
belonging to the user and non-world-writeable, copies the contents into
them, and then does the chown/chmod to the final ownership and
permissions on the way out. (This also avoids the problem of writing
files into a read-only directory.)
I could instead open the files O_EXCL but cp historically doesn't do
that, and has defined behavior for "cp file /dev/ttyS0" and so on where
it does O_TRUNC and then writes, so if you have a removable disk it
images it and if you have hardlinks it updates all copies.
I'm fine with changing how it works, just explaining why I did it in the
first place.
Elliott: any opinions on the right place to fix this?
Rob
_______________________________________________
Toybox mailing list
http://lists.landley.net/listinfo.cgi/toybox-landley.net
--
Elliott Hughes - http://who/enh - http://jessies.org/~enh/
Android native code/tools questions? Mail me/drop by/add me as a reviewer.
Loading...