[go][fdio] Always add GET_ATTRIBUTES in PosixFlagsToFuchsiaIo

POSIX requires that `fstat` succeeds on a valid file descriptor, so we
must always open with `fileIo.FlagsPermGetAttributes`. This is required
as new VFS changes will enforce GET_ATTRIBUTES permissions.

Also, evaluate the O_RDONLY and O_WRONLY and O_RDWR only if O_PATH is
not specified. If we don't do this calling `open(..., O_PATH)` will
evaluate to opening as O_RDONLY (because O_RDONLY == 0) which would lead
to ACCESS_DENIED errors when executing `O_PATH` on a write-only or
restricted file.

Bug: 517452382

TAG: agy
CONV: 17bf7e1b-bf30-4c05-bf61-a5856495709c
Change-Id: Ib6b1669feb3ad27ad22021207db62aeb31dec8ed
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/go/+/1726229
Reviewed-by: Bruno Dal Bo <brunodalbo@google.com>
Commit-Queue: Rui Qi Sim <rqsim@google.com>
diff --git a/src/syscall/syscall_fuchsia.go b/src/syscall/syscall_fuchsia.go
index 9cce2a3..f079232 100644
--- a/src/syscall/syscall_fuchsia.go
+++ b/src/syscall/syscall_fuchsia.go
@@ -81,16 +81,20 @@
 func PosixFlagsToFuchsiaIo(flags int, mode uint32) fidlIo.Flags {
 	io_flags := fidlIo.FlagsFlagSendRepresentation | fidlIo.Flags(flags&FdioAlignedFlags)
 
-	switch flags & (O_RDONLY | O_WRONLY | O_RDWR) {
-	case O_RDONLY:
-		io_flags |= fidlIo.Flags(fidlIo.RStarDir)
-	case O_WRONLY:
-		io_flags |= fidlIo.Flags(fidlIo.WStarDir)
-	case O_RDWR:
-		io_flags |= fidlIo.Flags(fidlIo.RwStarDir)
-	}
+	// POSIX guarantees `fstat` works on any valid FD, so we must always include the
+	// GET_ATTRIBUTES right on Fuchsia, regardless of the Open mode.
+	io_flags |= fidlIo.FlagsPermGetAttributes
 
 	if (flags & O_PATH) == 0 {
+		switch flags & (O_RDONLY | O_WRONLY | O_RDWR) {
+		case O_RDONLY:
+			io_flags |= fidlIo.Flags(fidlIo.RStarDir)
+		case O_WRONLY:
+			io_flags |= fidlIo.Flags(fidlIo.WStarDir)
+		case O_RDWR:
+			io_flags |= fidlIo.Flags(fidlIo.RwStarDir)
+		}
+
 		io_flags |= fidlIo.FlagsPermInheritWrite | fidlIo.FlagsPermInheritExecute
 	}