aboutsummaryrefslogtreecommitdiff
path: root/src/syscall
diff options
context:
space:
mode:
authorDamien Neil <dneil@google.com>2025-05-27 14:16:17 -0700
committerGopher Robot <gobot@golang.org>2025-05-27 19:35:07 -0700
commited08d2ad0928c0fc77cc2053863616ffb58c5aac (patch)
treee5ac6cdc943b5b17fa89145bcd200cd0675d25d8 /src/syscall
parentfce9d4515defec0473ca3a685408ef5304d23aa9 (diff)
downloadgo-ed08d2ad0928c0fc77cc2053863616ffb58c5aac.tar.xz
os: don't follow symlinks on Windows when O_CREATE|O_EXCL and read-only
Fix a bug in CL 672396, where we add FILE_FLAG_OPEN_REPARSE_POINT to the attributes passed to CreateFile, but then overwrite the attributes with FILE_ATTRIBUTE_READONLY when opening a file with a read-only permissions mode. For #73702 Change-Id: I6c10bf470054592bafa031732585fc3155c61341 Reviewed-on: https://go-review.googlesource.com/c/go/+/676655 Auto-Submit: Damien Neil <dneil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Alan Donovan <adonovan@google.com>
Diffstat (limited to 'src/syscall')
-rw-r--r--src/syscall/syscall_windows.go30
1 files changed, 15 insertions, 15 deletions
diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go
index 653e20f496..01c039cf28 100644
--- a/src/syscall/syscall_windows.go
+++ b/src/syscall/syscall_windows.go
@@ -398,22 +398,7 @@ func Open(name string, flag int, perm uint32) (fd Handle, err error) {
if flag&O_CLOEXEC == 0 {
sa = makeInheritSa()
}
- // We don't use CREATE_ALWAYS, because when opening a file with
- // FILE_ATTRIBUTE_READONLY these will replace an existing file
- // with a new, read-only one. See https://go.dev/issue/38225.
- //
- // Instead, we ftruncate the file after opening when O_TRUNC is set.
- var createmode uint32
var attrs uint32 = FILE_ATTRIBUTE_NORMAL
- switch {
- case flag&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
- createmode = CREATE_NEW
- attrs |= FILE_FLAG_OPEN_REPARSE_POINT // don't follow symlinks
- case flag&O_CREAT == O_CREAT:
- createmode = OPEN_ALWAYS
- default:
- createmode = OPEN_EXISTING
- }
if perm&S_IWRITE == 0 {
attrs = FILE_ATTRIBUTE_READONLY
}
@@ -433,6 +418,21 @@ func Open(name string, flag int, perm uint32) (fd Handle, err error) {
const _FILE_FLAG_WRITE_THROUGH = 0x80000000
attrs |= _FILE_FLAG_WRITE_THROUGH
}
+ // We don't use CREATE_ALWAYS, because when opening a file with
+ // FILE_ATTRIBUTE_READONLY these will replace an existing file
+ // with a new, read-only one. See https://go.dev/issue/38225.
+ //
+ // Instead, we ftruncate the file after opening when O_TRUNC is set.
+ var createmode uint32
+ switch {
+ case flag&(O_CREAT|O_EXCL) == (O_CREAT | O_EXCL):
+ createmode = CREATE_NEW
+ attrs |= FILE_FLAG_OPEN_REPARSE_POINT // don't follow symlinks
+ case flag&O_CREAT == O_CREAT:
+ createmode = OPEN_ALWAYS
+ default:
+ createmode = OPEN_EXISTING
+ }
h, err := createFile(namep, access, sharemode, sa, createmode, attrs, 0)
if h == InvalidHandle {
if err == ERROR_ACCESS_DENIED && (attrs&FILE_FLAG_BACKUP_SEMANTICS == 0) {