src/path/filepath/match.go | 12 +++++++++++- src/path/filepath/match_test.go | 10 ++++++++++ diff --git a/src/path/filepath/match.go b/src/path/filepath/match.go index c77a26952a657f2c53bd9dafbf98deb4a7071f56..55ed1d75ae1b0eb4f579652c04727315b77dcace 100644 --- a/src/path/filepath/match.go +++ b/src/path/filepath/match.go @@ -241,6 +241,16 @@ // Glob ignores file system errors such as I/O errors reading directories. // The only possible returned error is ErrBadPattern, when pattern // is malformed. func Glob(pattern string) (matches []string, err error) { + return globWithLimit(pattern, 0) +} + +func globWithLimit(pattern string, depth int) (matches []string, err error) { + // This limit is used prevent stack exhaustion issues. See CVE-2022-30632. + const pathSeparatorsLimit = 10000 + if depth == pathSeparatorsLimit { + return nil, ErrBadPattern + } + // Check pattern is well-formed. if _, err := Match(pattern, ""); err != nil { return nil, err @@ -270,7 +280,7 @@ return nil, ErrBadPattern } var m []string - m, err = Glob(dir) + m, err = globWithLimit(dir, depth+1) if err != nil { return } diff --git a/src/path/filepath/match_test.go b/src/path/filepath/match_test.go index 375c41a7e9d5d06615ba59451850bc8c552b45a9..d6282596fedbb93aeabc93fdc8029d43266098ae 100644 --- a/src/path/filepath/match_test.go +++ b/src/path/filepath/match_test.go @@ -155,6 +155,16 @@ } } } +func TestCVE202230632(t *testing.T) { + // Prior to CVE-2022-30632, this would cause a stack exhaustion given a + // large number of separators (more than 4,000,000). There is now a limit + // of 10,000. + _, err := Glob("/*" + strings.Repeat("/", 10001)) + if err != ErrBadPattern { + t.Fatalf("Glob returned err=%v, want ErrBadPattern", err) + } +} + func TestGlobError(t *testing.T) { bad := []string{`[]`, `nonexist/[]`} for _, pattern := range bad {