Re: syscall call-from verification

2019-12-02 Thread Thomas de Grivel
My bad, SBCL uses the libc's wrappers indeed looking at the sources.

Le ven. 29 nov. 2019 à 22:41, Josh Elsasser  a écrit :
>
> On Fri, Nov 29, 2019 at 10:12:10AM +0100, Thomas de Grivel wrote:
> > Maybe Go is not the only problem, I see SBCL compiling syscalls too.
> >
> > Truth is libc is for C and not all programs are written in C nowadays.
>
> Where are you seeing SBCL compiling direct syscalls? In my testing,
> SBCL self-hosts just fine under a kernel modified to disallow syscalls
> from the text segment, whereas go is killed under such a kernel. Are
> you sure you're not seeing SBCL compile calls to the libc syscall
> wrappers?



-- 
 Thomas de Grivel
 kmx.io



Re: syscall call-from verification

2019-11-30 Thread Pavel Korovin
I missed the point, sorry.
What I mean that without the patch, lang/go and go ports are fine on
-current.

On 11/30, Christian Weisgerber wrote:
> Pavel Korovin:
> 
> > In my partial dpb build, lang/go goes fine.
> > My amd64 snapshot was custom-built from sources, dated 2019-11-30 ~02 a.m.
> 
> ... and obviously without Theo's patch to sys/kern/exec_elf.c from
> earlier in this thread.

-- 
With best regards,
Pavel Korovin



Re: syscall call-from verification

2019-11-30 Thread Christian Weisgerber
Pavel Korovin:

> In my partial dpb build, lang/go goes fine.
> My amd64 snapshot was custom-built from sources, dated 2019-11-30 ~02 a.m.

... and obviously without Theo's patch to sys/kern/exec_elf.c from
earlier in this thread.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: syscall call-from verification

2019-11-30 Thread Pavel Korovin
In my partial dpb build, lang/go goes fine.
My amd64 snapshot was custom-built from sources, dated 2019-11-30 ~02 a.m.

go ports (net/mattermos-server, sysutils/beats/filebeat, www/gitea)
are functional.

On 11/30, Christian Weisgerber wrote:
> > I'm running an amd64 bulk build with this.
> 
> The build failures were:
> lang/fpc
> lang/go
> 
> -- 
> Christian "naddy" Weisgerber  na...@mips.inka.de
> 

-- 
With best regards,
Pavel Korovin



Re: syscall call-from verification

2019-11-30 Thread Christian Weisgerber
On 2019-11-30, Christian Weisgerber  wrote:

>> If other things are broken, we need accurate reports instead of drama.
>> The commited diff allows main-program-syscall in dynamic binaries until
>> go is fixed.
>>
>> Here's a kernel diff which will expose such problems, by removing that 
>> permission.
>
> I'm running an amd64 bulk build with this.

The build failures were:
lang/fpc
lang/go

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: syscall call-from verification

2019-11-30 Thread Christian Weisgerber
On 2019-11-29, "Theo de Raadt"  wrote:

> If other things are broken, we need accurate reports instead of drama.
> The commited diff allows main-program-syscall in dynamic binaries until
> go is fixed.
>
> Here's a kernel diff which will expose such problems, by removing that 
> permission.

I'm running an amd64 bulk build with this.  Results later today.

-- 
Christian "naddy" Weisgerber  na...@mips.inka.de



Re: syscall call-from verification

2019-11-29 Thread Theo de Raadt
Josh Elsasser  wrote:

> On Fri, Nov 29, 2019 at 10:12:10AM +0100, Thomas de Grivel wrote:
> > Maybe Go is not the only problem, I see SBCL compiling syscalls too.
> > 
> > Truth is libc is for C and not all programs are written in C nowadays.
> 
> Where are you seeing SBCL compiling direct syscalls? In my testing,
> SBCL self-hosts just fine under a kernel modified to disallow syscalls
> from the text segment, whereas go is killed under such a kernel. Are
> you sure you're not seeing SBCL compile calls to the libc syscall
> wrappers?

At this point, I am only aware of go.  go can be fixed, actually go has
been fixed to satisfy ABI-instability on another system, and we here at
OpenBSD are the kings of ABI-instability and I have wanted us to go that
way, and I predict it will happen.

