mirror of
https://github.com/pgsty/minio.git
synced 2026-08-09 07:43:29 +03:00
fix(storage): validate internode paths and erasure payloads
Storage REST request bodies and Grid RPC frames bypass the HTTP validity middleware, allowing wire-supplied paths and malformed FileInfo values to reach xlStorage unchecked. Wrap the remotely exposed StorageAPI with a guard that covers every path-bearing method, including nested metadata fields. Reject traversal and destructive volume-root aliases before path cleaning can erase them, and validate erasure geometry and part sizes at the same wire boundary. Keep a raw-volume check in getVolDir for peer-S3 calls that bypass the wrapper. Reflection, fuzz, traversal, peer-S3, compatibility, and malformed-erasure tests pin the complete method surface and prove that legal object names remain accepted. Co-authored-by: ChatGPT <noreply@openai.com> Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -75,6 +75,10 @@ var (
|
||||
storageListDirRPC = grid.NewStream[*grid.MSS, grid.NoPayload, *ListDirResult](grid.HandlerListDir, grid.NewMSS, nil, func() *ListDirResult { return &ListDirResult{} }).WithOutCapacity(1)
|
||||
)
|
||||
|
||||
// getStorageViaEndpoint returns the drive UNGUARDED. It is for local callers
|
||||
// only, whose arguments the server itself constructed. Anything serving a
|
||||
// remote peer must go through storageRESTServer.getStorage(), which wraps this
|
||||
// in guardedStorage to reject traversal in wire-supplied paths.
|
||||
func getStorageViaEndpoint(endpoint Endpoint) StorageAPI {
|
||||
globalLocalDrivesMu.RLock()
|
||||
defer globalLocalDrivesMu.RUnlock()
|
||||
@@ -85,7 +89,18 @@ func getStorageViaEndpoint(endpoint Endpoint) StorageAPI {
|
||||
}
|
||||
|
||||
func (s *storageRESTServer) getStorage() StorageAPI {
|
||||
return getStorageViaEndpoint(s.endpoint)
|
||||
st := getStorageViaEndpoint(s.endpoint)
|
||||
if st == nil {
|
||||
// Must stay an untyped nil. IsAuthValid and checkID compare the result
|
||||
// against nil before authenticating, and a nil interface wrapped in a
|
||||
// value struct does not compare equal to nil - that would turn an
|
||||
// unauthenticated request against a drive that has not come up yet
|
||||
// into a nil dereference.
|
||||
return nil
|
||||
}
|
||||
// Reject traversal in paths carried by request bodies and grid RPC frames,
|
||||
// neither of which the global HTTP middleware can see. See guardedStorage.
|
||||
return guardedStorage{st}
|
||||
}
|
||||
|
||||
func (s *storageRESTServer) writeErrorResponse(w http.ResponseWriter, err error) {
|
||||
|
||||
Reference in New Issue
Block a user