Skip to content

Commit 7fa2c73

Browse files
neildgopherbot
authored andcommitted
os: disallow Root.Remove(".") on Plan 9, js, and Windows
Windows already forbids this, since removing the root causes a sharing violation (can't delete the directory while the os.Root has a handle open to it), but add a more explicit check for attempts to delete "." and return EINVAL. Note that this change to Windows doesn't affect operations like Root.Remove("dir/."), since the path is cleaned into just "dir" before attempting the deletion. Fixes #73863 Change-Id: I0f45ccb6c9f171d3a52831632c134150388d77b6 Reviewed-on: https://go-review.googlesource.com/c/go/+/679377 Auto-Submit: Damien Neil <[email protected]> Reviewed-by: Alan Donovan <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent 281cfcf commit 7fa2c73

File tree

2 files changed

+12
-0
lines changed

2 files changed

+12
-0
lines changed

src/internal/syscall/windows/at_windows.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,11 @@ func Mkdirat(dirfd syscall.Handle, name string, mode uint32) error {
192192
}
193193

194194
func Deleteat(dirfd syscall.Handle, name string, options uint32) error {
195+
if name == "." {
196+
// NtOpenFile's documentation isn't explicit about what happens when deleting ".".
197+
// Make this an error consistent with that of POSIX.
198+
return syscall.EINVAL
199+
}
195200
objAttrs := &OBJECT_ATTRIBUTES{}
196201
if err := objAttrs.init(dirfd, name); err != nil {
197202
return err

src/os/root_noopenat.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package os
88

99
import (
1010
"errors"
11+
"internal/filepathlite"
1112
"internal/stringslite"
1213
"sync/atomic"
1314
"syscall"
@@ -173,6 +174,12 @@ func rootRemove(r *Root, name string) error {
173174
if err := checkPathEscapesLstat(r, name); err != nil {
174175
return &PathError{Op: "removeat", Path: name, Err: err}
175176
}
177+
if endsWithDot(name) {
178+
// We don't want to permit removing the root itself, so check for that.
179+
if filepathlite.Clean(name) == "." {
180+
return &PathError{Op: "removeat", Path: name, Err: errPathEscapes}
181+
}
182+
}
176183
if err := Remove(joinPath(r.root.name, name)); err != nil {
177184
return &PathError{Op: "removeat", Path: name, Err: underlyingError(err)}
178185
}

0 commit comments

Comments
 (0)