If other things are broken, we need accurate reports instead of drama.
The commited diff allows main-program-syscall in dynamic binaries until
go is fixed.

Here's a kernel diff which will expose such problems, by removing that 
permission.

If other problems are identified, work on them can start in parallel.

Index: exec_elf.c
===
RCS file: /cvs/src/sys/kern/exec_elf.c,v
retrieving revision 1.152
diff -u -p -u -r1.152 exec_elf.c
--- exec_elf.c  29 Nov 2019 06:34:45 -  1.152
+++ exec_elf.c  29 Nov 2019 17:07:34 -
@@ -621,17 +621,12 @@ exec_elf_makecmds(struct proc *p, struct
}
} else
addr = ELF_NO_ADDR;
-   /*
-* static binary: main program does system calls
-* dynamic binary: regular main program won't do system
-* calls, unfortunately go binaries do...
-*/
-   flags |= VMCMD_SYSCALL;
if (interp == NULL) {
/*
 * static binary: no ld.so, no late request for
 * syscalls inside libc,so block msyscall()
 */
+   flags |= VMCMD_SYSCALL;
p->p_vmspace->vm_map.flags |= 
VM_MAP_SYSCALL_ONCE;
}
 



Re: syscall call-from verification

2019-11-29 Thread Josh Elsasser
On Fri, Nov 29, 2019 at 10:12:10AM +0100, Thomas de Grivel wrote:
> Maybe Go is not the only problem, I see SBCL compiling syscalls too.
> 
> Truth is libc is for C and not all programs are written in C nowadays.

Where are you seeing SBCL compiling direct syscalls? In my testing,
SBCL self-hosts just fine under a kernel modified to disallow syscalls
from the text segment, whereas go is killed under such a kernel. Are
you sure you're not seeing SBCL compile calls to the libc syscall
wrappers?



Re: syscall call-from verification

2019-11-29 Thread Thomas de Grivel
Maybe Go is not the only problem, I see SBCL compiling syscalls too.

Truth is libc is for C and not all programs are written in C nowadays.

Le jeu. 28 nov. 2019 à 21:04, Theo de Raadt  a écrit :
>
> Miod Vallat  wrote:
>
> > > For dynamic binaries, valid regions are ld.so's text segment, the signal
> > > trampoline, and libc.so's text segment... AND the main program's text.
> > >
> > > Unfortunately our current go build model hasn't followed solaris/macos
> > > approach yet of calling libc stubs, and uses the inappropriate "embed
> > > system calls directly" method, so for now we'll need to authorize the main
> > > program text as well.  A comment in exec_elf.c explains this.
> > >
> > > If go is adapted to call library-based system call stubs on OpenBSD as
> > > well, this problem will go away.  There may be other environments creating
> > > raw system calls. I guess we'll need to find them as time goes by, and
> > > hope in time we can repair those also.
> >
> > Or you could use an ELF note to flag binaries allowed to issue syscalls
> > from their text section: only static binaries (including ld.so) and go
> > binaries would need them.
>
> Imagine a ld.so without the flag.  The kernel starts a userland process 
> running
> there.  So ld.so must be able to issue system calls
>
> Imagine a static binary without the flag.  It would fail.
>
> The kernel can alreayd identify these circumstances, and does not need a flag.
>
> The only special case is libc.so.  We discussed adding a linker option to add
> a note to libc.  And then build tooling to add the flag for libc.  And then 
> ld.so
> identification of this note.  But does it actually matter which way this is 
> done?
>
> I fear the option would be abused for other purposes.  In the future,
> why would we want programs doing system calls from other segments?  Are
> there any legitimate compelling reasons to avoid calling the libc stubs?
> I don't believe so.  Especially if those segments are in network facing
> programs and/or generated on the fly.  At worst a nasty JIT can generate code
> to call & of libc syscall(2) stub with SYS_* symbolic names.  That approach
> remains simple and workable for the developer, but somewhat more difficult for
> an attacker who not know the relevant locations.
>


-- 
 Thomas de Grivel
 kmx.io



Re: syscall call-from verification

2019-11-28 Thread Theo de Raadt
Miod Vallat  wrote:

