Messages in this thread | | | From | Florian Weimer <> | Subject | Re: CET shadow stack app compatibility | Date | Tue, 15 Nov 2022 08:33:39 +0100 |
| |
* Linus Torvalds:
> I'm disgusted by glibc being willing to just upgrade and break > existing binaries and take the "you shouldn't upgrade glibc if you > have old binaries" approach.
We've been in this position for years. Every time we use a new system call to implement existing functionality in glibc, some applications break. Mostly due to seccomp filters. They break even if there would be no observable differences for applictions in the way the new system calls would be invoked if the seccomp filter wouldn't block them.
I proposed a new ENOSYS handshake between userspace and kernel to reduce the amount of breakage (but not all of it). Senior kernel developers rejected it, so we didn't implement it in glibc.
[PATCH] syscalls: Document OCI seccomp filter interactions & workaround <https://lore.kernel.org/linux-api/87lfer2c0b.fsf@oldenburg2.str.redhat.com/>
(It deals with OCI because it's well-documented, but the same principle would have applied to browser sandboxes, too.)
Instead, we work with distributions and upstreams to make sure the applications are ready before the next distribution glibc update. Fortunately, there seems to be a pretty broad overlap between seccomp-using applications and applications with frequent, more-or-less mandatory updates, so the transition periods are relatively short. You didn't seem to have noticed, so maybe we aren't doing such a bad job after all.
I don't see why CET or x86 shadow stack support could not be handled in the same way. (There is probably a similar overlap.) At least we should try how far we can get with the existing binaries, and if things turn out not working after all, we will have to start over with different markers. But the kernel shouldn't have to care.
Based on what we have seen so far (and since fixed), it's mostly shared objects that weren't marked up correctly. The posted hack didn't even deal with that case. If the main executable has the current markers, the kernel will not disable shadow stack, and the process will still crash after loading the incorrectly marked shared object. Someone has to step in and fix things for real (so that they don't break again just after rebuild with a current toolchain adding the current markers). The kernel patch makes this harder because it's not possible anymore to use an existing distribution for this kind of work. Instead, we'd have to wait for a rebuild with the new markers, and of course this rebuild will put is in exactly the same position as before: the incompatibilities will be back because they are no longer masked by the kernel.
Fortunately, we are in a way better situation on x86 than where we are with PAC on AArch64: there you have to reboot with a custom kernel option to disable PAC and restore compatibility with applications. (As far as I know, PAC state isn't process-switched, which I find rather flabbergasting.) Furthermore, the way it was deployed in application and libraries was largely unconditional (hard-coded into hand-written assembly, without preprocessor conditionals to see of PAC was enabled during the build). At least the presence of CET features depends on CET compiler flags, and we can easily turn it off on a per-process basis if there are any incompatibilities.
Thanks, Florian
| |