diff options
author | Tobias Klauser <tklauser@distanz.ch> | 2018-06-13 15:54:42 +0200 |
---|---|---|
committer | Tobias Klauser <tobias.klauser@gmail.com> | 2018-06-13 20:32:08 +0000 |
commit | fb4fb0430b8d77b5487f51fd780bba25476e816c (patch) | |
tree | 8c8c1812e404a0d903278af37e750a4826f5d9a5 /src/syscall/syscall_linux.go | |
parent | 4a778cdf3375d418062b3c3e9f6891cc9162e3d0 (diff) | |
download | go-git-fb4fb0430b8d77b5487f51fd780bba25476e816c.tar.gz |
syscall: check Fchmodat flags parameter on Linux
As mentioned in #25845, port CL 46474 from golang.org/x/sys/unix to the
syscall package.
Currently Linux' fchmodat(2) syscall implementation doesn't support the
flags parameter (though it might in future versions [1]). Fchmodat in
the syscall package takes the parameter and (wrongly) passes it on to the
syscall which will ignore it.
According to the POSIX.1-2008 manual page [2], AT_SYMLINK_NOFOLLOW is
the only valid value for the flags parameter and EOPNOTSUPP should be
returned in case changing the mode of a symbolic link is not supported
by the underlying system. EINVAL should be returned for any other value
of the flags parameter.
[1] https://patchwork.kernel.org/patch/9596301/
[2] http://pubs.opengroup.org/onlinepubs/9699919799/functions/chmod.html
Updates #20130
Updates #25845
Change-Id: I1021dd0e6a4f4cb3557cb1c1b34dd618c378cda6
Reviewed-on: https://go-review.googlesource.com/118658
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/syscall/syscall_linux.go')
-rw-r--r-- | src/syscall/syscall_linux.go | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/src/syscall/syscall_linux.go b/src/syscall/syscall_linux.go index 58216f1957..8d0532e216 100644 --- a/src/syscall/syscall_linux.go +++ b/src/syscall/syscall_linux.go @@ -35,6 +35,20 @@ func Creat(path string, mode uint32) (fd int, err error) { return Open(path, O_CREAT|O_WRONLY|O_TRUNC, mode) } +//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 + } + return fchmodat(dirfd, path, mode) +} + //sys linkat(olddirfd int, oldpath string, newdirfd int, newpath string, flags int) (err error) func Link(oldpath string, newpath string) (err error) { @@ -830,7 +844,6 @@ func Mount(source string, target string, fstype string, flags uintptr, data stri //sys Fallocate(fd int, mode uint32, off int64, len int64) (err error) //sys Fchdir(fd int) (err error) //sys Fchmod(fd int, mode uint32) (err error) -//sys Fchmodat(dirfd int, path string, mode uint32, flags int) (err error) //sys Fchownat(dirfd int, path string, uid int, gid int, flags int) (err error) //sys fcntl(fd int, cmd int, arg int) (val int, err error) //sys Fdatasync(fd int) (err error) |