-
Notifications
You must be signed in to change notification settings - Fork 27
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.
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 | ❌ | ❌ |
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).
*/