Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?

2015-09-02 Thread Austin S Hemmelgarn

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: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?

2015-09-02 Thread Austin S Hemmelgarn

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: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?

2015-09-01 Thread Rich Felker
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?

2015-09-01 Thread Andy Lutomirski
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?

2015-09-01 Thread Rich Felker
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?

2015-09-01 Thread Andy Lutomirski
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?

2015-09-01 Thread Rich Felker
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?

2015-09-01 Thread Andy Lutomirski
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?

2015-09-01 Thread Rich Felker
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?

2015-09-01 Thread Rich Felker
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?

2015-09-01 Thread Rich Felker
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?

2015-09-01 Thread Rich Felker
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 

Re: [musl] RFC: adding Linux vsyscall-disable and similar backwards-incompatibility flags to ELF headers?

2015-09-01 Thread Rich Felker
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?

2015-09-01 Thread Andy Lutomirski
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?

2015-09-01 Thread Andy Lutomirski
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?

2015-09-01 Thread Andy Lutomirski
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/