What's funny is that in this case the dynamic loader was sanitising something irrelevant to the actual capability granted, which seems to me should be a bug.
Also, I'll be an advocate for just starting emacs with systemd, and never worrying about it again.
> What's funny is that in this case the dynamic loader was sanitising something irrelevant to the actual capability granted, which seems to me should be a bug.
EDIT: fixed incorrect description of the yak-shaving conclusion.
The dynamic loader did so because it ran with an extra capability that the user invoking it didn't already have. Most of that sanitizing exists to prevent the user from gaining those privileges themselves by invoking a more privileged program, such as by setting LD_LIBRARY_PATH. Sanitizing TMPDIR prevents a somewhat different class of vulnerabilities, such as using those extra privileges to write to files you normally couldn't. However, I don't think it makes sense to have a complex special case like "if you only have one of this subset of extra privileges, allow TMPDIR but don't allow all the other potentially dangerous environment variables"; that adds a significant amount of complexity and subtlety to already security-sensitive code.
Giving /usr/bin/perl itself extra capabilities effectively grants them to every user on the system, since you can use Perl to run arbitrary code. At that point, it would make more sense to just allow all non-root users to bind to arbitrary ports. I'm somewhat surprised that there isn't a sysctl to disable the reservation of ports 0-1023.
> However, I don't think it makes sense to have a complex special case like "if you only have one of this subset of extra privileges, allow TMPDIR but don't allow all the other potentially dangerous environment variables"; that adds a significant amount of complexity and subtlety to already security-sensitive code.
I think it'd make more sense to have a collection of lockdown functions which are run for each capability, with the action functions run being the union of the collections of each effective capability (with full root just being the union of the collections of all capabilities).
Or, y'know, rethink root in general. Plan 9 had good ideas in this area …
No, it was the dynamic loader that did the sanitizing. Mark said that he thought of Perl's sanitizing, and had ruled it out, and then explicitly said it was the dynamic loader that did the sanitizing in this case.
Thanks for the correction; fixed. I misremembered that bit of the yak-shaving adventure when I went to write my comment.
The conclusion still holds, though: I don't think special-casing particular capabilities makes sense. And in the case of the dynamic linker, it doesn't actually have that information available; it relies on the AT_SECURE bit set in the process's "auxiliary vector" (see "man getauxval"), which the kernel sets when the process has any privilege its caller didn't have.
I have to agree. It seems the vast majority of daemons that run as root only do that to get the special port they want. It made a tiny bit of sense in the days of multi-user systems. Those days are over.
That does something entirely different; see Documentation/networking/ip-sysctl.txt (online version at https://www.kernel.org/doc/Documentation/networking/ip-sysct...). ip_local_port_range sets the range of ports used as source ports for outbound connections that don't bind to a specific port.
I checked for a sysctl controlling the ability to bind to privileged ports before writing my comment. The relevant code in the kernel compares against a hardcoded #define PROT_SOCK 1024, and doesn't have any means to disable that check. See inet_bind in net/ipv4/af_inet.c .
> You can theoretically use tmp to gain any privilege.
Not when you access it as yourself rather than root. The capability in question only grants access to open low ports; there's no way to combine that with files in a temp directory to get root.
Also, I'll be an advocate for just starting emacs with systemd, and never worrying about it again.