From 3e3ff2a70be26a2612aa1d6ac28aa3aff4d83fbc Mon Sep 17 00:00:00 2001 From: Klaus Post Date: Mon, 2 May 2022 10:36:29 -0700 Subject: [PATCH] Check error status codes (#14850) If an invalid status code is generated from an error we risk panicking. Even if there are no potential problems at the moment we should prevent this in the future. Add safeguards against this. Sample trace: ``` May 02 06:41:39 minio[52806]: panic: "GET /20180401230655.PDF": invalid WriteHeader code 0 May 02 06:41:39 minio[52806]: goroutine 16040430822 [running]: May 02 06:41:39 minio[52806]: runtime/debug.Stack(0xc01fff7c20, 0x25c4b00, 0xc0490e4080) May 02 06:41:39 minio[52806]: runtime/debug/stack.go:24 +0x9f May 02 06:41:39 minio[52806]: github.com/minio/minio/cmd.setCriticalErrorHandler.func1.1(0xc022048800, 0x4f38ab0, 0xc0406e0fc0) May 02 06:41:39 minio[52806]: github.com/minio/minio/cmd/generic-handlers.go:469 +0x85 May 02 06:41:39 minio[52806]: panic(0x25c4b00, 0xc0490e4080) May 02 06:41:39 minio[52806]: runtime/panic.go:965 +0x1b9 May 02 06:41:39 minio[52806]: net/http.checkWriteHeaderCode(...) May 02 06:41:39 minio[52806]: net/http/server.go:1092 May 02 06:41:39 minio[52806]: net/http.(*response).WriteHeader(0xc0406e0fc0, 0x0) May 02 06:41:39 minio[52806]: net/http/server.go:1126 +0x718 May 02 06:41:39 minio[52806]: github.com/minio/minio/internal/logger.(*ResponseWriter).WriteHeader(0xc032fa3ea0, 0x0) May 02 06:41:39 minio[52806]: github.com/minio/minio/internal/logger/audit.go:116 +0xb1 May 02 06:41:39 minio[52806]: github.com/minio/minio/internal/logger.(*ResponseWriter).WriteHeader(0xc032fa3f40, 0x0) May 02 06:41:39 minio[52806]: github.com/minio/minio/internal/logger/audit.go:116 +0xb1 May 02 06:41:39 minio[52806]: github.com/minio/minio/internal/logger.(*ResponseWriter).WriteHeader(0xc002ce8000, 0x0) May 02 06:41:39 minio[52806]: github.com/minio/minio/internal/logger/audit.go:116 +0xb1 May 02 06:41:39 minio[52806]: github.com/minio/minio/cmd.writeResponse(0x4f364a0, 0xc002ce8000, 0x0, 0xc0443b86c0, 0x1cb, 0x224, 0x2a9651e, 0xf) May 02 06:41:39 minio[52806]: github.com/minio/minio/cmd/api-response.go:736 +0x18d May 02 06:41:39 minio[52806]: github.com/minio/minio/cmd.writeErrorResponse(0x4f44218, 0xc069086ae0, 0x4f364a0, 0xc002ce8000, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc00656afc0) May 02 06:41:39 minio[52806]: github.com/minio/minio/cmd/api-response.go:798 +0x306 May 02 06:41:39 minio[52806]: github.com/minio/minio/cmd.objectAPIHandlers.getObjectHandler(0x4b73768, 0x4b73730, 0x4f44218, 0xc069086ae0, 0x4f82090, 0xc002d80620, 0xc040e03885, 0xe, 0xc040e03894, 0x61, ...) May 02 06:41:39 minio[52806]: github.com/minio/minio/cmd/object-handlers.go:456 +0x252c ``` --- cmd/api-response.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cmd/api-response.go b/cmd/api-response.go index 86fa2d857..f39a0ed3d 100644 --- a/cmd/api-response.go +++ b/cmd/api-response.go @@ -728,6 +728,14 @@ func generateMultiDeleteResponse(quiet bool, deletedObjects []DeletedObject, err } func writeResponse(w http.ResponseWriter, statusCode int, response []byte, mType mimeType) { + if statusCode == 0 { + statusCode = 200 + } + // Similar check to http.checkWriteHeaderCode + if statusCode < 100 || statusCode > 999 { + logger.Error(fmt.Sprintf("invalid WriteHeader code %v", statusCode)) + statusCode = http.StatusInternalServerError + } setCommonHeaders(w) if mType != mimeNone { w.Header().Set(xhttp.ContentType, string(mType)) @@ -791,6 +799,12 @@ func writeErrorResponse(ctx context.Context, w http.ResponseWriter, err APIError err.Description = fmt.Sprintf("The authorization header is malformed; the region is wrong; expecting '%s'.", globalSite.Region) } + // Similar check to http.checkWriteHeaderCode + if err.HTTPStatusCode < 100 || err.HTTPStatusCode > 999 { + logger.Error(fmt.Sprintf("invalid WriteHeader code %v from %v", err.HTTPStatusCode, err.Code)) + err.HTTPStatusCode = http.StatusInternalServerError + } + // Generate error response. errorResponse := getAPIErrorResponse(ctx, err, reqURL.Path, w.Header().Get(xhttp.AmzRequestID), globalDeploymentID)