> > For dynamic binaries, valid regions are ld.so's text segment, the signal
> > trampoline, and libc.so's text segment... AND the main program's text.
> >
> > Unfortunately our current go build model hasn't followed solaris/macos
> > approach yet of calling libc stubs, and uses the inappropriate "embed
> > system calls directly" method, so for now we'll need to authorize the main
> > program text as well.  A comment in exec_elf.c explains this.
> >
> > If go is adapted to call library-based system call stubs on OpenBSD as
> > well, this problem will go away.  There may be other environments creating
> > raw system calls. I guess we'll need to find them as time goes by, and
> > hope in time we can repair those also.
> 
> Or you could use an ELF note to flag binaries allowed to issue syscalls
> from their text section: only static binaries (including ld.so) and go
> binaries would need them.

Imagine a ld.so without the flag.  The kernel starts a userland process running
there.  So ld.so must be able to issue system calls

Imagine a static binary without the flag.  It would fail.

The kernel can alreayd identify these circumstances, and does not need a flag.

The only special case is libc.so.  We discussed adding a linker option to add
a note to libc.  And then build tooling to add the flag for libc.  And then 
ld.so
identification of this note.  But does it actually matter which way this is 
done?

I fear the option would be abused for other purposes.  In the future,
why would we want programs doing system calls from other segments?  Are
there any legitimate compelling reasons to avoid calling the libc stubs?
I don't believe so.  Especially if those segments are in network facing
programs and/or generated on the fly.  At worst a nasty JIT can generate code
to call & of libc syscall(2) stub with SYS_* symbolic names.  That approach
remains simple and workable for the developer, but somewhat more difficult for
an attacker who not know the relevant locations.



Re: syscall call-from verification

2019-11-28 Thread Miod Vallat


> For dynamic binaries, valid regions are ld.so's text segment, the signal
> trampoline, and libc.so's text segment... AND the main program's text.
>
> Unfortunately our current go build model hasn't followed solaris/macos
> approach yet of calling libc stubs, and uses the inappropriate "embed
> system calls directly" method, so for now we'll need to authorize the main
> program text as well.  A comment in exec_elf.c explains this.
>
> If go is adapted to call library-based system call stubs on OpenBSD as
> well, this problem will go away.  There may be other environments creating
> raw system calls. I guess we'll need to find them as time goes by, and
> hope in time we can repair those also.

Or you could use an ELF note to flag binaries allowed to issue syscalls
from their text section: only static binaries (including ld.so) and go
binaries would need them.



Re: syscall call-from verification

2019-11-28 Thread Theo de Raadt
Alexander Nasonov  wrote:

> Theo de Raadt wrote:
> > The following change only permits system calls from address-ranges
> > in the process which system calls are expected from.
> 
> Just curious if some approximation of pledge can be reimplemented
> in userspace with more granular libc.so's text segments?

I don't understand the question.

Please note a common misconception.  Pledge isn't about blocking system
calls.  Rather, it blocks system behaviours in catagories.  A subset of
that is done by blocking system calls.  A large subset of that is not
done by blocking system calls, but instead their actions, based upon the
full parameter context.

When you suggest granularity you are surely talking about system
call blocking, so that ignores parameters, so it is not at all like
what pledge does, so you can understand my confusion.



Re: syscall call-from verification

2019-11-28 Thread Alexander Nasonov
Theo de Raadt wrote:
> The following change only permits system calls from address-ranges
> in the process which system calls are expected from.

Just curious if some approximation of pledge can be reimplemented
in userspace with more granular libc.so's text segments?

-- 
Alex



Re: syscall call-from verification

