* RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? @ 2015-09-02 0:51 Andy Lutomirski 2015-09-02 1:12 ` Ian Lance Taylor ` (2 more replies) 0 siblings, 3 replies; 15+ messages in thread From: Andy Lutomirski @ 2015-09-02 0:51 UTC (permalink / raw) To: Kees Cook, linux-kernel, libc-alpha, musl, gcc, Binutils Hi all- Linux has a handful of weird features that are only supported for backwards compatibility. The big one is the x86_64 vsyscall page, but uselib probably belongs on the list, too, and we might end up with more at some point. I'd like to add a way that new programs can turn these features off. In particular, I want the vsyscall page to be completely gone from the perspective of any new enough program. This is straightforward if we add a system call to ask for the vsyscall page to be disabled, but I'm wondering if we can come up with a non-syscall way to do it. I think that the ideal behavior would be that anything linked against a sufficiently new libc would be detected, but I don't see a good way to do that using existing toolchain features. Ideas? We could add a new phdr for this, but then we'd need to play linker script games, and I'm not sure that could be done in a clean, extensible way. --Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? 2015-09-02 0:51 RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? Andy Lutomirski @ 2015-09-02 1:12 ` Ian Lance Taylor 2015-09-02 2:23 ` Andy Lutomirski 2015-09-02 1:53 ` Brian Gerst 2015-09-02 2:54 ` [musl] " Rich Felker 2 siblings, 1 reply; 15+ messages in thread From: Ian Lance Taylor @ 2015-09-02 1:12 UTC (permalink / raw) To: Andy Lutomirski Cc: Kees Cook, linux-kernel, libc-alpha, musl, GCC Development, Binutils On Tue, Sep 1, 2015 at 5:51 PM, Andy Lutomirski <luto@amacapital.net> wrote: > > Linux has a handful of weird features that are only supported for > backwards compatibility. The big one is the x86_64 vsyscall page, but > uselib probably belongs on the list, too, and we might end up with > more at some point. > > I'd like to add a way that new programs can turn these features off. > In particular, I want the vsyscall page to be completely gone from the > perspective of any new enough program. This is straightforward if we > add a system call to ask for the vsyscall page to be disabled, but I'm > wondering if we can come up with a non-syscall way to do it. > > I think that the ideal behavior would be that anything linked against > a sufficiently new libc would be detected, but I don't see a good way > to do that using existing toolchain features. > > Ideas? We could add a new phdr for this, but then we'd need to play > linker script games, and I'm not sure that could be done in a clean, > extensible way. What sets up the vsyscall page, and what information does it have before doing so? I'm guessing it's the kernel that sets it up, and that all it can see at that point is the program headers. We could pass information using an appropriate note section. My recollection is that the linkers will turn an SHF_ALLOC note section into a PT_NOTE program header. Ian ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? 2015-09-02 1:12 ` Ian Lance Taylor @ 2015-09-02 2:23 ` Andy Lutomirski 0 siblings, 0 replies; 15+ messages in thread From: Andy Lutomirski @ 2015-09-02 2:23 UTC (permalink / raw) To: Ian Lance Taylor; +Cc: musl, gcc, Kees Cook, libc-alpha, linux-kernel, Binutils On Sep 1, 2015 6:12 PM, "Ian Lance Taylor" <iant@google.com> wrote: > > On Tue, Sep 1, 2015 at 5:51 PM, Andy Lutomirski <luto@amacapital.net> wrote: > > > > Linux has a handful of weird features that are only supported for > > backwards compatibility. The big one is the x86_64 vsyscall page, but > > uselib probably belongs on the list, too, and we might end up with > > more at some point. > > > > I'd like to add a way that new programs can turn these features off. > > In particular, I want the vsyscall page to be completely gone from the > > perspective of any new enough program. This is straightforward if we > > add a system call to ask for the vsyscall page to be disabled, but I'm > > wondering if we can come up with a non-syscall way to do it. > > > > I think that the ideal behavior would be that anything linked against > > a sufficiently new libc would be detected, but I don't see a good way > > to do that using existing toolchain features. > > > > Ideas? We could add a new phdr for this, but then we'd need to play > > linker script games, and I'm not sure that could be done in a clean, > > extensible way. > > What sets up the vsyscall page, and what information does it have > before doing so? > > I'm guessing it's the kernel that sets it up, and that all it can see > at that point is the program headers. Currently it's global and nothing thinks about it per-process at all. The kernel can do whatever it likes going forward, subject to backwards compatibility. Doing something at ELF load time is probably the right approach. > > We could pass information using an appropriate note section. My > recollection is that the linkers will turn an SHF_ALLOC note section > into a PT_NOTE program header. Oh, interesting. I'll check that. Glibc and competitors could add notes to their statically-linked bits. The unpleasant case is a new dynamic binary linked against an old libc, but that might be irrelevant in practice. After all, I think that a lot of libc competitors never supported the vsyscall page at all, and even glibc isn't really backwards compatible that way. We could also require that both the binary and interpreter have the note, which would more or less solve the backwards compatibility issue. --Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? 2015-09-02 0:51 RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? Andy Lutomirski 2015-09-02 1:12 ` Ian Lance Taylor @ 2015-09-02 1:53 ` Brian Gerst 2015-09-02 2:21 ` Andy Lutomirski 2015-09-02 2:54 ` [musl] " Rich Felker 2 siblings, 1 reply; 15+ messages in thread From: Brian Gerst @ 2015-09-02 1:53 UTC (permalink / raw) To: Andy Lutomirski; +Cc: Kees Cook, linux-kernel, libc-alpha, musl, gcc, Binutils On Tue, Sep 1, 2015 at 8:51 PM, Andy Lutomirski <luto@amacapital.net> wrote: > Hi all- > > Linux has a handful of weird features that are only supported for > backwards compatibility. The big one is the x86_64 vsyscall page, but > uselib probably belongs on the list, too, and we might end up with > more at some point. > > I'd like to add a way that new programs can turn these features off. > In particular, I want the vsyscall page to be completely gone from the > perspective of any new enough program. This is straightforward if we > add a system call to ask for the vsyscall page to be disabled, but I'm > wondering if we can come up with a non-syscall way to do it. > > I think that the ideal behavior would be that anything linked against > a sufficiently new libc would be detected, but I don't see a good way > to do that using existing toolchain features. > > Ideas? We could add a new phdr for this, but then we'd need to play > linker script games, and I'm not sure that could be done in a clean, > extensible way. The vsyscall page is mapped in the fixmap region, which is shared between all processes. You can't turn it off for an individual process. -- Brian Gerst ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? 2015-09-02 1:53 ` Brian Gerst @ 2015-09-02 2:21 ` Andy Lutomirski 2015-09-02 13:57 ` Brian Gerst 0 siblings, 1 reply; 15+ messages in thread From: Andy Lutomirski @ 2015-09-02 2:21 UTC (permalink / raw) To: Brian Gerst; +Cc: musl, Kees Cook, gcc, libc-alpha, linux-kernel, Binutils On Sep 1, 2015 6:53 PM, "Brian Gerst" <brgerst@gmail.com> wrote: > > On Tue, Sep 1, 2015 at 8:51 PM, Andy Lutomirski <luto@amacapital.net> wrote: > > Hi all- > > > > Linux has a handful of weird features that are only supported for > > backwards compatibility. The big one is the x86_64 vsyscall page, but > > uselib probably belongs on the list, too, and we might end up with > > more at some point. > > > > I'd like to add a way that new programs can turn these features off. > > In particular, I want the vsyscall page to be completely gone from the > > perspective of any new enough program. This is straightforward if we > > add a system call to ask for the vsyscall page to be disabled, but I'm > > wondering if we can come up with a non-syscall way to do it. > > > > I think that the ideal behavior would be that anything linked against > > a sufficiently new libc would be detected, but I don't see a good way > > to do that using existing toolchain features. > > > > Ideas? We could add a new phdr for this, but then we'd need to play > > linker script games, and I'm not sure that could be done in a clean, > > extensible way. > > > The vsyscall page is mapped in the fixmap region, which is shared > between all processes. You can't turn it off for an individual > process. Why not? We already emulate all attempts to execute it, and that's trivial to turn of per process. Project Zero pointed out that read access is a problem, too, but we can flip the U/S bit in the pgd once we evict pvclock from the fixmap. And we definitely need to evict pvclock from the fixmap regardless. --Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? 2015-09-02 2:21 ` Andy Lutomirski @ 2015-09-02 13:57 ` Brian Gerst 2015-09-02 14:08 ` Andy Lutomirski 0 siblings, 1 reply; 15+ messages in thread From: Brian Gerst @ 2015-09-02 13:57 UTC (permalink / raw) To: Andy Lutomirski; +Cc: musl, Kees Cook, gcc, libc-alpha, linux-kernel, Binutils On Tue, Sep 1, 2015 at 10:21 PM, Andy Lutomirski <luto@amacapital.net> wrote: > On Sep 1, 2015 6:53 PM, "Brian Gerst" <brgerst@gmail.com> wrote: >> >> On Tue, Sep 1, 2015 at 8:51 PM, Andy Lutomirski <luto@amacapital.net> wrote: >> > Hi all- >> > >> > Linux has a handful of weird features that are only supported for >> > backwards compatibility. The big one is the x86_64 vsyscall page, but >> > uselib probably belongs on the list, too, and we might end up with >> > more at some point. >> > >> > I'd like to add a way that new programs can turn these features off. >> > In particular, I want the vsyscall page to be completely gone from the >> > perspective of any new enough program. This is straightforward if we >> > add a system call to ask for the vsyscall page to be disabled, but I'm >> > wondering if we can come up with a non-syscall way to do it. >> > >> > I think that the ideal behavior would be that anything linked against >> > a sufficiently new libc would be detected, but I don't see a good way >> > to do that using existing toolchain features. >> > >> > Ideas? We could add a new phdr for this, but then we'd need to play >> > linker script games, and I'm not sure that could be done in a clean, >> > extensible way. >> >> >> The vsyscall page is mapped in the fixmap region, which is shared >> between all processes. You can't turn it off for an individual >> process. > > Why not? > > We already emulate all attempts to execute it, and that's trivial to > turn of per process. Project Zero pointed out that read access is a > problem, too, but we can flip the U/S bit in the pgd once we evict > pvclock from the fixmap. > > And we definitely need to evict pvclock from the fixmap regardless. Sure, you can turn off emulation per-process. But the page mapping will be the same for every process because it is in the kernel part of the page tables which is shared by all processes. -- Brian Gerst ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? 2015-09-02 13:57 ` Brian Gerst @ 2015-09-02 14:08 ` Andy Lutomirski 0 siblings, 0 replies; 15+ messages in thread From: Andy Lutomirski @ 2015-09-02 14:08 UTC (permalink / raw) To: Brian Gerst; +Cc: musl, Kees Cook, libc-alpha, gcc, linux-kernel, Binutils On Sep 2, 2015 6:57 AM, "Brian Gerst" <brgerst@gmail.com> wrote: > > On Tue, Sep 1, 2015 at 10:21 PM, Andy Lutomirski <luto@amacapital.net> wrote: > > On Sep 1, 2015 6:53 PM, "Brian Gerst" <brgerst@gmail.com> wrote: > >> > >> On Tue, Sep 1, 2015 at 8:51 PM, Andy Lutomirski <luto@amacapital.net> wrote: > >> > Hi all- > >> > > >> > Linux has a handful of weird features that are only supported for > >> > backwards compatibility. The big one is the x86_64 vsyscall page, but > >> > uselib probably belongs on the list, too, and we might end up with > >> > more at some point. > >> > > >> > I'd like to add a way that new programs can turn these features off. > >> > In particular, I want the vsyscall page to be completely gone from the > >> > perspective of any new enough program. This is straightforward if we > >> > add a system call to ask for the vsyscall page to be disabled, but I'm > >> > wondering if we can come up with a non-syscall way to do it. > >> > > >> > I think that the ideal behavior would be that anything linked against > >> > a sufficiently new libc would be detected, but I don't see a good way > >> > to do that using existing toolchain features. > >> > > >> > Ideas? We could add a new phdr for this, but then we'd need to play > >> > linker script games, and I'm not sure that could be done in a clean, > >> > extensible way. > >> > >> > >> The vsyscall page is mapped in the fixmap region, which is shared > >> between all processes. You can't turn it off for an individual > >> process. > > > > Why not? > > > > We already emulate all attempts to execute it, and that's trivial to > > turn of per process. Project Zero pointed out that read access is a > > problem, too, but we can flip the U/S bit in the pgd once we evict > > pvclock from the fixmap. > > > > And we definitely need to evict pvclock from the fixmap regardless. > > > Sure, you can turn off emulation per-process. But the page mapping > will be the same for every process because it is in the kernel part of > the page tables which is shared by all processes. True, but I don't think that means that the mapping has to be readable in all processes. Once it's the only user-readable mapping in the top 512 GB, we can turn off user access to the whole top 512 GB. The only other user accessible thing in the top 512GB (and the only other user accessible thing in a kernel address at all) is the KVM pvclock mapping. We should turn that off, too, because it's exploitable in more or less the same way as the vsyscall page. --Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? 2015-09-02 0:51 RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? Andy Lutomirski 2015-09-02 1:12 ` Ian Lance Taylor 2015-09-02 1:53 ` Brian Gerst @ 2015-09-02 2:54 ` Rich Felker 2015-09-02 3:39 ` Andy Lutomirski 2 siblings, 1 reply; 15+ messages in thread From: Rich Felker @ 2015-09-02 2:54 UTC (permalink / raw) To: Andy Lutomirski; +Cc: Kees Cook, linux-kernel, libc-alpha, musl, gcc, Binutils On Tue, Sep 01, 2015 at 05:51:44PM -0700, Andy Lutomirski wrote: > Hi all- > > Linux has a handful of weird features that are only supported for > backwards compatibility. The big one is the x86_64 vsyscall page, but > uselib probably belongs on the list, too, and we might end up with > more at some point. > > I'd like to add a way that new programs can turn these features off. > In particular, I want the vsyscall page to be completely gone from the > perspective of any new enough program. This is straightforward if we > add a system call to ask for the vsyscall page to be disabled, but I'm > wondering if we can come up with a non-syscall way to do it. > > I think that the ideal behavior would be that anything linked against > a sufficiently new libc would be detected, but I don't see a good way > to do that using existing toolchain features. > > Ideas? We could add a new phdr for this, but then we'd need to play > linker script games, and I'm not sure that could be done in a clean, > extensible way. Is there a practical problem you're trying to solve? My understanding is that the vsyscall nonsense is fully emulated now and that the ways it could be used as an attack vector have been mitigated. If this is not the case, I have what sounds like an elegant solution, if it works: presumably affected versions of glibc that used this used it for all syscalls, so if the process has made any normal syscalls before using the vsyscall addresses, you can assume it's a bug/attack and and just raise SIGSEGV. If there are corner cases this doesn't cover, maybe the approach can still be adapted to work; it's cleaner than introducing header cruft, IMO. Rich ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? 2015-09-02 2:54 ` [musl] " Rich Felker @ 2015-09-02 3:39 ` Andy Lutomirski 2015-09-02 4:18 ` Rich Felker 0 siblings, 1 reply; 15+ messages in thread From: Andy Lutomirski @ 2015-09-02 3:39 UTC (permalink / raw) To: Rich Felker; +Cc: Kees Cook, linux-kernel, libc-alpha, musl, gcc, Binutils On Tue, Sep 1, 2015 at 7:54 PM, Rich Felker <dalias@libc.org> wrote: > On Tue, Sep 01, 2015 at 05:51:44PM -0700, Andy Lutomirski wrote: >> Hi all- >> >> Linux has a handful of weird features that are only supported for >> backwards compatibility. The big one is the x86_64 vsyscall page, but >> uselib probably belongs on the list, too, and we might end up with >> more at some point. >> >> I'd like to add a way that new programs can turn these features off. >> In particular, I want the vsyscall page to be completely gone from the >> perspective of any new enough program. This is straightforward if we >> add a system call to ask for the vsyscall page to be disabled, but I'm >> wondering if we can come up with a non-syscall way to do it. >> >> I think that the ideal behavior would be that anything linked against >> a sufficiently new libc would be detected, but I don't see a good way >> to do that using existing toolchain features. >> >> Ideas? We could add a new phdr for this, but then we'd need to play >> linker script games, and I'm not sure that could be done in a clean, >> extensible way. > > Is there a practical problem you're trying to solve? My understanding > is that the vsyscall nonsense is fully emulated now and that the ways > it could be used as an attack vector have been mitigated. They've been mostly mitigated, but not fully. See: http://googleprojectzero.blogspot.com/2015/08/three-bypasses-and-fix-for-one-of.html I'm also waiting for someone to find an exploit that uses one of the vsyscalls as a ROP gadget. > > If this is not the case, I have what sounds like an elegant solution, > if it works: presumably affected versions of glibc that used this used > it for all syscalls, so if the process has made any normal syscalls > before using the vsyscall addresses, you can assume it's a bug/attack > and and just raise SIGSEGV. If there are corner cases this doesn't > cover, maybe the approach can still be adapted to work; it's cleaner > than introducing header cruft, IMO. Unfortunately, I don't think this will work. It's never been possible to use the vsyscalls for anything other than gettimeofday, time, or getcpu, so I doubt we can detect affected glibc versions that way. --Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? 2015-09-02 3:39 ` Andy Lutomirski @ 2015-09-02 4:18 ` Rich Felker 2015-09-02 4:32 ` Andy Lutomirski 0 siblings, 1 reply; 15+ messages in thread From: Rich Felker @ 2015-09-02 4:18 UTC (permalink / raw) To: Andy Lutomirski; +Cc: Kees Cook, linux-kernel, libc-alpha, musl, gcc, Binutils On Tue, Sep 01, 2015 at 08:39:27PM -0700, Andy Lutomirski wrote: > On Tue, Sep 1, 2015 at 7:54 PM, Rich Felker <dalias@libc.org> wrote: > > On Tue, Sep 01, 2015 at 05:51:44PM -0700, Andy Lutomirski wrote: > >> Hi all- > >> > >> Linux has a handful of weird features that are only supported for > >> backwards compatibility. The big one is the x86_64 vsyscall page, but > >> uselib probably belongs on the list, too, and we might end up with > >> more at some point. > >> > >> I'd like to add a way that new programs can turn these features off. > >> In particular, I want the vsyscall page to be completely gone from the > >> perspective of any new enough program. This is straightforward if we > >> add a system call to ask for the vsyscall page to be disabled, but I'm > >> wondering if we can come up with a non-syscall way to do it. > >> > >> I think that the ideal behavior would be that anything linked against > >> a sufficiently new libc would be detected, but I don't see a good way > >> to do that using existing toolchain features. > >> > >> Ideas? We could add a new phdr for this, but then we'd need to play > >> linker script games, and I'm not sure that could be done in a clean, > >> extensible way. > > > > Is there a practical problem you're trying to solve? My understanding > > is that the vsyscall nonsense is fully emulated now and that the ways > > it could be used as an attack vector have been mitigated. > > They've been mostly mitigated, but not fully. See: > > http://googleprojectzero.blogspot.com/2015/08/three-bypasses-and-fix-for-one-of.html That looks like it would be mitigated by not having any mapping there at all and having the kernel just catch the page fault and emulate rather than filling it with trapping opcodes for the kernel to catch. > I'm also waiting for someone to find an exploit that uses one of the > vsyscalls as a ROP gadget. This sounds more plausible. gettimeofday actually writes to memory pointed to by its arguments. The others look benign. > > If this is not the case, I have what sounds like an elegant solution, > > if it works: presumably affected versions of glibc that used this used > > it for all syscalls, so if the process has made any normal syscalls > > before using the vsyscall addresses, you can assume it's a bug/attack > > and and just raise SIGSEGV. If there are corner cases this doesn't > > cover, maybe the approach can still be adapted to work; it's cleaner > > than introducing header cruft, IMO. > > Unfortunately, I don't think this will work. It's never been possible > to use the vsyscalls for anything other than gettimeofday, time, or > getcpu, so I doubt we can detect affected glibc versions that way. I thought the idea of the old vsyscall was that you always call it rather than using a syscall instruction and it decides whether it can do it in userspace or needs to make a real syscall. But if it was only called from certain places, then yes, I think you're right that my approach doesn't work. Rich ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? 2015-09-02 4:18 ` Rich Felker @ 2015-09-02 4:32 ` Andy Lutomirski 2015-09-02 4:55 ` Rich Felker 2015-09-02 12:48 ` Austin S Hemmelgarn 0 siblings, 2 replies; 15+ messages in thread From: Andy Lutomirski @ 2015-09-02 4:32 UTC (permalink / raw) To: Rich Felker; +Cc: Kees Cook, linux-kernel, libc-alpha, musl, gcc, Binutils On Tue, Sep 1, 2015 at 9:18 PM, Rich Felker <dalias@libc.org> wrote: > On Tue, Sep 01, 2015 at 08:39:27PM -0700, Andy Lutomirski wrote: >> On Tue, Sep 1, 2015 at 7:54 PM, Rich Felker <dalias@libc.org> wrote: >> > On Tue, Sep 01, 2015 at 05:51:44PM -0700, Andy Lutomirski wrote: >> >> Hi all- >> >> >> >> Linux has a handful of weird features that are only supported for >> >> backwards compatibility. The big one is the x86_64 vsyscall page, but >> >> uselib probably belongs on the list, too, and we might end up with >> >> more at some point. >> >> >> >> I'd like to add a way that new programs can turn these features off. >> >> In particular, I want the vsyscall page to be completely gone from the >> >> perspective of any new enough program. This is straightforward if we >> >> add a system call to ask for the vsyscall page to be disabled, but I'm >> >> wondering if we can come up with a non-syscall way to do it. >> >> >> >> I think that the ideal behavior would be that anything linked against >> >> a sufficiently new libc would be detected, but I don't see a good way >> >> to do that using existing toolchain features. >> >> >> >> Ideas? We could add a new phdr for this, but then we'd need to play >> >> linker script games, and I'm not sure that could be done in a clean, >> >> extensible way. >> > >> > Is there a practical problem you're trying to solve? My understanding >> > is that the vsyscall nonsense is fully emulated now and that the ways >> > it could be used as an attack vector have been mitigated. >> >> They've been mostly mitigated, but not fully. See: >> >> http://googleprojectzero.blogspot.com/2015/08/three-bypasses-and-fix-for-one-of.html > > That looks like it would be mitigated by not having any mapping there > at all and having the kernel just catch the page fault and emulate > rather than filling it with trapping opcodes for the kernel to catch. > Oddly, that causes a compatibility problem. There's a program called pin that does dynamic instrumentation and actually expects to be able to read the targets of calls. The way that Linux handles this now is to put a literal mov $NR, %rax; syscall; ret sequence at the syscall address but to mark the whole page NX so that any attempt to call it traps. The trap gets fixed up if the call looks valid (properly aligned, etc) and the process gets SIGSEGV if not. This caught me by surprise when I implemented vsyscall emulation the first time. >> I'm also waiting for someone to find an exploit that uses one of the >> vsyscalls as a ROP gadget. > > This sounds more plausible. gettimeofday actually writes to memory > pointed to by its arguments. The others look benign. > >> > If this is not the case, I have what sounds like an elegant solution, >> > if it works: presumably affected versions of glibc that used this used >> > it for all syscalls, so if the process has made any normal syscalls >> > before using the vsyscall addresses, you can assume it's a bug/attack >> > and and just raise SIGSEGV. If there are corner cases this doesn't >> > cover, maybe the approach can still be adapted to work; it's cleaner >> > than introducing header cruft, IMO. >> >> Unfortunately, I don't think this will work. It's never been possible >> to use the vsyscalls for anything other than gettimeofday, time, or >> getcpu, so I doubt we can detect affected glibc versions that way. > > I thought the idea of the old vsyscall was that you always call it > rather than using a syscall instruction and it decides whether it can > do it in userspace or needs to make a real syscall. But if it was only > called from certain places, then yes, I think you're right that my > approach doesn't work. No, it's actually just three separate functions, one for each of gettimeofday, time, and getcpu. --Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? 2015-09-02 4:32 ` Andy Lutomirski @ 2015-09-02 4:55 ` Rich Felker 2015-09-02 5:03 ` Andy Lutomirski 2015-09-02 12:48 ` Austin S Hemmelgarn 1 sibling, 1 reply; 15+ messages in thread From: Rich Felker @ 2015-09-02 4:55 UTC (permalink / raw) To: Andy Lutomirski; +Cc: Kees Cook, linux-kernel, libc-alpha, musl, gcc, Binutils On Tue, Sep 01, 2015 at 09:32:22PM -0700, Andy Lutomirski wrote: > On Tue, Sep 1, 2015 at 9:18 PM, Rich Felker <dalias@libc.org> wrote: > > On Tue, Sep 01, 2015 at 08:39:27PM -0700, Andy Lutomirski wrote: > >> On Tue, Sep 1, 2015 at 7:54 PM, Rich Felker <dalias@libc.org> wrote: > >> > On Tue, Sep 01, 2015 at 05:51:44PM -0700, Andy Lutomirski wrote: > >> >> Hi all- > >> >> > >> >> Linux has a handful of weird features that are only supported for > >> >> backwards compatibility. The big one is the x86_64 vsyscall page, but > >> >> uselib probably belongs on the list, too, and we might end up with > >> >> more at some point. > >> >> > >> >> I'd like to add a way that new programs can turn these features off. > >> >> In particular, I want the vsyscall page to be completely gone from the > >> >> perspective of any new enough program. This is straightforward if we > >> >> add a system call to ask for the vsyscall page to be disabled, but I'm > >> >> wondering if we can come up with a non-syscall way to do it. > >> >> > >> >> I think that the ideal behavior would be that anything linked against > >> >> a sufficiently new libc would be detected, but I don't see a good way > >> >> to do that using existing toolchain features. > >> >> > >> >> Ideas? We could add a new phdr for this, but then we'd need to play > >> >> linker script games, and I'm not sure that could be done in a clean, > >> >> extensible way. > >> > > >> > Is there a practical problem you're trying to solve? My understanding > >> > is that the vsyscall nonsense is fully emulated now and that the ways > >> > it could be used as an attack vector have been mitigated. > >> > >> They've been mostly mitigated, but not fully. See: > >> > >> http://googleprojectzero.blogspot.com/2015/08/three-bypasses-and-fix-for-one-of.html > > > > That looks like it would be mitigated by not having any mapping there > > at all and having the kernel just catch the page fault and emulate > > rather than filling it with trapping opcodes for the kernel to catch. > > > > Oddly, that causes a compatibility problem. There's a program called > pin that does dynamic instrumentation and actually expects to be able > to read the targets of calls. The way that Linux handles this now is Um, do people seriously need to do this dynamic instrumentation on ancient obsolete binaries? This sounds to me like confused requirements. Rich ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? 2015-09-02 4:55 ` Rich Felker @ 2015-09-02 5:03 ` Andy Lutomirski 2015-09-02 5:22 ` Rich Felker 0 siblings, 1 reply; 15+ messages in thread From: Andy Lutomirski @ 2015-09-02 5:03 UTC (permalink / raw) To: Rich Felker; +Cc: Kees Cook, linux-kernel, libc-alpha, musl, gcc, Binutils On Tue, Sep 1, 2015 at 9:55 PM, Rich Felker <dalias@libc.org> wrote: > On Tue, Sep 01, 2015 at 09:32:22PM -0700, Andy Lutomirski wrote: >> On Tue, Sep 1, 2015 at 9:18 PM, Rich Felker <dalias@libc.org> wrote: >> > On Tue, Sep 01, 2015 at 08:39:27PM -0700, Andy Lutomirski wrote: >> >> On Tue, Sep 1, 2015 at 7:54 PM, Rich Felker <dalias@libc.org> wrote: >> >> > On Tue, Sep 01, 2015 at 05:51:44PM -0700, Andy Lutomirski wrote: >> >> >> Hi all- >> >> >> >> >> >> Linux has a handful of weird features that are only supported for >> >> >> backwards compatibility. The big one is the x86_64 vsyscall page, but >> >> >> uselib probably belongs on the list, too, and we might end up with >> >> >> more at some point. >> >> >> >> >> >> I'd like to add a way that new programs can turn these features off. >> >> >> In particular, I want the vsyscall page to be completely gone from the >> >> >> perspective of any new enough program. This is straightforward if we >> >> >> add a system call to ask for the vsyscall page to be disabled, but I'm >> >> >> wondering if we can come up with a non-syscall way to do it. >> >> >> >> >> >> I think that the ideal behavior would be that anything linked against >> >> >> a sufficiently new libc would be detected, but I don't see a good way >> >> >> to do that using existing toolchain features. >> >> >> >> >> >> Ideas? We could add a new phdr for this, but then we'd need to play >> >> >> linker script games, and I'm not sure that could be done in a clean, >> >> >> extensible way. >> >> > >> >> > Is there a practical problem you're trying to solve? My understanding >> >> > is that the vsyscall nonsense is fully emulated now and that the ways >> >> > it could be used as an attack vector have been mitigated. >> >> >> >> They've been mostly mitigated, but not fully. See: >> >> >> >> http://googleprojectzero.blogspot.com/2015/08/three-bypasses-and-fix-for-one-of.html >> > >> > That looks like it would be mitigated by not having any mapping there >> > at all and having the kernel just catch the page fault and emulate >> > rather than filling it with trapping opcodes for the kernel to catch. >> > >> >> Oddly, that causes a compatibility problem. There's a program called >> pin that does dynamic instrumentation and actually expects to be able >> to read the targets of calls. The way that Linux handles this now is > > Um, do people seriously need to do this dynamic instrumentation on > ancient obsolete binaries? This sounds to me like confused > requirements. Unclear. They certainly did, and I got a bug report, the first time around. That was a couple years ago. I suppose we could have a sysctl that you need to set to enable that use case. OTOH, I think that, as long as we have a way to distinguish new and old binaries, it's not that much harder to twiddle vsyscall readability per process than it is to twiddle vsyscall executability per process. --Andy ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? 2015-09-02 5:03 ` Andy Lutomirski @ 2015-09-02 5:22 ` Rich Felker 0 siblings, 0 replies; 15+ messages in thread From: Rich Felker @ 2015-09-02 5:22 UTC (permalink / raw) To: Andy Lutomirski; +Cc: Kees Cook, linux-kernel, libc-alpha, musl, gcc, Binutils On Tue, Sep 01, 2015 at 10:03:27PM -0700, Andy Lutomirski wrote: > On Tue, Sep 1, 2015 at 9:55 PM, Rich Felker <dalias@libc.org> wrote: > > On Tue, Sep 01, 2015 at 09:32:22PM -0700, Andy Lutomirski wrote: > >> On Tue, Sep 1, 2015 at 9:18 PM, Rich Felker <dalias@libc.org> wrote: > >> > On Tue, Sep 01, 2015 at 08:39:27PM -0700, Andy Lutomirski wrote: > >> >> On Tue, Sep 1, 2015 at 7:54 PM, Rich Felker <dalias@libc.org> wrote: > >> >> > On Tue, Sep 01, 2015 at 05:51:44PM -0700, Andy Lutomirski wrote: > >> >> >> Hi all- > >> >> >> > >> >> >> Linux has a handful of weird features that are only supported for > >> >> >> backwards compatibility. The big one is the x86_64 vsyscall page, but > >> >> >> uselib probably belongs on the list, too, and we might end up with > >> >> >> more at some point. > >> >> >> > >> >> >> I'd like to add a way that new programs can turn these features off. > >> >> >> In particular, I want the vsyscall page to be completely gone from the > >> >> >> perspective of any new enough program. This is straightforward if we > >> >> >> add a system call to ask for the vsyscall page to be disabled, but I'm > >> >> >> wondering if we can come up with a non-syscall way to do it. > >> >> >> > >> >> >> I think that the ideal behavior would be that anything linked against > >> >> >> a sufficiently new libc would be detected, but I don't see a good way > >> >> >> to do that using existing toolchain features. > >> >> >> > >> >> >> Ideas? We could add a new phdr for this, but then we'd need to play > >> >> >> linker script games, and I'm not sure that could be done in a clean, > >> >> >> extensible way. > >> >> > > >> >> > Is there a practical problem you're trying to solve? My understanding > >> >> > is that the vsyscall nonsense is fully emulated now and that the ways > >> >> > it could be used as an attack vector have been mitigated. > >> >> > >> >> They've been mostly mitigated, but not fully. See: > >> >> > >> >> http://googleprojectzero.blogspot.com/2015/08/three-bypasses-and-fix-for-one-of.html > >> > > >> > That looks like it would be mitigated by not having any mapping there > >> > at all and having the kernel just catch the page fault and emulate > >> > rather than filling it with trapping opcodes for the kernel to catch. > >> > > >> > >> Oddly, that causes a compatibility problem. There's a program called > >> pin that does dynamic instrumentation and actually expects to be able > >> to read the targets of calls. The way that Linux handles this now is > > > > Um, do people seriously need to do this dynamic instrumentation on > > ancient obsolete binaries? This sounds to me like confused > > requirements. > > Unclear. They certainly did, and I got a bug report, the first time > around. That was a couple years ago. > > I suppose we could have a sysctl that you need to set to enable that > use case. OTOH, I think that, as long as we have a way to distinguish > new and old binaries, it's not that much harder to twiddle vsyscall > readability per process than it is to twiddle vsyscall executability > per process. But we don't have a (reasonable) way to distinguish new and old binaries, at least not at the right point in history. If we're adding a new header or whatnot, only bleeding-edge binaries will benefit from it. All existing binaries from the past N years that don't need the vsyscall nonsense will still get it unnecessarily, and still be subject to the risks. This has me wondering if there's any point in trying to solve the problem on the granularity of individual programs. Users running all-new binaries (that would benefit from a header flag) can just remove vsyscall support entirely from their kernels. Users with a mix binaries of various ages will likely still have the vsyscall risk in most programs, _including_ many newer binaries that have no use for vsyscall but lack the new header. BTW, since the only calls to vsyscall are from glibc, it seems to me that the only ways vsyscall can be needed are: 1. The user is running old glibc, in which case all dynamic-linked programs need it. 2. The user is running old static-linked glibc binaries. Almost nobody does this. During the era of vsyscall, static linking was all but deprecated. 3. The user is running old binaries using a custom library path with old glibc in it. This is almost certainly just a bogus setup since glibc's symbol versioning is supposed to make old binaries run fine with a newer libc.so. None of these seem to be use cases that we should be engineering complex solutions for. For case 1, the solution wouldn't help anyway since all programs need vsyscall. For cases 2 and 3, if the user wants to harden their system so that newer binaries are not affected by vsyscall, they should just remove vsyscall and fix their old binaries/libraries. In case 2, in particular, you can assume the ability to re-link with an updated glibc; otherwise, there's an LGPL violation going on. Rich ^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? 2015-09-02 4:32 ` Andy Lutomirski 2015-09-02 4:55 ` Rich Felker @ 2015-09-02 12:48 ` Austin S Hemmelgarn 1 sibling, 0 replies; 15+ messages in thread From: Austin S Hemmelgarn @ 2015-09-02 12:48 UTC (permalink / raw) To: Andy Lutomirski, Rich Felker Cc: Kees Cook, linux-kernel, libc-alpha, musl, gcc, Binutils [-- Attachment #1: Type: text/plain, Size: 1645 bytes --] On 2015-09-02 00:32, Andy Lutomirski wrote: > On Tue, Sep 1, 2015 at 9:18 PM, Rich Felker <dalias@libc.org> wrote: >> On Tue, Sep 01, 2015 at 08:39:27PM -0700, Andy Lutomirski wrote: >>> On Tue, Sep 1, 2015 at 7:54 PM, Rich Felker <dalias@libc.org> wrote: >>>> If this is not the case, I have what sounds like an elegant solution, >>>> if it works: presumably affected versions of glibc that used this used >>>> it for all syscalls, so if the process has made any normal syscalls >>>> before using the vsyscall addresses, you can assume it's a bug/attack >>>> and and just raise SIGSEGV. If there are corner cases this doesn't >>>> cover, maybe the approach can still be adapted to work; it's cleaner >>>> than introducing header cruft, IMO. >>> >>> Unfortunately, I don't think this will work. It's never been possible >>> to use the vsyscalls for anything other than gettimeofday, time, or >>> getcpu, so I doubt we can detect affected glibc versions that way. >> >> I thought the idea of the old vsyscall was that you always call it >> rather than using a syscall instruction and it decides whether it can >> do it in userspace or needs to make a real syscall. But if it was only >> called from certain places, then yes, I think you're right that my >> approach doesn't work. > > No, it's actually just three separate functions, one for each of > gettimeofday, time, and getcpu. Did the old versions of glibc always use vsyscall calling for these syscalls? If they did, then we could (probably) safely disable the vsyscall stuff the first time we see any of these called through the normal syscall paths. [-- Attachment #2: S/MIME Cryptographic Signature --] [-- Type: application/pkcs7-signature, Size: 3019 bytes --] ^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2015-09-02 14:08 UTC | newest] Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2015-09-02 0:51 RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers? Andy Lutomirski 2015-09-02 1:12 ` Ian Lance Taylor 2015-09-02 2:23 ` Andy Lutomirski 2015-09-02 1:53 ` Brian Gerst 2015-09-02 2:21 ` Andy Lutomirski 2015-09-02 13:57 ` Brian Gerst 2015-09-02 14:08 ` Andy Lutomirski 2015-09-02 2:54 ` [musl] " Rich Felker 2015-09-02 3:39 ` Andy Lutomirski 2015-09-02 4:18 ` Rich Felker 2015-09-02 4:32 ` Andy Lutomirski 2015-09-02 4:55 ` Rich Felker 2015-09-02 5:03 ` Andy Lutomirski 2015-09-02 5:22 ` Rich Felker 2015-09-02 12:48 ` Austin S Hemmelgarn
Code repositories for project(s) associated with this public inbox https://git.vuxu.org/mirror/musl/ This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).