tech-kern archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: FWIW: sysrestrict



Le 23/07/2016 à 21:36, Matt Thomas a écrit :

On Jul 23, 2016, at 1:36 AM, Maxime Villard <max%M00nBSD.net@localhost> wrote:

Eight months ago, I shared with a few developers the code for a kernel
interface [1] that can disable syscalls in user processes.

The idea is the following: a syscall bitmap is embedded into the ELF binary
itself (in a note section, like PaX), and each time the binary performs a
syscall, the kernel checks whether the syscall in question is allowed in
the bitmap.

In details:
- the ELF section is a bitmap of 64 bytes, which means 512 bits, the
  number of syscalls. 0 means allowed, 1 means restricted.

Seems you only need the number of bytes needed to encode the hightest
restricted syscall.

I don't understand what you mean.

However, I think I'd prefer a level of indirection.  Have
a name of a bitmap embedded which references to a bitmap already loaded.
These would be visible via kern.restriction_sets.<name> which would contain the bitmap.
There would also be a sysctl controlling what happens if you try to run a program
with an unknown bitmap set which only take effect where securelevel is non-zero.

My idea was to do it rather in userland: for example, a conf file in /etc/ that
associates aliases to several syscalls. Then, the userland tool reads this file
and creates the bitmap as expected if an alias is given in argv.

Like: /etc/sysrestrict.cfg has the following entry

	SYSCALL_VFS = SYS_read, SYS_write, SYS_seek

And then, you could just do:

	$ sysrestrictctl restrict SYSCALL_VFS [binary]

We would then just add rules for different types of syscalls.


- in the proc structure, 64 bytes are present, just a copy of the
  ELF section.
- when a syscall is performed, the kernel calls sysrestrict_enforce
  with the proc structure and the syscall number, and gives a look
  at the bitmap to make sure it is allowed. If it isn't, the process
  is killed.

What happens when we get more than 512 syscalls?  Is this for NetBSD
binaries only?

- a new syscall is added, sysrestrict, so that programs can restrict
  a syscall at runtime. This might be useful, particularly if a
  program calls a syscall once and wants to make sure it is not
  allowed any longer.

I assume it can't unrestrict.  do you pass the size of the array(s)?

Yes, it can't unrestrict. I don't know which array you are talking about,
but in the syscall, struct sysrestrict_list contains the number of entries
and a int array, and they are copied in.


- a userland tool (that I didn't write) can add and update such an ELF
  section in the binary.

This interface has the following advantages over most already-existing
implementations:
- it is system-independent, it could almost be copied as-is in FreeBSD.
- it is syscall-independent, we don't need to patch each syscall.
- it does not require binaries to be recompiled.
- the performance cost is low, if not non-existent.

If a syscall is restricted, what error is returned?  EPERM?  ENOSYS?

I said the process is killed.


Home | Main Index | Thread Index | Old Index