2019-11-27 Thread Steffen Nurpmeso
Theo de Raadt wrote in <91679.1574892...@cvs.openbsd.org>:
 |Steffen Nurpmeso  wrote:
 |1> Theo de Raadt wrote in <29275.1574888...@cvs.openbsd.org>:
 |>|The following change only permits system calls from address-ranges
 |>|in the process which system calls are expected from.
 |>   ...
 |>|Unfortunately our current go build model hasn't followed solaris/macos
 |>|approach yet of calling libc stubs, and uses the inappropriate "embed
 |>|system calls directly" method, so for now we'll need to authorize \
 |>|the main
 |>|program text as well.  A comment in exec_elf.c explains this.
 |>|
 |>|If go is adapted to call library-based system call stubs on OpenBSD as
 |> 
 |> May i ask -- does this really mean that the (theoretic)
 |> possibility of writing a small assembler program which performs
 |> direct system calls will no longer be possible?
 |> Whereas i see "static binary: main program does system calls",
 |> a future change could very well restrict the allowed address range
 |> some more even then?
 |
 |Hopefully once go (and other environments which do the same) are
 |converted to use libc stubs, yes.  Unless your binary is static (which
 |is PIC/PIE, which is already an ABI hurdle).
 |
 |Program to the API rather than the ABI.  When we see benefits, we
 |change the ABI more often than the API.
 |
 |I have altered the ABI.  Pray I do not alter it further.

Ok.  It was that cool feeling once you had learned assembler, only
you (, the assembler) and the OS.
Thanks, and ciao!

--steffen
|
|Der Kragenbaer,The moon bear,
|der holt sich munter   he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)



Re: syscall call-from verification

2019-11-27 Thread Theo de Raadt
Steffen Nurpmeso  wrote:

1> Theo de Raadt wrote in <29275.1574888...@cvs.openbsd.org>:
>  |The following change only permits system calls from address-ranges
>  |in the process which system calls are expected from.
>   ...
>  |Unfortunately our current go build model hasn't followed solaris/macos
>  |approach yet of calling libc stubs, and uses the inappropriate "embed
>  |system calls directly" method, so for now we'll need to authorize the main
>  |program text as well.  A comment in exec_elf.c explains this.
>  |
>  |If go is adapted to call library-based system call stubs on OpenBSD as
> 
> May i ask -- does this really mean that the (theoretic)
> possibility of writing a small assembler program which performs
> direct system calls will no longer be possible?
> Whereas i see "static binary: main program does system calls",
> a future change could very well restrict the allowed address range
> some more even then?

Hopefully once go (and other environments which do the same) are
converted to use libc stubs, yes.  Unless your binary is static (which
is PIC/PIE, which is already an ABI hurdle).

Program to the API rather than the ABI.  When we see benefits, we
change the ABI more often than the API.

I have altered the ABI.  Pray I do not alter it further.



Re: syscall call-from verification

2019-11-27 Thread Steffen Nurpmeso
Theo de Raadt wrote in <29275.1574888...@cvs.openbsd.org>:
 |The following change only permits system calls from address-ranges
 |in the process which system calls are expected from.
  ...
 |Unfortunately our current go build model hasn't followed solaris/macos
 |approach yet of calling libc stubs, and uses the inappropriate "embed
 |system calls directly" method, so for now we'll need to authorize the main
 |program text as well.  A comment in exec_elf.c explains this.
 |
 |If go is adapted to call library-based system call stubs on OpenBSD as

May i ask -- does this really mean that the (theoretic)
possibility of writing a small assembler program which performs
direct system calls will no longer be possible?
Whereas i see "static binary: main program does system calls",
a future change could very well restrict the allowed address range
some more even then?

--steffen
|
|Der Kragenbaer,The moon bear,
|der holt sich munter   he cheerfully and one by one
|einen nach dem anderen runter  wa.ks himself off
|(By Robert Gernhardt)



syscall call-from verification

2019-11-27 Thread Theo de Raadt
The following change only permits system calls from address-ranges
in the process which system calls are expected from.

If you manage to upload exploit code containing a raw system call
sequence and instruction, and mprotect -w+x that block, such a system
call will not succeed but the process is killed.  This obliges the
attacker to use the libc system call stubs, which in some
circumstances are difficult to find due to libc random-relinking at
boot.

This is done by adding 1 extra condition to the fast-path of the
"syscall not on a writeable page" check.

For static binaries, the valid regions are the base program's text
segment and the signal trampoline page.

For dynamic binaries, valid regions are ld.so's text segment, the signal
trampoline, and libc.so's text segment... AND the main program's text.

Unfortunately our current go build model hasn't followed solaris/macos
approach yet of calling libc stubs, and uses the inappropriate "embed
system calls directly" method, so for now we'll need to authorize the main
program text as well.  A comment in exec_elf.c explains this.

