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 <dneil@google.com>
Reviewed-by: Alan Donovan <adonovan@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
}
func Deleteat(dirfd syscall.Handle, name string, options uint32) error {
+ if name == "." {
+ // NtOpenFile's documentation isn't explicit about what happens when deleting ".".
+ // Make this an error consistent with that of POSIX.
+ return syscall.EINVAL
+ }
objAttrs := &OBJECT_ATTRIBUTES{}
if err := objAttrs.init(dirfd, name); err != nil {
return err
import (
"errors"
+ "internal/filepathlite"
"internal/stringslite"
"sync/atomic"
"syscall"
if err := checkPathEscapesLstat(r, name); err != nil {
return &PathError{Op: "removeat", Path: name, Err: err}
}
+ if endsWithDot(name) {
+ // We don't want to permit removing the root itself, so check for that.
+ if filepathlite.Clean(name) == "." {
+ return &PathError{Op: "removeat", Path: name, Err: errPathEscapes}
+ }
+ }
if err := Remove(joinPath(r.root.name, name)); err != nil {
return &PathError{Op: "removeat", Path: name, Err: underlyingError(err)}
}