2013-10-23 21:02:26

by Andy Lutomirski

[permalink] [raw]
Subject: ARM seccomp filters and EABI/OABI

I'm looking at the seccomp code, the ARM entry code, and the
syscall(2) manpage, and I'm a bit lost. (The fact that I don't really
speak ARM assembly doesn't help.) My basic question is: what happens
if an OABI syscall happens?

AFAICS, the syscall arguments for EABI are r0..r5, although their
ordering is a bit odd*. For OABI, r6 seems to play some role, but I'm
lost as to what it is. The seccomp_bpf_load function won't load r6,
so there had better not be anything useful in there... (Also, struct
seccomp_data will have issues with a seventh "argument".)

But what happens to the syscall number? For an EABI syscall, it's in
r7. For an OABI syscall, it's in the swi instruction and gets copied
to r7 on entry. If a debugger changes r7, presumably the syscall
number changes.

Oddly, there are two different syscall tables. The major differences
seem to be that some of the OABI entries have their argument order
changed. But there's also a magic constant 0x900000 added to the
syscall number somewhere -- is it reflected in _sigsys._syscall? Is
it reflected in ucontext's r7?

I'm a bit surprised to see that both the EABI and OABI ABIs show up as
AUDIT_ARCH_ARM.

Can any of you shed some light on this? I don't have an ARM system I
can test on, but if one of you can point me at a decent QEMU image, I
can play around.

For reference, I'm working on userspace code to decode a TRAP and
eventually to allow syscall emulation (either by emulating the syscall
inside the signal handler and setting the return value or (egads!) by
changing the syscall and restarting it -- the latter is probably
impossible if the original syscall came in through OABI and may be
generally impossible if userspace expects any of the argument
registers to be preserved).


* I think that a syscall with signature long func(int a, long long b,
int c, int d, int e) ends up with c in r1 and b in r2/r3. The
syscall(2) manpage appears to be entirely wrong.


2013-10-24 19:11:34

by Paul Moore

[permalink] [raw]
Subject: Re: [libseccomp-discuss] ARM seccomp filters and EABI/OABI

On Wednesday, October 23, 2013 02:02:00 PM Andy Lutomirski wrote:
> I'm looking at the seccomp code, the ARM entry code, and the
> syscall(2) manpage, and I'm a bit lost. (The fact that I don't really
> speak ARM assembly doesn't help.)

I suspect Kees, and perhaps Will, will be able to provide the best answers,
but my thoughts are below.

> My basic question is: what happens if an OABI syscall happens?

Well, libseccomp doesn't support ARM OABI and since all the new ARM stuff is
EABI I don't think there is much reason to worry about OABI. I know this
doesn't answer your question, but perhaps this provides some context.

> AFAICS, the syscall arguments for EABI are r0..r5, although their
> ordering is a bit odd*.

Hmmm, that could complicate things a bit - do you know if they are put in a
more "standard" order by the time they are accessed in seccomp_bpf_load() via
task_pt_regs()? If not, we likely need to come up with some special handling
in libseccomp to account for this.

> For OABI, r6 seems to play some role, but I'm
> lost as to what it is. The seccomp_bpf_load function won't load r6,
> so there had better not be anything useful in there... (Also, struct
> seccomp_data will have issues with a seventh "argument".)
>
> But what happens to the syscall number? For an EABI syscall, it's in
> r7. For an OABI syscall, it's in the swi instruction and gets copied
> to r7 on entry. If a debugger changes r7, presumably the syscall
> number changes.
>
> Oddly, there are two different syscall tables. The major differences
> seem to be that some of the OABI entries have their argument order
> changed. But there's also a magic constant 0x900000 added to the
> syscall number somewhere -- is it reflected in _sigsys._syscall? Is
> it reflected in ucontext's r7?

Thankfully, I've been able to ignore most of this.

> I'm a bit surprised to see that both the EABI and OABI ABIs show up as
> AUDIT_ARCH_ARM.

Yeah, the usage of AUDIT_ARCH_* is not really ideal for seccomp. There are
similar issues with x32; not quite as bad as with ARM, but still ...

> Can any of you shed some light on this? I don't have an ARM system I
> can test on, but if one of you can point me at a decent QEMU image, I
> can play around.

I know Kees had one at one point, although I remember him commenting that it
was painfully slow under QEMU.

> For reference, I'm working on userspace code to decode a TRAP and
> eventually to allow syscall emulation (either by emulating the syscall
> inside the signal handler and setting the return value or (egads!) by
> changing the syscall and restarting it -- the latter is probably
> impossible if the original syscall came in through OABI and may be
> generally impossible if userspace expects any of the argument
> registers to be preserved).
>
>
> * I think that a syscall with signature long func(int a, long long b,
> int c, int d, int e) ends up with c in r1 and b in r2/r3. The
> syscall(2) manpage appears to be entirely wrong.

--
paul moore
security and virtualization @ redhat

2013-10-24 19:55:59

by Richard Weinberger

[permalink] [raw]
Subject: Re: ARM seccomp filters and EABI/OABI

