diff options
| author | Damien Neil <dneil@google.com> | 2025-01-30 15:53:06 -0800 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2025-02-10 15:33:35 -0800 |
| commit | 371e83cd7b309988bbe6b1bc7d0bd72aff52aa08 (patch) | |
| tree | 224760e8930b26caa4abdd7db3a233eb404e6fc3 /src/internal/syscall | |
| parent | 2e8973aeea66f01d9770e1d307330a2d188b27cc (diff) | |
| download | go-371e83cd7b309988bbe6b1bc7d0bd72aff52aa08.tar.xz | |
os: add Root.Chmod
For #67002
Change-Id: Id6c3a2096bd10f5f5f6921a0441dc6d9e6cdeb3b
Reviewed-on: https://go-review.googlesource.com/c/go/+/645718
Commit-Queue: Damien Neil <dneil@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Damien Neil <dneil@google.com>
Diffstat (limited to 'src/internal/syscall')
| -rw-r--r-- | src/internal/syscall/unix/asm_darwin.s | 1 | ||||
| -rw-r--r-- | src/internal/syscall/unix/asm_openbsd.s | 2 | ||||
| -rw-r--r-- | src/internal/syscall/unix/at.go | 17 | ||||
| -rw-r--r-- | src/internal/syscall/unix/at_darwin.go | 22 | ||||
| -rw-r--r-- | src/internal/syscall/unix/at_libc.go | 21 | ||||
| -rw-r--r-- | src/internal/syscall/unix/at_openbsd.go | 22 | ||||
| -rw-r--r-- | src/internal/syscall/unix/at_sysnum_dragonfly.go | 1 | ||||
| -rw-r--r-- | src/internal/syscall/unix/at_sysnum_freebsd.go | 1 | ||||
| -rw-r--r-- | src/internal/syscall/unix/at_sysnum_linux.go | 1 | ||||
| -rw-r--r-- | src/internal/syscall/unix/at_sysnum_netbsd.go | 1 | ||||
| -rw-r--r-- | src/internal/syscall/unix/at_wasip1.go | 5 | ||||
| -rw-r--r-- | src/internal/syscall/windows/at_windows.go | 8 | ||||
| -rw-r--r-- | src/internal/syscall/windows/at_windows_test.go | 2 |
13 files changed, 100 insertions, 4 deletions
diff --git a/src/internal/syscall/unix/asm_darwin.s b/src/internal/syscall/unix/asm_darwin.s index b96eb1e807..de6e01ee4a 100644 --- a/src/internal/syscall/unix/asm_darwin.s +++ b/src/internal/syscall/unix/asm_darwin.s @@ -25,3 +25,4 @@ TEXT ·libc_sysconf_trampoline(SB),NOSPLIT,$0-0; JMP libc_sysconf(SB) TEXT ·libc_faccessat_trampoline(SB),NOSPLIT,$0-0; JMP libc_faccessat(SB) TEXT ·libc_readlinkat_trampoline(SB),NOSPLIT,$0-0; JMP libc_readlinkat(SB) TEXT ·libc_mkdirat_trampoline(SB),NOSPLIT,$0-0; JMP libc_mkdirat(SB) +TEXT ·libc_fchmodat_trampoline(SB),NOSPLIT,$0-0; JMP libc_fchmodat(SB) diff --git a/src/internal/syscall/unix/asm_openbsd.s b/src/internal/syscall/unix/asm_openbsd.s index 90f6831e4e..306ef4664d 100644 --- a/src/internal/syscall/unix/asm_openbsd.s +++ b/src/internal/syscall/unix/asm_openbsd.s @@ -14,3 +14,5 @@ TEXT ·libc_readlinkat_trampoline(SB),NOSPLIT,$0-0 JMP libc_readlinkat(SB) TEXT ·libc_mkdirat_trampoline(SB),NOSPLIT,$0-0 JMP libc_mkdirat(SB) +TEXT ·libc_fchmodat_trampoline(SB),NOSPLIT,$0-0 + JMP libc_fchmodat(SB) diff --git a/src/internal/syscall/unix/at.go b/src/internal/syscall/unix/at.go index 27a798e046..2a29dd6a5a 100644 --- a/src/internal/syscall/unix/at.go +++ b/src/internal/syscall/unix/at.go @@ -79,3 +79,20 @@ func Mkdirat(dirfd int, path string, mode uint32) error { } return nil } + +func Fchmodat(dirfd int, path string, mode uint32, flags int) error { + p, err := syscall.BytePtrFromString(path) + if err != nil { + return err + } + _, _, errno := syscall.Syscall6(fchmodatTrap, + uintptr(dirfd), + uintptr(unsafe.Pointer(p)), + uintptr(mode), + uintptr(flags), + 0, 0) + if errno != 0 { + return errno + } + return nil +} diff --git a/src/internal/syscall/unix/at_darwin.go b/src/internal/syscall/unix/at_darwin.go index dbcae5a788..759b0943f5 100644 --- a/src/internal/syscall/unix/at_darwin.go +++ b/src/internal/syscall/unix/at_darwin.go @@ -58,3 +58,25 @@ func Mkdirat(dirfd int, path string, mode uint32) error { } return nil } + +func libc_fchmodat_trampoline() + +//go:cgo_import_dynamic libc_fchmodat fchmodat "/usr/lib/libSystem.B.dylib" + +func Fchmodat(dirfd int, path string, mode uint32, flags int) error { + p, err := syscall.BytePtrFromString(path) + if err != nil { + return err + } + _, _, errno := syscall_syscall6(abi.FuncPCABI0(libc_fchmodat_trampoline), + uintptr(dirfd), + uintptr(unsafe.Pointer(p)), + uintptr(mode), + uintptr(flags), + 0, + 0) + if errno != 0 { + return errno + } + return nil +} diff --git a/src/internal/syscall/unix/at_libc.go b/src/internal/syscall/unix/at_libc.go index faf38be602..f88e09d31d 100644 --- a/src/internal/syscall/unix/at_libc.go +++ b/src/internal/syscall/unix/at_libc.go @@ -16,13 +16,15 @@ import ( //go:linkname procUnlinkat libc_unlinkat //go:linkname procReadlinkat libc_readlinkat //go:linkname procMkdirat libc_mkdirat +//go:linkname procFchmodat libc_fchmodat var ( procFstatat, procOpenat, procUnlinkat, procReadlinkat, - procMkdirat uintptr + procMkdirat, + procFchmodat uintptr ) func Unlinkat(dirfd int, path string, flags int) error { @@ -107,3 +109,20 @@ func Mkdirat(dirfd int, path string, mode uint32) error { } return nil } + +func Fchmodat(dirfd int, path string, mode uint32, flags int) error { + p, err := syscall.BytePtrFromString(path) + if err != nil { + return err + } + _, _, errno := syscall6(uintptr(unsafe.Pointer(&procFchmodat)), 4, + uintptr(dirfd), + uintptr(unsafe.Pointer(p)), + uintptr(mode), + uintptr(flags), + 0, 0) + if errno != 0 { + return errno + } + return nil +} diff --git a/src/internal/syscall/unix/at_openbsd.go b/src/internal/syscall/unix/at_openbsd.go index 69463e00b9..26ca70322b 100644 --- a/src/internal/syscall/unix/at_openbsd.go +++ b/src/internal/syscall/unix/at_openbsd.go @@ -49,3 +49,25 @@ func Mkdirat(dirfd int, path string, mode uint32) error { } return nil } + +//go:cgo_import_dynamic libc_fchmodat fchmodat "libc.so" + +func libc_fchmodat_trampoline() + +func Fchmodat(dirfd int, path string, mode uint32, flags int) error { + p, err := syscall.BytePtrFromString(path) + if err != nil { + return err + } + _, _, errno := syscall_syscall6(abi.FuncPCABI0(libc_fchmodat_trampoline), + uintptr(dirfd), + uintptr(unsafe.Pointer(p)), + uintptr(mode), + uintptr(flags), + 0, + 0) + if errno != 0 { + return errno + } + return nil +} diff --git a/src/internal/syscall/unix/at_sysnum_dragonfly.go b/src/internal/syscall/unix/at_sysnum_dragonfly.go index d0ba12a78a..84c60c47b8 100644 --- a/src/internal/syscall/unix/at_sysnum_dragonfly.go +++ b/src/internal/syscall/unix/at_sysnum_dragonfly.go @@ -12,6 +12,7 @@ const ( fstatatTrap uintptr = syscall.SYS_FSTATAT readlinkatTrap uintptr = syscall.SYS_READLINKAT mkdiratTrap uintptr = syscall.SYS_MKDIRAT + fchmodatTrap uintptr = syscall.SYS_FCHMODAT AT_EACCESS = 0x4 AT_FDCWD = 0xfffafdcd diff --git a/src/internal/syscall/unix/at_sysnum_freebsd.go b/src/internal/syscall/unix/at_sysnum_freebsd.go index 0f34722432..22ff4e7e89 100644 --- a/src/internal/syscall/unix/at_sysnum_freebsd.go +++ b/src/internal/syscall/unix/at_sysnum_freebsd.go @@ -19,4 +19,5 @@ const ( posixFallocateTrap uintptr = syscall.SYS_POSIX_FALLOCATE readlinkatTrap uintptr = syscall.SYS_READLINKAT mkdiratTrap uintptr = syscall.SYS_MKDIRAT + fchmodatTrap uintptr = syscall.SYS_FCHMODAT ) diff --git a/src/internal/syscall/unix/at_sysnum_linux.go b/src/internal/syscall/unix/at_sysnum_linux.go index 2885c7c681..8fba319cab 100644 --- a/src/internal/syscall/unix/at_sysnum_linux.go +++ b/src/internal/syscall/unix/at_sysnum_linux.go @@ -11,6 +11,7 @@ const ( openatTrap uintptr = syscall.SYS_OPENAT readlinkatTrap uintptr = syscall.SYS_READLINKAT mkdiratTrap uintptr = syscall.SYS_MKDIRAT + fchmodatTrap uintptr = syscall.SYS_FCHMODAT ) const ( diff --git a/src/internal/syscall/unix/at_sysnum_netbsd.go b/src/internal/syscall/unix/at_sysnum_netbsd.go index 820b977436..f2b7a4f9eb 100644 --- a/src/internal/syscall/unix/at_sysnum_netbsd.go +++ b/src/internal/syscall/unix/at_sysnum_netbsd.go @@ -12,6 +12,7 @@ const ( fstatatTrap uintptr = syscall.SYS_FSTATAT readlinkatTrap uintptr = syscall.SYS_READLINKAT mkdiratTrap uintptr = syscall.SYS_MKDIRAT + fchmodatTrap uintptr = syscall.SYS_FCHMODAT ) const ( diff --git a/src/internal/syscall/unix/at_wasip1.go b/src/internal/syscall/unix/at_wasip1.go index cd0cb4b7e4..7289317110 100644 --- a/src/internal/syscall/unix/at_wasip1.go +++ b/src/internal/syscall/unix/at_wasip1.go @@ -101,6 +101,11 @@ func Mkdirat(dirfd int, path string, mode uint32) error { )) } +func Fchmodat(dirfd int, path string, mode uint32, flags int) error { + // WASI preview 1 doesn't support changing file modes. + return syscall.ENOSYS +} + //go:wasmimport wasi_snapshot_preview1 path_create_directory //go:noescape func path_create_directory(fd int32, path *byte, pathLen size) syscall.Errno diff --git a/src/internal/syscall/windows/at_windows.go b/src/internal/syscall/windows/at_windows.go index 18429773c0..19bcc0dbac 100644 --- a/src/internal/syscall/windows/at_windows.go +++ b/src/internal/syscall/windows/at_windows.go @@ -20,9 +20,10 @@ const ( O_DIRECTORY = 0x100000 // target must be a directory O_NOFOLLOW_ANY = 0x20000000 // disallow symlinks anywhere in the path O_OPEN_REPARSE = 0x40000000 // FILE_OPEN_REPARSE_POINT, used by Lstat + O_WRITE_ATTRS = 0x80000000 // FILE_WRITE_ATTRIBUTES, used by Chmod ) -func Openat(dirfd syscall.Handle, name string, flag int, perm uint32) (_ syscall.Handle, e1 error) { +func Openat(dirfd syscall.Handle, name string, flag uint64, perm uint32) (_ syscall.Handle, e1 error) { if len(name) == 0 { return syscall.InvalidHandle, syscall.ERROR_FILE_NOT_FOUND } @@ -61,6 +62,9 @@ func Openat(dirfd syscall.Handle, name string, flag int, perm uint32) (_ syscall if flag&syscall.O_SYNC != 0 { options |= FILE_WRITE_THROUGH } + if flag&O_WRITE_ATTRS != 0 { + access |= FILE_WRITE_ATTRIBUTES + } // Allow File.Stat. access |= STANDARD_RIGHTS_READ | FILE_READ_ATTRIBUTES | FILE_READ_EA @@ -129,7 +133,7 @@ func Openat(dirfd syscall.Handle, name string, flag int, perm uint32) (_ syscall } // ntCreateFileError maps error returns from NTCreateFile to user-visible errors. -func ntCreateFileError(err error, flag int) error { +func ntCreateFileError(err error, flag uint64) error { s, ok := err.(NTStatus) if !ok { // Shouldn't really be possible, NtCreateFile always returns NTStatus. diff --git a/src/internal/syscall/windows/at_windows_test.go b/src/internal/syscall/windows/at_windows_test.go index 7da9ecf07a..daeb4fcde3 100644 --- a/src/internal/syscall/windows/at_windows_test.go +++ b/src/internal/syscall/windows/at_windows_test.go @@ -46,7 +46,7 @@ func TestOpen(t *testing.T) { continue } base := filepath.Base(tt.path) - h, err := windows.Openat(dirfd, base, tt.flag, 0o660) + h, err := windows.Openat(dirfd, base, uint64(tt.flag), 0o660) syscall.CloseHandle(dirfd) if err == nil { syscall.CloseHandle(h) |
