Merge pull request #29817 from YHNdnzj/fchmodat2

Add support for fchmodat2 and use it where appropriate
This commit is contained in:
Yu Watanabe
2023-11-02 04:56:29 +09:00
committed by GitHub
5 changed files with 55 additions and 18 deletions
+16 -2
View File
@@ -288,8 +288,22 @@ int fchmod_umask(int fd, mode_t m) {
int fchmod_opath(int fd, mode_t m) {
/* This function operates also on fd that might have been opened with
* O_PATH. Indeed fchmodat() doesn't have the AT_EMPTY_PATH flag like
* fchownat() does. */
* O_PATH. The tool set we have is non-intuitive:
* - fchmod(2) only operates on open files (i. e., fds with an open file description);
* - fchmodat(2) does not have a flag arg like fchownat(2) does, so no way to pass AT_EMPTY_PATH;
* + it should not be confused with the libc fchmodat(3) interface, which adds 4th flag argument,
* but does not support AT_EMPTY_PATH (only supports AT_SYMLINK_NOFOLLOW);
* - fchmodat2(2) supports all the AT_* flags, but is still very recent.
*
* We try to use fchmodat2(), and, if it is not supported, resort
* to the /proc/self/fd dance. */
assert(fd >= 0);
if (fchmodat2(fd, "", m, AT_EMPTY_PATH) >= 0)
return 0;
if (!IN_SET(errno, ENOSYS, EPERM)) /* Some container managers block unknown syscalls with EPERM */
return -errno;
if (chmod(FORMAT_PROC_FD_PATH(fd), m) < 0) {
if (errno != ENOENT)
+15
View File
@@ -32,6 +32,21 @@
/* ======================================================================= */
#if !HAVE_FCHMODAT2
static inline int missing_fchmodat2(int dirfd, const char *path, mode_t mode, int flags) {
# ifdef __NR_fchmodat2
return syscall(__NR_fchmodat2, dirfd, path, mode, flags);
# else
errno = ENOSYS;
return -1;
# endif
}
# define fchmodat2 missing_fchmodat2
#endif
/* ======================================================================= */
#if !HAVE_PIVOT_ROOT
static inline int missing_pivot_root(const char *new_root, const char *put_old) {
return syscall(__NR_pivot_root, new_root, put_old);