On Wed, Oct 23, 2013 at 11:02 PM, Andy Lutomirski <[email protected]> wrote:
> I'm looking at the seccomp code, the ARM entry code, and the
> syscall(2) manpage, and I'm a bit lost. (The fact that I don't really
> speak ARM assembly doesn't help.) My basic question is: what happens
> if an OABI syscall happens?
>
> AFAICS, the syscall arguments for EABI are r0..r5, although their
> ordering is a bit odd*. For OABI, r6 seems to play some role, but I'm
> lost as to what it is. The seccomp_bpf_load function won't load r6,
> so there had better not be anything useful in there... (Also, struct
> seccomp_data will have issues with a seventh "argument".)
>
> But what happens to the syscall number? For an EABI syscall, it's in
> r7. For an OABI syscall, it's in the swi instruction and gets copied
> to r7 on entry. If a debugger changes r7, presumably the syscall
> number changes.
>
> Oddly, there are two different syscall tables. The major differences
> seem to be that some of the OABI entries have their argument order
> changed. But there's also a magic constant 0x900000 added to the
> syscall number somewhere -- is it reflected in _sigsys._syscall? Is
> it reflected in ucontext's r7?
>
> I'm a bit surprised to see that both the EABI and OABI ABIs show up as
> AUDIT_ARCH_ARM.
>
> Can any of you shed some light on this? I don't have an ARM system I
> can test on, but if one of you can point me at a decent QEMU image, I
> can play around.

Maybe this helps:
http://people.debian.org/~aurel32/qemu/armel/

> For reference, I'm working on userspace code to decode a TRAP and
> eventually to allow syscall emulation (either by emulating the syscall
> inside the signal handler and setting the return value or (egads!) by
> changing the syscall and restarting it -- the latter is probably
> impossible if the original syscall came in through OABI and may be
> generally impossible if userspace expects any of the argument
> registers to be preserved).
>
>
> * I think that a syscall with signature long func(int a, long long b,
> int c, int d, int e) ends up with c in r1 and b in r2/r3. The
> syscall(2) manpage appears to be entirely wrong.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/



--
Thanks,
//richard

2013-10-24 21:14:38

by Andy Lutomirski

[permalink] [raw]
Subject: Re: [libseccomp-discuss] ARM seccomp filters and EABI/OABI

On Thu, Oct 24, 2013 at 12:11 PM, Paul Moore <[email protected]> wrote:
> On Wednesday, October 23, 2013 02:02:00 PM Andy Lutomirski wrote:
>> I'm looking at the seccomp code, the ARM entry code, and the
>> syscall(2) manpage, and I'm a bit lost. (The fact that I don't really
>> speak ARM assembly doesn't help.)
>
> I suspect Kees, and perhaps Will, will be able to provide the best answers,
> but my thoughts are below.
>
>> My basic question is: what happens if an OABI syscall happens?
>
> Well, libseccomp doesn't support ARM OABI and since all the new ARM stuff is
> EABI I don't think there is much reason to worry about OABI. I know this
> doesn't answer your question, but perhaps this provides some context.

Are you sure you don't support it? What actually happens if someone
writes an EABI program that issues an OABI syscall? (I'm hoping that
the syscall nr ends up offset by 0x900000, but I'm not sure.)

>
>> AFAICS, the syscall arguments for EABI are r0..r5, although their
>> ordering is a bit odd*.
>
> Hmmm, that could complicate things a bit - do you know if they are put in a
> more "standard" order by the time they are accessed in seccomp_bpf_load() via
> task_pt_regs()? If not, we likely need to come up with some special handling
> in libseccomp to account for this.

I don't think that such a think is possible. It depends on the
signature of the particular syscall, and I don't know if there's any
table of these things.


>
>> For OABI, r6 seems to play some role, but I'm
>> lost as to what it is. The seccomp_bpf_load function won't load r6,
>> so there had better not be anything useful in there... (Also, struct
>> seccomp_data will have issues with a seventh "argument".)
>>
>> But what happens to the syscall number? For an EABI syscall, it's in
>> r7. For an OABI syscall, it's in the swi instruction and gets copied
>> to r7 on entry. If a debugger changes r7, presumably the syscall
>> number changes.
>>
>> Oddly, there are two different syscall tables. The major differences
>> seem to be that some of the OABI entries have their argument order
>> changed. But there's also a magic constant 0x900000 added to the
>> syscall number somewhere -- is it reflected in _sigsys._syscall? Is
>> it reflected in ucontext's r7?
>
> Thankfully, I've been able to ignore most of this.
>
>> I'm a bit surprised to see that both the EABI and OABI ABIs show up as
>> AUDIT_ARCH_ARM.
>
> Yeah, the usage of AUDIT_ARCH_* is not really ideal for seccomp. There are
> similar issues with x32; not quite as bad as with ARM, but still ...

As long as the combination of AUDIT_ARCH and nr uniquely identifies a
syscall and its ABI, life should be good.

--Andy

>
>> Can any of you shed some light on this? I don't have an ARM system I
>> can test on, but if one of you can point me at a decent QEMU image, I
>> can play around.
>
> I know Kees had one at one point, although I remember him commenting that it
> was painfully slow under QEMU.
>
>> For reference, I'm working on userspace code to decode a TRAP and
>> eventually to allow syscall emulation (either by emulating the syscall
>> inside the signal handler and setting the return value or (egads!) by
>> changing the syscall and restarting it -- the latter is probably
>> impossible if the original syscall came in through OABI and may be
>> generally impossible if userspace expects any of the argument
>> registers to be preserved).
>>
>>
>> * I think that a syscall with signature long func(int a, long long b,
>> int c, int d, int e) ends up with c in r1 and b in r2/r3. The
>> syscall(2) manpage appears to be entirely wrong.
>
> --
> paul moore
> security and virtualization @ redhat
>



--
Andy Lutomirski
AMA Capital Management, LLC

2013-10-28 21:53:32

by Paul Moore

[permalink] [raw]
Subject: Re: ARM seccomp filters and EABI/OABI

On Thursday, October 24, 2013 09:55:57 PM Richard Weinberger wrote:
> On Wed, Oct 23, 2013 at 11:02 PM, Andy Lutomirski <[email protected]>
wrote:
> > I'm looking at the seccomp code, the ARM entry code, and the
> > syscall(2) manpage, and I'm a bit lost. (The fact that I don't really
> > speak ARM assembly doesn't help.) My basic question is: what happens
> > if an OABI syscall happens?
> >
> > AFAICS, the syscall arguments for EABI are r0..r5, although their
> > ordering is a bit odd*. For OABI, r6 seems to play some role, but I'm
> > lost as to what it is. The seccomp_bpf_load function won't load r6,
> > so there had better not be anything useful in there... (Also, struct
> > seccomp_data will have issues with a seventh "argument".)
> >
> > But what happens to the syscall number? For an EABI syscall, it's in
> > r7. For an OABI syscall, it's in the swi instruction and gets copied
> > to r7 on entry. If a debugger changes r7, presumably the syscall
> > number changes.
> >
> > Oddly, there are two different syscall tables. The major differences
> > seem to be that some of the OABI entries have their argument order
> > changed. But there's also a magic constant 0x900000 added to the
> > syscall number somewhere -- is it reflected in _sigsys._syscall? Is
> > it reflected in ucontext's r7?
> >
> > I'm a bit surprised to see that both the EABI and OABI ABIs show up as
> > AUDIT_ARCH_ARM.
> >
> > Can any of you shed some light on this? I don't have an ARM system I
> > can test on, but if one of you can point me at a decent QEMU image, I
> > can play around.
>
> Maybe this helps:
> http://people.debian.org/~aurel32/qemu/armel/

Thanks for the pointer, although those images look quite old, has anyone done
a refresh?

Also, on a related note, does anyone have any experience with any of the cheap
PC-esque ARM boards/systems that are floating around? I'm to the point of
considering picking one up for libseccomp development if I can find one that
supports a standard development environment, decently responsive, and is
relatively cheap ... anyone?

--
paul moore
http://www.paul-moore.com

2013-10-28 22:02:34

by Paul Moore

[permalink] [raw]
Subject: Re: [libseccomp-discuss] ARM seccomp filters and EABI/OABI

On Thursday, October 24, 2013 02:14:15 PM Andy Lutomirski wrote:
> On Thu, Oct 24, 2013 at 12:11 PM, Paul Moore <[email protected]> wrote:
> > On Wednesday, October 23, 2013 02:02:00 PM Andy Lutomirski wrote:
> >> I'm looking at the seccomp code, the ARM entry code, and the
> >> syscall(2) manpage, and I'm a bit lost. (The fact that I don't really
> >> speak ARM assembly doesn't help.)
> >
> > I suspect Kees, and perhaps Will, will be able to provide the best
> > answers, but my thoughts are below.
> >
> >> My basic question is: what happens if an OABI syscall happens?
> >
> > Well, libseccomp doesn't support ARM OABI and since all the new ARM stuff
> > is EABI I don't think there is much reason to worry about OABI. I know
> > this doesn't answer your question, but perhaps this provides some
> > context.
>
> Are you sure you don't support it?

Yep, I said libseccomp doesn't support it so we don't ;)

