Skip to content

Translation of system calls

imlk edited this page Aug 23, 2021 · 1 revision

System call translation is the most important and complex part of proot-rs. This is because it can easily introduce bugs or behave inconsistently with the kernel.

We use unit tests and test_with_proot() to test if these system calls work correctly.

Current State of Translation

The following table describes the current state of translation of system calls. These system calls are organized by SyscallGroup, and system calls in the same SyscallGroup usually imply similar processing.

SyscallGroup Syscall Status UnitTest Covered Remarks
Execve execve
Ptrace ptrace
Wait wait4
Brk brk
GetCwd getcwd
Chdir fchdir, chdir
BindConnect bind, connect
Accept accept, accept4
GetSockOrPeerName getsockname, getpeername
StandardSyscall access, acct, chmod, chown, chroot, getxattr, listxattr, mknod, creat, removexattr, setxattr, stat, swapoff, swapon, truncate, umount2, uselib, utime, utimes int syscall(const char *pathname, ...) follow symlink
Open open int syscall(const char *pathname, int flags, ...)
StatAt fchownat, newfstatat, utimensat, name_to_handle_at, statx int syscall(int dirfd, const char *pathname, ... , int flags, ...)
ChmodAccessMkNodAt fchmodat, faccessat, futimesat, mknodat int syscall(int dirfd, const char *pathname, ...) follow symlink
InotifyAddWatch inotify_add_watch
DirLinkAttr lchown, lgetxattr, llistxattr, lremovexattr, lsetxattr, lstat, unlink, rmdir, mkdir int syscall(const char *pathname, ...) not follow symlink
PivotRoot pivot_root
LinkAt linkat
Mount mount
OpenAt openat
ReadLink readlink
ReadLinkAt readlinkat
UnlinkMkdirAt unlinkat, mkdirat int syscall(int dirfd, const char *pathname, ...) not follow symlink
Link link
Rename rename
RenameAt renameat
SymLink symlink
SymLinkAt symlinkat
Uname uname

Path Translation

One complication in path translation is whether we need to dereference/follow it if the last component of the path is a symbolic link.

In solving this problem, we found something worthy of reference in the kernel source code: https://elixir.bootlin.com/linux/latest/source/fs/namei.c#L97

/* [Feb-Apr 2000 AV] Complete rewrite. Rules for symlinks:
 *	inside the path - always follow.
 *	in the last component in creation/removal/renaming - never follow.
 *	if LOOKUP_FOLLOW passed - follow.
 *	if the pathname has trailing slashes - follow.
 *	otherwise - don't follow.
 * (applied in that order).
*/