If go is adapted to call library-based system call stubs on OpenBSD as
well, this problem will go away.  There may be other environments creating
raw system calls. I guess we'll need to find them as time goes by, and
hope in time we can repair those also.

The kernel performs most of these syscall-allowed registrations, but
the permission for libc.so is done by ld.so once it (randomly) maps
libc.so into the address space.  That is the purpose of the new
msyscall(2) system call.

procmap has benen updated to show the syscall regions with 'e' and the
stack regions with 'S'.  Here is a dynamic binary:

Start  EndrwxSep Offset   Dev   Inode  
File
0x6885cde4000  0x6885ce89000  r-x-ep 00037000 04:05 51988 
/usr/lib/libc.so.96.0
0x68899d05000  0x68899d06000  r-x-ep  00:00 0 
0x688cc8a2000  0x688cc8ae000  r-x-ep 4000 04:05 649617 
/usr/libexec/ld.so
0x7f7fff7c2000 0x7f7c2000 rw-S-p  00:00 0 

and a static binary:

Start  EndrwxSep Offset   Dev   Inode  
File
0x1c365b518000 0x1c365b592000 r-x-ep 00018000 04:00 25990 
/bin/ksh
0x1c38e5174000 0x1c38e5175000 r-x-ep  00:00 0 
0x7f7fff7d2000 0x7f7d1000 rw-S-p  00:00 0 

This diff has a ABI break:  ld.so depends on a new kernel system call 
msyscall(2).
Update to a -current kernel first, which contains a dummy version.  After that,
this may work:

cd /usr/src && make includes
cd */ld.so && make && make install
build new kernel and boot it.

i386 ld.so uses custom code library loading, and hasn't been tested yet.

Index: sys/sys/exec.h
===
RCS file: /cvs/src/sys/sys/exec.h,v
retrieving revision 1.38
diff -u -p -u -r1.38 exec.h
--- sys/sys/exec.h  1 Jun 2018 03:27:59 -   1.38
+++ sys/sys/exec.h  26 Nov 2019 23:25:47 -
@@ -99,6 +99,7 @@ struct exec_vmcmd {
 #define VMCMD_RELATIVE  0x0001  /* ev_addr is relative to base entry */
 #define VMCMD_BASE  0x0002  /* marks a base entry */
 #define VMCMD_STACK 0x0004  /* create with UVM_FLAG_STACK */
+#define VMCMD_SYSCALL   0x0008  /* create with UVM_FLAG_SYSCALL */
 };
 
 #defineEXEC_DEFAULT_VMCMD_SETSIZE  8   /* # of cmds in set to 
start */
Index: sys/sys/syscall_mi.h
===
RCS file: /cvs/src/sys/sys/syscall_mi.h,v
retrieving revision 1.23
diff -u -p -u -r1.23 syscall_mi.h
--- sys/sys/syscall_mi.h4 Nov 2019 18:06:03 -   1.23
+++ sys/sys/syscall_mi.h25 Nov 2019 22:57:10 -
@@ -73,9 +73,9 @@ mi_syscall(struct proc *p, register_t co
uvm_map_inentry_sp, p->p_vmspace->vm_map.sserial))
return (EPERM);
 
-   /* PC must not be in writeable memory */
+   /* PC must be in un-writeable permitted text (sigtramp, libc, ld.so) */
if (!uvm_map_inentry(p, >p_pcinentry, PROC_PC(p),
-   "[%s]%d/%d pc=%lx inside %lx-%lx: writeable syscall\n",
+   "[%s]%d/%d pc=%lx inside %lx-%lx: bogus syscall\n",
uvm_map_inentry_pc, p->p_vmspace->vm_map.wserial))
return (EPERM);
 
Index: sys/kern/exec_elf.c
===
RCS file: /cvs/src/sys/kern/exec_elf.c,v
retrieving revision 1.151
diff -u -p -u -r1.151 exec_elf.c
--- sys/kern/exec_elf.c 13 May 2019 19:21:31 -  1.151
+++ sys/kern/exec_elf.c 27 Nov 2019 19:59:17 -
@@ -456,7 +456,7 @@ elf_load_file(struct proc *p, char *path
addr = ph[i].p_vaddr - base_ph->p_vaddr;
}
elf_load_psection(>ep_vmcmds, nd.ni_vp,
-