It may build and function to some extent, but I'm making no claims for OABI
support; if someone tries it on a OABI system they do so as their own risk.

> What actually happens if someone writes an EABI program that issues an OABI
> syscall? (I'm hoping that the syscall nr ends up offset by 0x900000, but
> I'm not sure.)

Like you, I expect there would be a syscall mismatch but I can't say for
certain.

> >> AFAICS, the syscall arguments for EABI are r0..r5, although their
> >> ordering is a bit odd*.
> >
> > Hmmm, that could complicate things a bit - do you know if they are put in
> > a more "standard" order by the time they are accessed in
> > seccomp_bpf_load() via task_pt_regs()? If not, we likely need to come up
> > with some special handling in libseccomp to account for this.
>
> I don't think that such a think is possible. It depends on the
> signature of the particular syscall, and I don't know if there's any
> table of these things.

Oh, that's all sorts of awesome.

Well, at least in libseccomp we do have a syscall table for each arch so it
should be possible to track what per-syscall fixups are needed (assuming some
augmentation of our syscall table structures) and apply them at runtime. The
hard part is going to be determining what fixups are needed and recording them
in the table.

Grrrrr.

> >> I'm a bit surprised to see that both the EABI and OABI ABIs show up as
> >> AUDIT_ARCH_ARM.
> >
> > Yeah, the usage of AUDIT_ARCH_* is not really ideal for seccomp. There
> > are similar issues with x32; not quite as bad as with ARM, but still ...
>
> As long as the combination of AUDIT_ARCH and nr uniquely identifies a
> syscall and its ABI, life should be good.

Ha! Life may be good, but the code to handle it was annoying* ;)

Largely because I made the assumption (which turned out to be a bad) that an
AUDIT_ARCH_* value uniquely identified a single ABI. Removing that assumption
was both annoying and painful; the code still isn't very good in dealing with
multiple ABIs sharing a single AUDIT_ARCH_* token but it works.

--
paul moore
security and virtualization @ redhat

2013-10-28 22:16:31

by Richard Weinberger

[permalink] [raw]
Subject: Re: ARM seccomp filters and EABI/OABI

