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