aboutsummaryrefslogtreecommitdiff
path: root/src/internal/syscall
diff options
context:
space:
mode:
authorOliver Stenbom <ostenbom@pivotal.io>2018-10-31 10:55:24 +0000
committerIan Lance Taylor <iant@golang.org>2018-10-31 13:55:01 +0000
commite8ffb8a74c90e3723dd6777af2c894f39d656795 (patch)
tree3407b57a00711aa3a7a8f7e10c7b197b4cebc04a /src/internal/syscall
parent49dafc70c8558271fc2205061d07eed490f2bc18 (diff)
downloadgo-e8ffb8a74c90e3723dd6777af2c894f39d656795.tar.xz
os: add support for long path names on unix RemoveAll
On unix systems, long enough path names will fail when performing syscalls like `Lstat`. The current RemoveAll uses several of these syscalls, and so will fail for long paths. This can be risky, as it can let users "hide" files from the system or otherwise make long enough paths for programs to fail. By using `Unlinkat` and `Openat` syscalls instead, RemoveAll is safer on unix systems. Initially implemented for linux, darwin, dragonfly, netbsd and openbsd. Not yet implemented on freebsd due to fstatat 64-bit inode compatibility issues. Fixes #27029 Co-authored-by: Giuseppe Capizzi <gcapizzi@pivotal.io> Co-authored-by: Julia Nedialkova <yulia.nedyalkova@sap.com> Change-Id: I978a6a4986878fe076d3c7af86e7927675624a96 GitHub-Last-Rev: 9235489c81b90c228210144b7c25b28a46bb80b7 GitHub-Pull-Request: golang/go#28494 Reviewed-on: https://go-review.googlesource.com/c/146020 Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/internal/syscall')
-rw-r--r--src/internal/syscall/unix/at.go58
-rw-r--r--src/internal/syscall/unix/at_sysnum_darwin.go12
-rw-r--r--src/internal/syscall/unix/at_sysnum_dragonfly.go14
-rw-r--r--src/internal/syscall/unix/at_sysnum_freebsd.go14
-rw-r--r--src/internal/syscall/unix/at_sysnum_fstatat64_linux.go11
-rw-r--r--src/internal/syscall/unix/at_sysnum_fstatat_linux.go11
-rw-r--r--src/internal/syscall/unix/at_sysnum_linux.go13
-rw-r--r--src/internal/syscall/unix/at_sysnum_netbsd.go14
-rw-r--r--src/internal/syscall/unix/at_sysnum_newfstatat_linux.go11
-rw-r--r--src/internal/syscall/unix/at_sysnum_openbsd.go14
10 files changed, 172 insertions, 0 deletions
diff --git a/src/internal/syscall/unix/at.go b/src/internal/syscall/unix/at.go
new file mode 100644
index 0000000000..1c05d2abe3
--- /dev/null
+++ b/src/internal/syscall/unix/at.go
@@ -0,0 +1,58 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux darwin freebsd openbsd netbsd dragonfly
+
+package unix
+
+import (
+ "syscall"
+ "unsafe"
+)
+
+func Unlinkat(dirfd int, path string, flags int) error {
+ var p *byte
+ p, err := syscall.BytePtrFromString(path)
+ if err != nil {
+ return err
+ }
+
+ _, _, errno := syscall.Syscall(unlinkatTrap, uintptr(dirfd), uintptr(unsafe.Pointer(p)), uintptr(flags))
+ if errno != 0 {
+ return errno
+ }
+
+ return nil
+}
+
+func Openat(dirfd int, path string, flags int, perm uint32) (int, error) {
+ var p *byte
+ p, err := syscall.BytePtrFromString(path)
+ if err != nil {
+ return 0, err
+ }
+
+ fd, _, errno := syscall.Syscall6(openatTrap, uintptr(dirfd), uintptr(unsafe.Pointer(p)), uintptr(flags), uintptr(perm), 0, 0)
+ if errno != 0 {
+ return 0, errno
+ }
+
+ return int(fd), nil
+}
+
+func Fstatat(dirfd int, path string, stat *syscall.Stat_t, flags int) error {
+ var p *byte
+ p, err := syscall.BytePtrFromString(path)
+ if err != nil {
+ return err
+ }
+
+ _, _, errno := syscall.Syscall6(fstatatTrap, uintptr(dirfd), uintptr(unsafe.Pointer(p)), uintptr(unsafe.Pointer(stat)), uintptr(flags), 0, 0)
+ if errno != 0 {
+ return errno
+ }
+
+ return nil
+
+}
diff --git a/src/internal/syscall/unix/at_sysnum_darwin.go b/src/internal/syscall/unix/at_sysnum_darwin.go
new file mode 100644
index 0000000000..12b7d79882
--- /dev/null
+++ b/src/internal/syscall/unix/at_sysnum_darwin.go
@@ -0,0 +1,12 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+const unlinkatTrap uintptr = 472
+const openatTrap uintptr = 463
+const fstatatTrap uintptr = 470
+
+const AT_REMOVEDIR = 0x80
+const AT_SYMLINK_NOFOLLOW = 0x0020
diff --git a/src/internal/syscall/unix/at_sysnum_dragonfly.go b/src/internal/syscall/unix/at_sysnum_dragonfly.go
new file mode 100644
index 0000000000..cec9abce6a
--- /dev/null
+++ b/src/internal/syscall/unix/at_sysnum_dragonfly.go
@@ -0,0 +1,14 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import "syscall"
+
+const unlinkatTrap uintptr = syscall.SYS_UNLINKAT
+const openatTrap uintptr = syscall.SYS_OPENAT
+const fstatatTrap uintptr = syscall.SYS_FSTATAT
+
+const AT_REMOVEDIR = 0x2
+const AT_SYMLINK_NOFOLLOW = 0x1
diff --git a/src/internal/syscall/unix/at_sysnum_freebsd.go b/src/internal/syscall/unix/at_sysnum_freebsd.go
new file mode 100644
index 0000000000..fe45e296d7
--- /dev/null
+++ b/src/internal/syscall/unix/at_sysnum_freebsd.go
@@ -0,0 +1,14 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import "syscall"
+
+const unlinkatTrap uintptr = syscall.SYS_UNLINKAT
+const openatTrap uintptr = syscall.SYS_OPENAT
+const fstatatTrap uintptr = syscall.SYS_FSTATAT
+
+const AT_REMOVEDIR = 0x800
+const AT_SYMLINK_NOFOLLOW = 0x200
diff --git a/src/internal/syscall/unix/at_sysnum_fstatat64_linux.go b/src/internal/syscall/unix/at_sysnum_fstatat64_linux.go
new file mode 100644
index 0000000000..c6ea206c12
--- /dev/null
+++ b/src/internal/syscall/unix/at_sysnum_fstatat64_linux.go
@@ -0,0 +1,11 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build arm mips mipsle 386
+
+package unix
+
+import "syscall"
+
+const fstatatTrap uintptr = syscall.SYS_FSTATAT64
diff --git a/src/internal/syscall/unix/at_sysnum_fstatat_linux.go b/src/internal/syscall/unix/at_sysnum_fstatat_linux.go
new file mode 100644
index 0000000000..580e7997f8
--- /dev/null
+++ b/src/internal/syscall/unix/at_sysnum_fstatat_linux.go
@@ -0,0 +1,11 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build arm64
+
+package unix
+
+import "syscall"
+
+const fstatatTrap uintptr = syscall.SYS_FSTATAT
diff --git a/src/internal/syscall/unix/at_sysnum_linux.go b/src/internal/syscall/unix/at_sysnum_linux.go
new file mode 100644
index 0000000000..fa7cd75d42
--- /dev/null
+++ b/src/internal/syscall/unix/at_sysnum_linux.go
@@ -0,0 +1,13 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import "syscall"
+
+const unlinkatTrap uintptr = syscall.SYS_UNLINKAT
+const openatTrap uintptr = syscall.SYS_OPENAT
+
+const AT_REMOVEDIR = 0x200
+const AT_SYMLINK_NOFOLLOW = 0x100
diff --git a/src/internal/syscall/unix/at_sysnum_netbsd.go b/src/internal/syscall/unix/at_sysnum_netbsd.go
new file mode 100644
index 0000000000..fe45e296d7
--- /dev/null
+++ b/src/internal/syscall/unix/at_sysnum_netbsd.go
@@ -0,0 +1,14 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import "syscall"
+
+const unlinkatTrap uintptr = syscall.SYS_UNLINKAT
+const openatTrap uintptr = syscall.SYS_OPENAT
+const fstatatTrap uintptr = syscall.SYS_FSTATAT
+
+const AT_REMOVEDIR = 0x800
+const AT_SYMLINK_NOFOLLOW = 0x200
diff --git a/src/internal/syscall/unix/at_sysnum_newfstatat_linux.go b/src/internal/syscall/unix/at_sysnum_newfstatat_linux.go
new file mode 100644
index 0000000000..e76c1cbdce
--- /dev/null
+++ b/src/internal/syscall/unix/at_sysnum_newfstatat_linux.go
@@ -0,0 +1,11 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build amd64 mips64 mips64le ppc64 ppc64le s390x
+
+package unix
+
+import "syscall"
+
+const fstatatTrap uintptr = syscall.SYS_NEWFSTATAT
diff --git a/src/internal/syscall/unix/at_sysnum_openbsd.go b/src/internal/syscall/unix/at_sysnum_openbsd.go
new file mode 100644
index 0000000000..c2d48b9914
--- /dev/null
+++ b/src/internal/syscall/unix/at_sysnum_openbsd.go
@@ -0,0 +1,14 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import "syscall"
+
+const unlinkatTrap uintptr = syscall.SYS_UNLINKAT
+const openatTrap uintptr = syscall.SYS_OPENAT
+const fstatatTrap uintptr = syscall.SYS_FSTATAT
+
+const AT_REMOVEDIR = 0x08
+const AT_SYMLINK_NOFOLLOW = 0x02