Am 28.10.2013 22:53, schrieb Paul Moore:
> On Thursday, October 24, 2013 09:55:57 PM Richard Weinberger wrote:
>> On Wed, Oct 23, 2013 at 11:02 PM, Andy Lutomirski <[email protected]>
> wrote:
>>> I'm looking at the seccomp code, the ARM entry code, and the
>>> syscall(2) manpage, and I'm a bit lost. (The fact that I don't really
>>> speak ARM assembly doesn't help.) My basic question is: what happens
>>> if an OABI syscall happens?
>>>
>>> AFAICS, the syscall arguments for EABI are r0..r5, although their
>>> ordering is a bit odd*. For OABI, r6 seems to play some role, but I'm
>>> lost as to what it is. The seccomp_bpf_load function won't load r6,
>>> so there had better not be anything useful in there... (Also, struct
>>> seccomp_data will have issues with a seventh "argument".)
>>>
>>> But what happens to the syscall number? For an EABI syscall, it's in
>>> r7. For an OABI syscall, it's in the swi instruction and gets copied
>>> to r7 on entry. If a debugger changes r7, presumably the syscall
>>> number changes.
>>>
>>> Oddly, there are two different syscall tables. The major differences
>>> seem to be that some of the OABI entries have their argument order
>>> changed. But there's also a magic constant 0x900000 added to the
>>> syscall number somewhere -- is it reflected in _sigsys._syscall? Is
>>> it reflected in ucontext's r7?
>>>
>>> I'm a bit surprised to see that both the EABI and OABI ABIs show up as
>>> AUDIT_ARCH_ARM.
>>>
>>> Can any of you shed some light on this? I don't have an ARM system I
>>> can test on, but if one of you can point me at a decent QEMU image, I
>>> can play around.
>>
>> Maybe this helps:
>> http://people.debian.org/~aurel32/qemu/armel/
>
> Thanks for the pointer, although those images look quite old, has anyone done
> a refresh?

You are free to run "apt-get upgrade" within the said images. :-)

Thanks,
//richard

2013-10-29 17:48:47

by Will Drewry

[permalink] [raw]
Subject: Re: [libseccomp-discuss] ARM seccomp filters and EABI/OABI

On Mon, Oct 28, 2013 at 5:02 PM, Paul Moore <[email protected]> wrote:
> On Thursday, October 24, 2013 02:14:15 PM Andy Lutomirski wrote:
>> On Thu, Oct 24, 2013 at 12:11 PM, Paul Moore <[email protected]> wrote:
>> > On Wednesday, October 23, 2013 02:02:00 PM Andy Lutomirski wrote:
>> >> I'm looking at the seccomp code, the ARM entry code, and the
>> >> syscall(2) manpage, and I'm a bit lost. (The fact that I don't really
>> >> speak ARM assembly doesn't help.)
>> >
>> > I suspect Kees, and perhaps Will, will be able to provide the best
>> > answers, but my thoughts are below.
>> >
>> >> My basic question is: what happens if an OABI syscall happens?
>> >
>> > Well, libseccomp doesn't support ARM OABI and since all the new ARM stuff
>> > is EABI I don't think there is much reason to worry about OABI. I know
>> > this doesn't answer your question, but perhaps this provides some
>> > context.
>>
>> Are you sure you don't support it?
>
> Yep, I said libseccomp doesn't support it so we don't ;)
>
> It may build and function to some extent, but I'm making no claims for OABI
> support; if someone tries it on a OABI system they do so as their own risk.
>
>> What actually happens if someone writes an EABI program that issues an OABI
>> syscall? (I'm hoping that the syscall nr ends up offset by 0x900000, but
>> I'm not sure.)
>
> Like you, I expect there would be a syscall mismatch but I can't say for
> certain.

It looks like entry-common.S masks off the 0x900000 so that the
numbers are the same, but the entry path is determined by the software
interrupt instruction (SWI) 8-bit immediate which indicates the type
(which it looks like is read by loading the address(-4) in the link
register).

http://lxr.free-electrons.com/source/arch/arm/kernel/entry-common.S?a=arm#L420

Then it just swaps the call table if the immediate is non-zero and
uses the arg to call into the oabi version of the syscall table.

I don't think there's a clear way to detect if the oabi table has been
swapped in. I think that the reason that the AUDIT_ARCH is the same
for OABI compat/not compat is that there is no argument ordering or
syscall numbering difference. I'm not 100% though.

>> >> AFAICS, the syscall arguments for EABI are r0..r5, although their
>> >> ordering is a bit odd*.
>> >
>> > Hmmm, that could complicate things a bit - do you know if they are put in
>> > a more "standard" order by the time they are accessed in
>> > seccomp_bpf_load() via task_pt_regs()? If not, we likely need to come up
>> > with some special handling in libseccomp to account for this.
>>
>> I don't think that such a think is possible. It depends on the
>> signature of the particular syscall, and I don't know if there's any
>> table of these things.
>
> Oh, that's all sorts of awesome.
>
> Well, at least in libseccomp we do have a syscall table for each arch so it
> should be possible to track what per-syscall fixups are needed (assuming some
> augmentation of our syscall table structures) and apply them at runtime. The
> hard part is going to be determining what fixups are needed and recording them
> in the table.
>
> Grrrrr.

>From looking at the oabi compat calls, it may be that no fixup is
really needed in the BPF side, but only in places where other argument
introspection occurs -- ptrace or sigsys handlers.

>> >> I'm a bit surprised to see that both the EABI and OABI ABIs show up as
>> >> AUDIT_ARCH_ARM.
>> >
>> > Yeah, the usage of AUDIT_ARCH_* is not really ideal for seccomp. There
>> > are similar issues with x32; not quite as bad as with ARM, but still ...
>>
>> As long as the combination of AUDIT_ARCH and nr uniquely identifies a
>> syscall and its ABI, life should be good.
>
> Ha! Life may be good, but the code to handle it was annoying* ;)
>
> Largely because I made the assumption (which turned out to be a bad) that an
> AUDIT_ARCH_* value uniquely identified a single ABI. Removing that assumption
> was both annoying and painful; the code still isn't very good in dealing with
> multiple ABIs sharing a single AUDIT_ARCH_* token but it works.

