Syscall intercept vs dynamic rewriting
While going through syscall_intercept I realised that the project has been moved to another maintainer (Intel discontinued support).
There are some updates with clone3 (we should incorporate them).
On other hand, Reading this paper (https://d-nb.info/1260458342/34) I was thinking about going to a dynamic rewrite solution.
https://github.com/srg-imperial/sabre
Sycall Intercept vs SaBRE
syscall_intercept comes with some important limitations.
First, syscall_intercept does not support the clone syscall
and thus multithreaded applications are out of scope. Indeed,
we observed instant crashes in all of our server benchmarks
except Lighttpd. Second, syscall_intercept only rewrites
syscalls inside the libc library and thus other syscalls might
be ignored. Lighttpd depends on libraries that have additional
system calls, for example librt. Syscalls in libraries outside of libc are common: In a quick scan on our Ubuntu
system, we found that 20% of system libraries issue syscalls.
In our Lighttpd benchmark, we avoid triggering system
calls outside of libc in order to compare the two systems
fairly. syscall_intercept showed a +7% overhead compared
to +0.9% of SaBRe. In terms of load time, syscall_intercept
showed a 230.35 ms overhead compared to 64.4 ms for
SaBRe.
Inspection of the syscall_intercept code base revealed
some contributing factors to the observed performance
overhead. The trampolines leading to the user-provided
interception routine perform additional unnecessary work
compared to SaBRe, such as saving and restoring registers
used by SIMD instructions (which we think would be better done as part of the user-provided handler when needed),
as well as doing unavoidable additional checks related to
syscall_intercept’s implementation of logging. Furthermore SaBRe employs a more optimised trampoline system using
only two jumps to get to the user-provided system call handler as opposed to syscall_intercept which uses three or four
jumps to get to the user-provided system call handler.
We also note that syscall_intercept is initialised during
early runtime, while SaBRe is initialised during load time
and thus can intercept a larger set of functionality, e.g. the
loader itself and libraries that come before syscall_intercept
in .init and .preinit.