POSIX defines faccessat() as having a fourth "flags" argument, while the linux syscall doesn't have it. Glibc tries to emulate AT_EACCESS and AT_SYMLINK_NOFOLLOW, but AT_EACCESS emulation is broken. Add a new faccessat(2) syscall with the added flags argument and implement both flags. The value of AT_EACCESS is defined in glibc headers to be the same as AT_REMOVEDIR. Use this value for the kernel interface as well, together with the explanatory comment. Also add AT_EMPTY_PATH support, which is not documented by POSIX, but can be useful and is trivial to implement.
Showing the changes to include/linux (1 of 23 files). Show all
Unified · Split
| @@ -428,6 +428,8 @@ asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length); · 427 unmodified lines | ||
| 428 | 428 | #endif |
| 429 | 429 | asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len); |
| 430 | 430 | asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode); |
| 431 | +asmlinkage long sys_faccessat2(int dfd, const char __user *filename, int mode, | |
| 432 | + int flags); | |
| 431 | 433 | asmlinkage long sys_chdir(const char __user *filename); |
| 432 | 434 | asmlinkage long sys_fchdir(unsigned int fd); |
| 433 | 435 | asmlinkage long sys_chroot(const char __user *filename); |
| @@ -1333,11 +1335,11 @@ static inline int ksys_chmod(const char __user *filename, umode_t mode) · 899 unmodified lines | ||
| 1333 | 1335 | return do_fchmodat(AT_FDCWD, filename, mode); |
| 1334 | 1336 | } |
| 1335 | 1337 | |
| 1336 | −extern long do_faccessat(int dfd, const char __user *filename, int mode); | |
| 1338 | +long do_faccessat(int dfd, const char __user *filename, int mode, int flags); | |
| 1337 | 1339 | |
| 1338 | 1340 | static inline long ksys_access(const char __user *filename, int mode) |
| 1339 | 1341 | { |
| 1340 | − return do_faccessat(AT_FDCWD, filename, mode); | |
| 1342 | + return do_faccessat(AT_FDCWD, filename, mode, 0); | |
| 1341 | 1343 | } |
| 1342 | 1344 | |
| 1343 | 1345 | extern int do_fchownat(int dfd, const char __user *filename, uid_t user, |