It seems like a problem for the audit infrastucture if the calling
conventions are yielding improper system call information -- but I
don't think it is in this case (which is why it seemed to make sense
to connect the two subsystems...). The calls don't seem different,
but the structs are organized, aligned, or padded differently (which
shouldn't matter _too_ much to the seccomp filter unless the arg
ordering is different, etc). Bleh.
[ http://lxr.free-electrons.com/source/arch/arm/kernel/sys_oabi-compat.c ]

I'm not sure if pt_regs ends up looking the same, but I was hoping it
did. I realize that the seventh argument is dropped for OABI, but
IIRC, the only call that used it was the syscall() syscall:

http://lxr.free-electrons.com/source/arch/arm/kernel/entry-common.S#L524

which is marked as obsolete in calls.S. I don't think any other OABI
calls (or any other calls in general) pass a seventh argument. *think*
is the operative word though.

Maybe someone who's a bit more confident with the ARM syscall path can weigh in!

> Also, on a related note, does anyone have any experience with any of the cheap
> PC-esque ARM boards/systems that are floating around? I'm to the point of
> considering picking one up for libseccomp development if I can find one that
> supports a standard development environment, decently responsive, and is
> relatively cheap ... anyone?

I might have a spare, not-too-old board around - I'll take a look.

cheers!
will

2013-10-29 18:34:19

by Andy Lutomirski

[permalink] [raw]
Subject: Re: [libseccomp-discuss] ARM seccomp filters and EABI/OABI

On Tue, Oct 29, 2013 at 10:48 AM, Will Drewry <[email protected]> wrote:
> On Mon, Oct 28, 2013 at 5:02 PM, Paul Moore <[email protected]> wrote:
>> On Thursday, October 24, 2013 02:14:15 PM Andy Lutomirski wrote:
>>> On Thu, Oct 24, 2013 at 12:11 PM, Paul Moore <[email protected]> wrote:
>>> > On Wednesday, October 23, 2013 02:02:00 PM Andy Lutomirski wrote:
>>> >> I'm looking at the seccomp code, the ARM entry code, and the
>>> >> syscall(2) manpage, and I'm a bit lost. (The fact that I don't really
>>> >> speak ARM assembly doesn't help.)
>>> >
>>> > I suspect Kees, and perhaps Will, will be able to provide the best
>>> > answers, but my thoughts are below.
>>> >
>>> >> My basic question is: what happens if an OABI syscall happens?
>>> >
>>> > Well, libseccomp doesn't support ARM OABI and since all the new ARM stuff
>>> > is EABI I don't think there is much reason to worry about OABI. I know
>>> > this doesn't answer your question, but perhaps this provides some
>>> > context.
>>>
>>> Are you sure you don't support it?
>>
>> Yep, I said libseccomp doesn't support it so we don't ;)
>>
>> It may build and function to some extent, but I'm making no claims for OABI
>> support; if someone tries it on a OABI system they do so as their own risk.
>>
>>> What actually happens if someone writes an EABI program that issues an OABI
>>> syscall? (I'm hoping that the syscall nr ends up offset by 0x900000, but
>>> I'm not sure.)
>>
>> Like you, I expect there would be a syscall mismatch but I can't say for
>> certain.
>
> It looks like entry-common.S masks off the 0x900000 so that the
> numbers are the same, but the entry path is determined by the software
> interrupt instruction (SWI) 8-bit immediate which indicates the type
> (which it looks like is read by loading the address(-4) in the link
> register).
>
> http://lxr.free-electrons.com/source/arch/arm/kernel/entry-common.S?a=arm#L420
>
> Then it just swaps the call table if the immediate is non-zero and
> uses the arg to call into the oabi version of the syscall table.
>
> I don't think there's a clear way to detect if the oabi table has been
> swapped in. I think that the reason that the AUDIT_ARCH is the same
> for OABI compat/not compat is that there is no argument ordering or
> syscall numbering difference. I'm not 100% though.
>
>>> >> AFAICS, the syscall arguments for EABI are r0..r5, although their
>>> >> ordering is a bit odd*.
>>> >
>>> > Hmmm, that could complicate things a bit - do you know if they are put in
>>> > a more "standard" order by the time they are accessed in
>>> > seccomp_bpf_load() via task_pt_regs()? If not, we likely need to come up
>>> > with some special handling in libseccomp to account for this.
>>>
>>> I don't think that such a think is possible. It depends on the
>>> signature of the particular syscall, and I don't know if there's any
>>> table of these things.
>>
>> Oh, that's all sorts of awesome.
>>
>> Well, at least in libseccomp we do have a syscall table for each arch so it
>> should be possible to track what per-syscall fixups are needed (assuming some
>> augmentation of our syscall table structures) and apply them at runtime. The
>> hard part is going to be determining what fixups are needed and recording them
>> in the table.
>>
>> Grrrrr.
>
> From looking at the oabi compat calls, it may be that no fixup is
> really needed in the BPF side, but only in places where other argument
> introspection occurs -- ptrace or sigsys handlers.

Isn't a fixup needed for things like oabi_pread64 if the filter tries
to load the arguments?

If it's indeed the case that the nr has the 0x900000 masked off from
the syscall nr, I'd argue that that's a security bug -- a compromised
EABI process could (assuming it can find the right instruction in
executable memory) issue an OABI call to try to confuse the filter.
(Actually, executable memory might not be needed -- for all I know,
ARM code can spoof the link register.) Alternatively, banning OABI
calls outright when seccomp is enabled might not be such a bad idea.

>
>>> >> I'm a bit surprised to see that both the EABI and OABI ABIs show up as
>>> >> AUDIT_ARCH_ARM.
>>> >
>>> > Yeah, the usage of AUDIT_ARCH_* is not really ideal for seccomp. There
>>> > are similar issues with x32; not quite as bad as with ARM, but still ...
>>>
>>> As long as the combination of AUDIT_ARCH and nr uniquely identifies a
>>> syscall and its ABI, life should be good.
>>
>> Ha! Life may be good, but the code to handle it was annoying* ;)
>>
>> Largely because I made the assumption (which turned out to be a bad) that an
>> AUDIT_ARCH_* value uniquely identified a single ABI. Removing that assumption
>> was both annoying and painful; the code still isn't very good in dealing with
>> multiple ABIs sharing a single AUDIT_ARCH_* token but it works.
>
> It seems like a problem for the audit infrastucture if the calling
> conventions are yielding improper system call information -- but I
> don't think it is in this case (which is why it seemed to make sense
> to connect the two subsystems...). The calls don't seem different,
> but the structs are organized, aligned, or padded differently (which
> shouldn't matter _too_ much to the seccomp filter unless the arg
> ordering is different, etc). Bleh.
> [ http://lxr.free-electrons.com/source/arch/arm/kernel/sys_oabi-compat.c ]
>
> I'm not sure if pt_regs ends up looking the same, but I was hoping it
> did. I realize that the seventh argument is dropped for OABI, but
> IIRC, the only call that used it was the syscall() syscall:
>
> http://lxr.free-electrons.com/source/arch/arm/kernel/entry-common.S#L524
>
> which is marked as obsolete in calls.S. I don't think any other OABI
> calls (or any other calls in general) pass a seventh argument. *think*
> is the operative word though.

Good find. I didn't realize that anything used the seventh argument.
sys_syscall is probably completely useless for EABI, though --
userspace can issue a syscall by number the same way it would on any
other (sane) architecture. I can see why it's useful for OABI,
though.

--Andy

2013-10-29 19:38:35

by Paul Moore

[permalink] [raw]
Subject: Re: ARM seccomp filters and EABI/OABI

On Monday, October 28, 2013 11:16:20 PM Richard Weinberger wrote:
> Am 28.10.2013 22:53, schrieb Paul Moore:
> > On Thursday, October 24, 2013 09:55:57 PM Richard Weinberger wrote:
> >> On Wed, Oct 23, 2013 at 11:02 PM, Andy Lutomirski <[email protected]>
> >
> > wrote:
> >>> I'm looking at the seccomp code, the ARM entry code, and the
> >>> syscall(2) manpage, and I'm a bit lost. (The fact that I don't really
> >>> speak ARM assembly doesn't help.) My basic question is: what happens
> >>> if an OABI syscall happens?
> >>>
> >>> AFAICS, the syscall arguments for EABI are r0..r5, although their
> >>> ordering is a bit odd*. For OABI, r6 seems to play some role, but I'm
> >>> lost as to what it is. The seccomp_bpf_load function won't load r6,
> >>> so there had better not be anything useful in there... (Also, struct
> >>> seccomp_data will have issues with a seventh "argument".)
> >>>
> >>> But what happens to the syscall number? For an EABI syscall, it's in
> >>> r7. For an OABI syscall, it's in the swi instruction and gets copied
> >>> to r7 on entry. If a debugger changes r7, presumably the syscall
> >>> number changes.
> >>>
> >>> Oddly, there are two different syscall tables. The major differences
> >>> seem to be that some of the OABI entries have their argument order
> >>> changed. But there's also a magic constant 0x900000 added to the
> >>> syscall number somewhere -- is it reflected in _sigsys._syscall? Is
> >>> it reflected in ucontext's r7?
> >>>
> >>> I'm a bit surprised to see that both the EABI and OABI ABIs show up as
> >>> AUDIT_ARCH_ARM.
> >>>
> >>> Can any of you shed some light on this? I don't have an ARM system I
> >>> can test on, but if one of you can point me at a decent QEMU image, I
> >>> can play around.
> >>
> >> Maybe this helps:
> >> http://people.debian.org/~aurel32/qemu/armel/
> >
> > Thanks for the pointer, although those images look quite old, has anyone
> > done a refresh?
>
> You are free to run "apt-get upgrade" within the said images. :-)

