Skip to content

Commit

Permalink
unix: use fchmodat2 in Fchmodat
Browse files Browse the repository at this point in the history
The fchmodat2 syscall was added in Linux kernel 6.6. Use it in Fchmodat
if flags are given. It will return ENOSYS on older kernels (or EINVAL or
any other bogus error in some container implementations).

Fixes golang/go#61636

Change-Id: Ibbc9a08733b7186907b2fe5837cb997446c38357
Reviewed-on: https://go-review.googlesource.com/c/sys/+/539635
Reviewed-by: Heschi Kreinick <heschi@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
  • Loading branch information
tklauser committed Nov 6, 2023
1 parent ec230da commit 2d0c736
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 9 deletions.
26 changes: 17 additions & 9 deletions unix/syscall_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,23 @@ func FanotifyMark(fd int, flags uint, mask uint64, dirFd int, pathname string) (
}

//sys fchmodat(dirfd int, path string, mode uint32) (err error)

func Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) {
// Linux fchmodat doesn't support the flags parameter. Mimick glibc's behavior
// and check the flags. Otherwise the mode would be applied to the symlink
// destination which is not what the user expects.
if flags&^AT_SYMLINK_NOFOLLOW != 0 {
return EINVAL
} else if flags&AT_SYMLINK_NOFOLLOW != 0 {
return EOPNOTSUPP
//sys fchmodat2(dirfd int, path string, mode uint32, flags int) (err error)

func Fchmodat(dirfd int, path string, mode uint32, flags int) error {
// Linux fchmodat doesn't support the flags parameter, but fchmodat2 does.
// Try fchmodat2 if flags are specified.
if flags != 0 {
err := fchmodat2(dirfd, path, mode, flags)
if err == ENOSYS {
// fchmodat2 isn't available. If the flags are known to be valid,
// return EOPNOTSUPP to indicate that fchmodat doesn't support them.
if flags&^(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) != 0 {
return EINVAL
} else if flags&(AT_SYMLINK_NOFOLLOW|AT_EMPTY_PATH) != 0 {
return EOPNOTSUPP
}
}
return err
}
return fchmodat(dirfd, path, mode)
}
Expand Down
15 changes: 15 additions & 0 deletions unix/zsyscall_linux.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 2d0c736

Please sign in to comment.