Merge pull request #101478 from Haleygo/fix-logs-with-too-long-name-request

fix return code when request /logs with long file name
This commit is contained in:
Kubernetes Prow Robot 2022-01-06 04:53:02 -08:00 committed by GitHub
commit 9cbfb2ac16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 68 additions and 0 deletions

View File

@ -18,7 +18,9 @@ package routes
import (
"net/http"
"os"
"path"
"syscall"
"github.com/emicklei/go-restful"
)
@ -42,6 +44,12 @@ func (l Logs) Install(c *restful.Container) {
func logFileHandler(req *restful.Request, resp *restful.Response) {
logdir := "/var/log"
actual := path.Join(logdir, req.PathParameter("logpath"))
// check filename length first, return 404 if it's oversize.
if logFileNameIsTooLong(actual) {
http.Error(resp, "file not found", http.StatusNotFound)
return
}
http.ServeFile(resp.ResponseWriter, req.Request, actual)
}
@ -49,3 +57,15 @@ func logFileListHandler(req *restful.Request, resp *restful.Response) {
logdir := "/var/log"
http.ServeFile(resp.ResponseWriter, req.Request, logdir)
}
// logFileNameIsTooLong checks filename length, returns true if it's longer than 255.
// cause http.ServeFile returns default error code 500 except for NotExist and Forbidden, but we need to separate the real 500 from oversize filename here.
func logFileNameIsTooLong(filePath string) bool {
_, err := os.Stat(filePath)
if err != nil {
if e, ok := err.(*os.PathError); ok && e.Err == syscall.ENAMETOOLONG {
return true
}
}
return false
}

48
pkg/routes/logs_test.go Normal file
View File

@ -0,0 +1,48 @@
/*
Copyright 2021 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package routes
import (
"fmt"
"os"
"testing"
)
func TestPreCheckLogFileNameLength(t *testing.T) {
oversizeFileName := fmt.Sprintf("%0256s", "a")
normalFileName := fmt.Sprintf("%0255s", "a")
// check file with oversize name.
if !logFileNameIsTooLong(oversizeFileName) {
t.Error("failed to check oversize filename")
}
// check file with normal name which doesn't exist.
if logFileNameIsTooLong(normalFileName) {
t.Error("failed to check normal filename")
}
// check file with normal name which does exist.
_, err := os.Create(normalFileName)
if err != nil {
t.Error("failed to create test file")
}
defer os.Remove(normalFileName)
if logFileNameIsTooLong(normalFileName) {
t.Error("failed to check normal filename")
}
}