[Toybox] cp --preserve=a doesn't preserve security context of directories.

Rob Landley rob at landley.net
Wed Aug 16 12:36:10 PDT 2023


On 8/16/23 09:14, enh wrote:
> strace other cp implementations?

I was hoping someone somewhere would actually have/know rules. :P

Alas strace doesn't show you that it checked 3 stat fields and then did this
thing, otherwise it would have done that other thing. You just get the one
codepath it took. And "I broke it" is way easier to spot than "I opened up a
theoretical security hole which somebody will exploit eight years from now in
combination with 3 other things."

I understand unix permissions, ownership, and filesystem atomicity: it helps
that they're 30-50 years old, simple, and widely used. (And that most systems
give each user their own group and leave it at that.) I think I understand at
least what containers are trying to accomplish. But I don't understand selinux
at all (even the mechanisms, let alone any specific rulesets), and am
uncomfortable trying to reason with it. I've seen too many "selinux vetoed
setuid and now this code is continuing to run with privileges it thought it
dropped" corner cases over the years where selinux's micromanaging of the unix
security model went about as well as china's micromanaging of its river systems,
and I tend to want to call in a professional when the topic comes up.

*shrug* Comfort thing, really. Changing the directory permissions during
traversal is in the easy to stop "I broke it" bucket if that goes wrong, but I
still need the paranoia checks at the top level so might as well do them for all
directories, with failure just meaning "don't apply selinux labels".

(Modulo NOT applying selinux labels to a directory _being_ the potential attack
surface, failing closed is still failing. But in the absence of a syscall that
can do dirfd = mkdiratopen(fdcwd, name) I'm just "managing suck", it moves the
potential exploits around. If the object got switched in the gap with a perfect
replica... I mean I can also check that the timestamp is between when I called
mkdir and when I called open() but they can set that, and the filesystem could
round the granularity putting it outside the window...)

(Don't get me started on capability bits. I am not a fan of capability bits.
"You have authority to set fire to the living room. YOU have authority to set
fire to the kitchen. YOU have authority to set fire to the bathroom. Now we're
much safer.")

> (if you've never looked at the source of
> https://github.com/SELinuxProject/selinux/tree/main/libselinux/src
> it's probably not the kind of code you're imagining/hoping code whose
> whole purpose is security should look like.)

I went through a chunk of selinux source when trying to figure out what xattrs
it actually sets, I think for adding xattr support to tar without pulling in a
shared library?

To quote Miracle Max, "I've seen worse", but that is very much not an endorsement.

Rob


More information about the Toybox mailing list