S3: stamp the gateway's own uid/gid on PutObject and copy entries (#10844)

* fix(s3): stamp the gateway's own ids on single-shot PutObject entries

putToFiler builds the entry in the gateway now instead of proxying a PUT to
the filer, and it hardcoded Uid/Gid 0 while every sibling write path stamps
filer_pb.OS_UID/OS_GID. On a non-root deployment that leaves single-shot PUTs
and multipart parts owned by root while directories and completed multipart
objects keep the real ids, so a mount reader can list the tree but gets EACCES
on every open once objects are not world-readable.

* fix(s3): stamp mode and ownership on copy destinations

CopyObject and UploadPartCopy build the destination attributes themselves and
then assign them over the entry filer_pb.MkFile just stamped, so the copy
landed with mode 0000 and uid/gid 0 - unreadable on a mount even by the filer's
own user. Build the destination with the same mode PutObject resolves for the
request and the gateway's own ids.
This commit is contained in:
Chris Lu
2026-08-19 18:57:37 -07:00
committed by GitHub
parent 5d5fcdf07b
commit abd61de52c
2 changed files with 8 additions and 2 deletions
+6
View File
@@ -329,6 +329,9 @@ func (s3a *S3ApiServer) CopyObjectHandler(w http.ResponseWriter, r *http.Request
Mtime: t.Unix(),
Crtime: entry.Attributes.Crtime,
Mime: resolveDestinationMime(r.Header, entry.Attributes.Mime, replaceMeta),
FileMode: s3a.resolveFileMode(r),
Uid: filer_pb.OS_UID,
Gid: filer_pb.OS_GID,
},
Extended: make(map[string][]byte),
}
@@ -1030,6 +1033,9 @@ func (s3a *S3ApiServer) CopyObjectPartHandler(w http.ResponseWriter, r *http.Req
Mtime: t.Unix(),
Crtime: t.Unix(),
Mime: entry.Attributes.Mime,
FileMode: s3a.resolveFileMode(r),
Uid: filer_pb.OS_UID,
Gid: filer_pb.OS_GID,
},
Extended: make(map[string][]byte),
}
+2 -2
View File
@@ -694,8 +694,8 @@ func (s3a *S3ApiServer) putToFiler(r *http.Request, filePath string, dataReader
Crtime: now.Unix(),
Mtime: now.Unix(),
FileMode: fileMode,
Uid: 0,
Gid: 0,
Uid: filer_pb.OS_UID,
Gid: filer_pb.OS_GID,
Mime: mimeType,
FileSize: uint64(chunkResult.TotalSize),
TtlSec: lifecycleTTLSec,