diff options
Diffstat (limited to 'src/os/root_js.go')
| -rw-r--r-- | src/os/root_js.go | 21 |
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 { |
