tech-kern archive

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

Re: FWIW: sysrestrict




On 23.07.2016 10:36, Maxime Villard 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.
>  - 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.
>  - 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.
>  - 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.
> 
> I've never tested this code. But in case it inspires or motivates someone.
> 
> [1] http://m00nbsd.net/garbage/sysrestrict/

I like this approach of not shipping external toolchain for new ABI
(CloudABI) and not patching and rebuilding software (pledge).

About the restrictions with paths (like prohibiting/permitting $HOME or
/etc access), how about making it a separate interface? It's currently
built into the pledge() interface:

"int pledge(const char *promises, const char *paths[]);"

That way people can use one or the other mechanism, or both. I think it
could also make sense to have compatibility support with the pledge()
interface - with an external libpledge library. To achieve this it would
be needed to have a capability to drop access to previously allowed
syscalls by an executable.

Attachment: signature.asc
Description: OpenPGP digital signature



Home | Main Index | Thread Index | Old Index