Okay, true ;)

--
paul moore
http://www.paul-moore.com

2013-10-29 20:11:53

by Paul Moore

[permalink] [raw]
Subject: Re: [libseccomp-discuss] ARM seccomp filters and EABI/OABI

On Tuesday, October 29, 2013 12:48:45 PM Will Drewry wrote:
> On Mon, Oct 28, 2013 at 5:02 PM, Paul Moore <[email protected]> wrote:
> > On Thursday, October 24, 2013 02:14:15 PM Andy Lutomirski wrote:
> >> On Thu, Oct 24, 2013 at 12:11 PM, Paul Moore <[email protected]> wrote:
> >> > On Wednesday, October 23, 2013 02:02:00 PM Andy Lutomirski wrote:
> >> >> I'm looking at the seccomp code, the ARM entry code, and the
> >> >> syscall(2) manpage, and I'm a bit lost. (The fact that I don't really
> >> >> speak ARM assembly doesn't help.)
> >> >
> >> > I suspect Kees, and perhaps Will, will be able to provide the best
> >> > answers, but my thoughts are below.
> >> >
> >> >> My basic question is: what happens if an OABI syscall happens?
> >> >
> >> > Well, libseccomp doesn't support ARM OABI and since all the new ARM
> >> > stuff is EABI I don't think there is much reason to worry about OABI.
> >> > I know this doesn't answer your question, but perhaps this provides
> >> > some context.
> >>
> >> Are you sure you don't support it?
> >
> > Yep, I said libseccomp doesn't support it so we don't ;)
> >
> > It may build and function to some extent, but I'm making no claims for
> > OABI support; if someone tries it on a OABI system they do so as their own
> > risk.
> >
> >> What actually happens if someone writes an EABI program that issues an
> >> OABI syscall? (I'm hoping that the syscall nr ends up offset by
> >> 0x900000, but I'm not sure.)
> >
> > Like you, I expect there would be a syscall mismatch but I can't say for
> > certain.
>
> It looks like entry-common.S masks off the 0x900000 so that the
> numbers are the same, but the entry path is determined by the software
> interrupt instruction (SWI) 8-bit immediate which indicates the type
> (which it looks like is read by loading the address(-4) in the link
> register).
>
> http://lxr.free-electrons.com/source/arch/arm/kernel/entry-common.S?a=arm#L4
> 20
>
> Then it just swaps the call table if the immediate is non-zero and
> uses the arg to call into the oabi version of the syscall table.
>
> I don't think there's a clear way to detect if the oabi table has been
> swapped in. I think that the reason that the AUDIT_ARCH is the same
> for OABI compat/not compat is that there is no argument ordering or
> syscall numbering difference. I'm not 100% though.

I'm now also suspicious of what ends up being returned from syscall_get_nr(),
is the 0x900000 masked out for OABI or not? We had a similar problem with the
x32 stuff and had to fix the kernel to get things working correctly.

> >> >> AFAICS, the syscall arguments for EABI are r0..r5, although their
> >> >> ordering is a bit odd*.
> >> >
> >> > Hmmm, that could complicate things a bit - do you know if they are put
> >> > in a more "standard" order by the time they are accessed in
> >> > seccomp_bpf_load() via task_pt_regs()? If not, we likely need to come
> >> > up with some special handling in libseccomp to account for this.
> >>
> >> I don't think that such a think is possible. It depends on the
> >> signature of the particular syscall, and I don't know if there's any
> >> table of these things.
> >
> > Oh, that's all sorts of awesome.
> >
> > Well, at least in libseccomp we do have a syscall table for each arch so
> > it should be possible to track what per-syscall fixups are needed
> > (assuming some augmentation of our syscall table structures) and apply
> > them at runtime. The hard part is going to be determining what fixups are
> > needed and recording them in the table.
> >
> > Grrrrr.
>
> From looking at the oabi compat calls, it may be that no fixup is
> really needed in the BPF side, but only in places where other argument
> introspection occurs -- ptrace or sigsys handlers.

Better I suppose, still not great. It frees us up a bit from needing to do in
special ARM handling when generating the filter, but it does make it harder to
do the stuff that Andy is trying to do.

> >> >> I'm a bit surprised to see that both the EABI and OABI ABIs show up as
> >> >> AUDIT_ARCH_ARM.
> >> >
> >> > Yeah, the usage of AUDIT_ARCH_* is not really ideal for seccomp. There
> >> > are similar issues with x32; not quite as bad as with ARM, but still
> >> > ...
> >>
> >> As long as the combination of AUDIT_ARCH and nr uniquely identifies a
> >> syscall and its ABI, life should be good.
> >
> > Ha! Life may be good, but the code to handle it was annoying* ;)
> >
> > Largely because I made the assumption (which turned out to be a bad) that
> > an AUDIT_ARCH_* value uniquely identified a single ABI. Removing that
> > assumption was both annoying and painful; the code still isn't very good
> > in dealing with multiple ABIs sharing a single AUDIT_ARCH_* token but it
> > works.
>
> It seems like a problem for the audit infrastucture if the calling
> conventions are yielding improper system call information -- but I
> don't think it is in this case (which is why it seemed to make sense
> to connect the two subsystems...).

