The trouble with symbolic links
The trouble with symbolic links
Posted Jul 7, 2022 17:40 UTC (Thu) by sbaugh (guest, #103291)Parent article: The trouble with symbolic links
Posted Jul 7, 2022 20:09 UTC (Thu)
by wahern (subscriber, #37304)
[Link] (12 responses)
Posted Jul 7, 2022 21:33 UTC (Thu)
by neilbrown (subscriber, #359)
[Link] (11 responses)
But it isn't just bind mounts, it is bind mounts in a private namespace. I don't think they are insecure.
The insecurity of symlinks is that if I create a symlink you have to follow it. When I create a bind mount in a private namespace you can't even see it let alone follow it
Posted Jul 7, 2022 22:15 UTC (Thu)
by willy (subscriber, #9762)
[Link] (10 responses)
Posted Jul 7, 2022 22:43 UTC (Thu)
by khim (subscriber, #9252)
[Link] (1 responses)
It all comes down to the original sin: the ability of less-privileged programs to dictate the worldview of more privileged programs. This is fixable (Android, macOS, Windows, some Linux distributions are trying to fix that) but I wonder how much time would it take. Years? Decades?
Posted Aug 5, 2022 16:11 UTC (Fri)
by immibis (subscriber, #105511)
[Link]
Posted Jul 7, 2022 22:58 UTC (Thu)
by Hello71 (subscriber, #103412)
[Link] (6 responses)
Posted Jul 8, 2022 5:13 UTC (Fri)
by matthias (subscriber, #94967)
[Link]
Are you suggesting that if someone calls a suid binary inside a container, the binary should not use the mount namespace of the container but the root mount namespace instead?
Posted Jul 8, 2022 6:35 UTC (Fri)
by neilbrown (subscriber, #359)
[Link]
That's exactly the point I was going to make. bind mounts in private namespaces are perfectly safe. setuid programs as profoundly broken, whether you use namespaces or not.
Posted Jul 8, 2022 10:16 UTC (Fri)
by tialaramex (subscriber, #21167)
[Link] (2 responses)
One of the things I appreciate in Rust is that where there are special cases somebody takes the time to think about whether in fact there's some more general principle of which the special case was just the easy to observe part, the tip of the iceberg so to say, and to provide for the general principle, rather than just the special case.
Example: If you're a Rust beginner you learn that Option's None and Result's Error can be passed back up to your caller where appropriate with the '?' try operator and this seems like a special case, you can't go around treating an integer, or a file handle, or some other kind of thing this way. Or can you? In fact the general principle is the (nightly gated) Try trait, and Option and Result merely implement Try (they're allowed to do this even in stable Rust because Rust internally isn't subject to its own stability rules or it'd be recursively impossible to develop anything)
Another example: In languages with ad hoc polymorphism ("Function overloading") it's obvious that "LWN.net".contains("LWN") and "LWN.net".contains('.') are both reasonable things to write so you just overload the function to do either. Rust doesn't have ad hoc polymorphism, so it must decide what type that parameter is such that both "LWN" and '.' match or else provide two functions with different names. The resulting trait Pattern once again represents a more general principle - any pattern which could match parts of a string, and so in Rust you can also write "LWN.net".contains(char::is_alphabetic) because hey, char::is_alphabetic is a function which matches parts of a string so why not.
I think SUID just isn't one of those things, it's a profoundly special case, and so we should immediately be prejudiced against it as a design feature of the operating system. Rather than everything just falling out naturally, as we'd like for a general solution, SUID means everywhere we need to handle this differently. If you've just written a bunch of low level code there's a good chance that if I remind you that SUID exists you'll need to go back and add a bunch of conditional branches to handle that...
Posted Jul 8, 2022 11:25 UTC (Fri)
by farnz (subscriber, #17727)
[Link] (1 responses)
Another reason to be biased against SUID is that it's a quick solution to the problem of users not having root access to the entire machine.
There are three different ways to run something as root on a Linux-like system (assuming that you've got an ordinary user account):
The first is a non-starter if you're not trusted with root yourself - the coordination to keep someone with root access around is a pain.
The second involves more code. You have to have something running that can make the policy decisions based on a string sent to it, and then execute the process for you. There's also complexity around transferring "enough" environment state to the privileged process, and transferring results back.
The third is easy. Most of your SUID process's state is the same as it would have if it wasn't SUID, except for a few "minor" bits here and there (and this list of things is growing as we find security holes that cannot be fixed except by resetting state).
Ideally, everyone would bother to do the second option for things that need to be privileged - but that's a lot of work, and SUID is a "neat hack" that means you don't need to do it.
Posted Jul 9, 2022 20:19 UTC (Sat)
by NYKevin (subscriber, #129325)
[Link]
Posted Jul 8, 2022 12:32 UTC (Fri)
by hallyn (subscriber, #22558)
[Link]
User namespaces are designed such that this is supposed to not be necessary: you can only mount things if you create a new user namespace, and if you are fully unprivileged, you can only map ns-root to your own or a delegated uid, so you cannot trick host root with bind mounts and a setuid-root binary. The problem with user namespaces comes because user namespaces also want to grant ns-root privilege over the resources owned by the creator. And they do that pretty well, it's just that that expands the amount of kernel code which an unprivileged user can exercise, and exploit.
> privilege escalation should occur via communication with a system daemon using a well-defined protocol
Several people have tried to the plumbing needed for plan-9 factotum functionality into the kernel. My last attempt (expanding on Ashwin Ganti's original code) was 10 years ago - https://lore.kernel.org/all/20100427164139.GA7359@us.ibm.... , and there was a more recent independent patch posted at https://lore.kernel.org/all/20180210165845.18852-1-metux@... .
Posted Jul 12, 2022 8:10 UTC (Tue)
by koverstreet (✭ supporter ✭, #4296)
[Link]
Which is pretty huge.
The trouble with symbolic links
The trouble with symbolic links
The trouble with symbolic links
The trouble with symbolic links
The trouble with symbolic links
The trouble with symbolic links
The trouble with symbolic links
The trouble with symbolic links
If we, collectively, were serious about security, we would be mounting all filesystems with nosuid.
The trouble with symbolic links
The trouble with symbolic links
The trouble with symbolic links
The trouble with symbolic links
The trouble with symbolic links