Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Sep 2, 2015 6:57 AM, "Brian Gerst" wrote: > > On Tue, Sep 1, 2015 at 10:21 PM, Andy Lutomirski wrote: > > On Sep 1, 2015 6:53 PM, "Brian Gerst" wrote: > >> > >> On Tue, Sep 1, 2015 at 8:51 PM, 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. > >> > >> > >> 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 1, 2015 at 10:21 PM, Andy Lutomirski wrote: > On Sep 1, 2015 6:53 PM, "Brian Gerst" wrote: >> >> On Tue, Sep 1, 2015 at 8:51 PM, 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. >> >> >> 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On 2015-09-02 00:32, Andy Lutomirski wrote: On Tue, Sep 1, 2015 at 9:18 PM, Rich Felker 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 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. smime.p7s Description: S/MIME Cryptographic Signature
Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 1, 2015 at 10:21 PM, Andy Lutomirskiwrote: > On Sep 1, 2015 6:53 PM, "Brian Gerst" wrote: >> >> On Tue, Sep 1, 2015 at 8:51 PM, 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. >> >> >> 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Sep 2, 2015 6:57 AM, "Brian Gerst"wrote: > > On Tue, Sep 1, 2015 at 10:21 PM, Andy Lutomirski wrote: > > On Sep 1, 2015 6:53 PM, "Brian Gerst" wrote: > >> > >> On Tue, Sep 1, 2015 at 8:51 PM, 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. > >> > >> > >> 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On 2015-09-02 00:32, Andy Lutomirski wrote: On Tue, Sep 1, 2015 at 9:18 PM, Rich Felkerwrote: On Tue, Sep 01, 2015 at 08:39:27PM -0700, Andy Lutomirski wrote: On Tue, Sep 1, 2015 at 7:54 PM, Rich Felker 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. smime.p7s Description: S/MIME Cryptographic Signature
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 01, 2015 at 10:03:27PM -0700, Andy Lutomirski wrote: > On Tue, Sep 1, 2015 at 9:55 PM, Rich Felker 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 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 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 -- To unsubscribe from this list:
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 1, 2015 at 9:55 PM, Rich Felker 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 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 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 01, 2015 at 09:32:22PM -0700, Andy Lutomirski wrote: > On Tue, Sep 1, 2015 at 9:18 PM, Rich Felker 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 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 1, 2015 at 9:18 PM, Rich Felker 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 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 01, 2015 at 08:39:27PM -0700, Andy Lutomirski wrote: > On Tue, Sep 1, 2015 at 7:54 PM, Rich Felker 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 1, 2015 at 7:54 PM, Rich Felker 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Sep 1, 2015 6:12 PM, "Ian Lance Taylor" wrote: > > On Tue, Sep 1, 2015 at 5:51 PM, Andy Lutomirski 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Sep 1, 2015 6:53 PM, "Brian Gerst" wrote: > > On Tue, Sep 1, 2015 at 8:51 PM, 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. > > > 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 1, 2015 at 8:51 PM, 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. 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 1, 2015 at 5:51 PM, Andy Lutomirski 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 1, 2015 at 5:51 PM, Andy Lutomirskiwrote: > > 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Sep 1, 2015 6:53 PM, "Brian Gerst"wrote: > > On Tue, Sep 1, 2015 at 8:51 PM, 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. > > > 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 1, 2015 at 8:51 PM, Andy Lutomirskiwrote: > 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Sep 1, 2015 6:12 PM, "Ian Lance Taylor"wrote: > > On Tue, Sep 1, 2015 at 5:51 PM, Andy Lutomirski 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 01, 2015 at 09:32:22PM -0700, Andy Lutomirski wrote: > On Tue, Sep 1, 2015 at 9:18 PM, Rich Felkerwrote: > > On Tue, Sep 01, 2015 at 08:39:27PM -0700, Andy Lutomirski wrote: > >> On Tue, Sep 1, 2015 at 7:54 PM, Rich Felker 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 01, 2015 at 10:03:27PM -0700, Andy Lutomirski wrote: > On Tue, Sep 1, 2015 at 9:55 PM, Rich Felkerwrote: > > On Tue, Sep 01, 2015 at 09:32:22PM -0700, Andy Lutomirski wrote: > >> On Tue, Sep 1, 2015 at 9:18 PM, Rich Felker 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 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
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 01, 2015 at 08:39:27PM -0700, Andy Lutomirski wrote: > On Tue, Sep 1, 2015 at 7:54 PM, Rich Felkerwrote: > > 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 1, 2015 at 9:18 PM, Rich Felkerwrote: > On Tue, Sep 01, 2015 at 08:39:27PM -0700, Andy Lutomirski wrote: >> On Tue, Sep 1, 2015 at 7:54 PM, Rich Felker 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 1, 2015 at 9:55 PM, Rich Felkerwrote: > On Tue, Sep 01, 2015 at 09:32:22PM -0700, Andy Lutomirski wrote: >> On Tue, Sep 1, 2015 at 9:18 PM, Rich Felker 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 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?
On Tue, Sep 1, 2015 at 7:54 PM, Rich Felkerwrote: > 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 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/