aboutsummaryrefslogtreecommitdiff
path: root/src/os/root_js.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/os/root_js.go')
-rw-r--r--src/os/root_js.go21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/os/root_js.go b/src/os/root_js.go
index 72138d1e89..70aa5f9ccd 100644
--- a/src/os/root_js.go
+++ b/src/os/root_js.go
@@ -12,7 +12,24 @@ import (
"syscall"
)
+// checkPathEscapes reports whether name escapes the root.
+//
+// Due to the lack of openat, checkPathEscapes is subject to TOCTOU races
+// when symlinks change during the resolution process.
func checkPathEscapes(r *Root, name string) error {
+ return checkPathEscapesInternal(r, name, false)
+}
+
+// checkPathEscapesLstat reports whether name escapes the root.
+// It does not resolve symlinks in the final path component.
+//
+// Due to the lack of openat, checkPathEscapes is subject to TOCTOU races
+// when symlinks change during the resolution process.
+func checkPathEscapesLstat(r *Root, name string) error {
+ return checkPathEscapesInternal(r, name, true)
+}
+
+func checkPathEscapesInternal(r *Root, name string, lstat bool) error {
if r.root.closed.Load() {
return ErrClosed
}
@@ -44,6 +61,10 @@ func checkPathEscapes(r *Root, name string) error {
continue
}
+ if lstat && i == len(parts)-1 {
+ break
+ }
+
next := joinPath(base, parts[i])
fi, err := Lstat(next)
if err != nil {