The problem I've been bumping into with libseccomp is that the AUDIT_ARCH_*
values are really only useful in pointing you at the right syscall table, and
not necessarily the ABI. The x86_64/x32 (and possibly ARM OABI/EABI) issue is
a good example of this limitation. I suppose for audit this may not be a
major concern, but when you are writing a seccomp BPF filter and you want to
allow x86_64 but not x32 you have to examine both the AUDIT_ARCH_* value and
the syscall number, looking at the AUDIT_ARCH_* value is not sufficient.

> The calls don't seem different, but the structs are organized, aligned, or
> padded differently (which shouldn't matter _too_ much to the seccomp filter
> unless the arg ordering is different, etc). Bleh.
> [ http://lxr.free-electrons.com/source/arch/arm/kernel/sys_oabi-compat.c ]

That's a pretty strong argument for not supporting ARM OABI in libseccomp,
especially since everything seems to be going towards EABI.

> I'm not sure if pt_regs ends up looking the same, but I was hoping it
> did. I realize that the seventh argument is dropped for OABI, but
> IIRC, the only call that used it was the syscall() syscall:
>
> http://lxr.free-electrons.com/source/arch/arm/kernel/entry-common.S#L524
>
> which is marked as obsolete in calls.S. I don't think any other OABI
> calls (or any other calls in general) pass a seventh argument. *think*
> is the operative word though.
>
> Maybe someone who's a bit more confident with the ARM syscall path can weigh
> in!
>
> > Also, on a related note, does anyone have any experience with any of the
> > cheap PC-esque ARM boards/systems that are floating around? I'm to the
> > point of considering picking one up for libseccomp development if I can
> > find one that supports a standard development environment, decently
> > responsive, and is relatively cheap ... anyone?
>
> I might have a spare, not-too-old board around - I'll take a look.

That would be great, but I was really just looking for recommendations. I
don't mind buying some ARM hardware, I just would like to find something that
I can treat like a normal PC (or close to it), e.g. limited bootloader hacks
needed, SATA port, working display, network, etc.

--
paul moore
security and virtualization @ redhat

2013-10-30 17:19:36

by Kees Cook

[permalink] [raw]
Subject: Re: [libseccomp-discuss] ARM seccomp filters and EABI/OABI

On Thu, Oct 24, 2013 at 12:11 PM, Paul Moore <[email protected]> wrote:
> On Wednesday, October 23, 2013 02:02:00 PM Andy Lutomirski wrote:
>> I'm looking at the seccomp code, the ARM entry code, and the
>> syscall(2) manpage, and I'm a bit lost. (The fact that I don't really
>> speak ARM assembly doesn't help.)
>
> I suspect Kees, and perhaps Will, will be able to provide the best answers,
> but my thoughts are below.
>
>> My basic question is: what happens if an OABI syscall happens?
>
> Well, libseccomp doesn't support ARM OABI and since all the new ARM stuff is
> EABI I don't think there is much reason to worry about OABI. I know this
> doesn't answer your question, but perhaps this provides some context.

The original ARM seccomp patch had two SECCOMP_ARCH entries, but it
was a mistake as it was really a description of endianness:
https://lkml.org/lkml/2012/11/5/273

I also got the impression from another discussion I can't find that
when seccomp does its checks, the syscall offset has already been
dealt with. The best I could find discussing this was:
https://lkml.org/lkml/2012/11/1/383

>> AFAICS, the syscall arguments for EABI are r0..r5, although their
>> ordering is a bit odd*.
>
> Hmmm, that could complicate things a bit - do you know if they are put in a
> more "standard" order by the time they are accessed in seccomp_bpf_load() via
> task_pt_regs()? If not, we likely need to come up with some special handling
> in libseccomp to account for this.
>
>> For OABI, r6 seems to play some role, but I'm
>> lost as to what it is. The seccomp_bpf_load function won't load r6,
>> so there had better not be anything useful in there... (Also, struct
>> seccomp_data will have issues with a seventh "argument".)
>>
>> But what happens to the syscall number? For an EABI syscall, it's in
>> r7. For an OABI syscall, it's in the swi instruction and gets copied
>> to r7 on entry. If a debugger changes r7, presumably the syscall
>> number changes.
>>
>> Oddly, there are two different syscall tables. The major differences
>> seem to be that some of the OABI entries have their argument order
>> changed. But there's also a magic constant 0x900000 added to the
>> syscall number somewhere -- is it reflected in _sigsys._syscall? Is
>> it reflected in ucontext's r7?
>
> Thankfully, I've been able to ignore most of this.
>
>> I'm a bit surprised to see that both the EABI and OABI ABIs show up as
>> AUDIT_ARCH_ARM.
>
> Yeah, the usage of AUDIT_ARCH_* is not really ideal for seccomp. There are
> similar issues with x32; not quite as bad as with ARM, but still ...
>
>> Can any of you shed some light on this? I don't have an ARM system I
>> can test on, but if one of you can point me at a decent QEMU image, I
>> can play around.
>
> I know Kees had one at one point, although I remember him commenting that it
> was painfully slow under QEMU.

Yeah, I set up an ARM emulator via QEMU. It is very slow, but it at
least gets me somewhere with testing when I don't have a real ARM
device handy. I followed the Debian ARM qemu instructions.

-Kees

--
Kees Cook
Chrome OS Security

2013-10-31 23:51:07

by Andy Lutomirski

[permalink] [raw]
Subject: Re: ARM seccomp filters and EABI/OABI

On Tue, Oct 29, 2013 at 12:38 PM, Paul Moore <[email protected]> wrote:
> On Monday, October 28, 2013 11:16:20 PM Richard Weinberger wrote:
>> Am 28.10.2013 22:53, schrieb Paul Moore:
>> > On Thursday, October 24, 2013 09:55:57 PM Richard Weinberger wrote:
>> >> On Wed, Oct 23, 2013 at 11:02 PM, Andy Lutomirski <[email protected]>
>> >
>> > wrote:
>> >>> I'm looking at the seccomp code, the ARM entry code, and the
>> >>> syscall(2) manpage, and I'm a bit lost. (The fact that I don't really
>> >>> speak ARM assembly doesn't help.) My basic question is: what happens
>> >>> if an OABI syscall happens?
>> >>>
>> >>> AFAICS, the syscall arguments for EABI are r0..r5, although their
>> >>> ordering is a bit odd*. For OABI, r6 seems to play some role, but I'm
>> >>> lost as to what it is. The seccomp_bpf_load function won't load r6,
>> >>> so there had better not be anything useful in there... (Also, struct
>> >>> seccomp_data will have issues with a seventh "argument".)
>> >>>
>> >>> But what happens to the syscall number? For an EABI syscall, it's in
>> >>> r7. For an OABI syscall, it's in the swi instruction and gets copied
>> >>> to r7 on entry. If a debugger changes r7, presumably the syscall
>> >>> number changes.
>> >>>
>> >>> Oddly, there are two different syscall tables. The major differences
>> >>> seem to be that some of the OABI entries have their argument order
>> >>> changed. But there's also a magic constant 0x900000 added to the
>> >>> syscall number somewhere -- is it reflected in _sigsys._syscall? Is
>> >>> it reflected in ucontext's r7?
>> >>>
>> >>> I'm a bit surprised to see that both the EABI and OABI ABIs show up as
>> >>> AUDIT_ARCH_ARM.
>> >>>
>> >>> Can any of you shed some light on this? I don't have an ARM system I
>> >>> can test on, but if one of you can point me at a decent QEMU image, I
>> >>> can play around.
>> >>
>> >> Maybe this helps:
>> >> http://people.debian.org/~aurel32/qemu/armel/
>> >
>> > Thanks for the pointer, although those images look quite old, has anyone
>> > done a refresh?
>>
>> You are free to run "apt-get upgrade" within the said images. :-)
>
> Okay, true ;)

Except it didn't work... I fixed it with 'apt-key adv --recv-keys
--keyserver keyserver.ubuntu.com <key id from update's error
message>'.

I have yet to build a working kernel for this thing, though.
Apparently kernels since 3.8 have something wrong in the "versatile"
board file. Do any of you have a working .config and qemu -M option?

>
> --
> paul moore
> http://www.paul-moore.com
>



--
Andy Lutomirski
AMA Capital Management, LLC