]> Cypherpunks.ru repositories - gostls13.git/commitdiff
io/fs: fix stack exhaustion in Glob
authorJulie Qiu <julieqiu@google.com>
Thu, 23 Jun 2022 23:17:53 +0000 (23:17 +0000)
committerMichael Knyszek <mknyszek@google.com>
Tue, 12 Jul 2022 15:05:55 +0000 (15:05 +0000)
A limit is added to the number of path separators allowed by an input to
Glob, to prevent stack exhaustion issues.

Thanks to Juho Nurminen of Mattermost who reported a similar issue in
path/filepath.

Fixes CVE-2022-30630
Fixes golang/go#53415

Change-Id: I5a9d02591fed90cd3d52627f5945f1301e53465d
Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1497588
Reviewed-by: Roland Shoemaker <bracewell@google.com>
Reviewed-on: https://go-review.googlesource.com/c/go/+/417065
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Heschi Kreinick <heschi@google.com>
src/io/fs/glob.go
src/io/fs/glob_test.go

index 45d9cb61b9632af83bf9834ef99d47e6133b193b..0e529cd05d139e20e639a97cc5caa6cc440be033 100644 (file)
@@ -31,6 +31,16 @@ type GlobFS interface {
 // Otherwise, Glob uses ReadDir to traverse the directory tree
 // and look for matches for the pattern.
 func Glob(fsys FS, pattern string) (matches []string, err error) {
+       return globWithLimit(fsys, pattern, 0)
+}
+
+func globWithLimit(fsys FS, pattern string, depth int) (matches []string, err error) {
+       // This limit is added to prevent stack exhaustion issues. See
+       // CVE-2022-30630.
+       const pathSeparatorsLimit = 10000
+       if depth > pathSeparatorsLimit {
+               return nil, path.ErrBadPattern
+       }
        if fsys, ok := fsys.(GlobFS); ok {
                return fsys.Glob(pattern)
        }
@@ -59,9 +69,9 @@ func Glob(fsys FS, pattern string) (matches []string, err error) {
        }
 
        var m []string
-       m, err = Glob(fsys, dir)
+       m, err = globWithLimit(fsys, dir, depth+1)
        if err != nil {
-               return
+               return nil, err
        }
        for _, d := range m {
                matches, err = glob(fsys, d, file, matches)
index f19bebed77f6c7c7e9fad7017b94b9c557a77bca..d052eab371366f00a17692774c87fec260b89946 100644 (file)
@@ -8,6 +8,7 @@ import (
        . "io/fs"
        "os"
        "path"
+       "strings"
        "testing"
 )
 
@@ -55,6 +56,15 @@ func TestGlobError(t *testing.T) {
        }
 }
 
+func TestCVE202230630(t *testing.T) {
+       // Prior to CVE-2022-30630, a stack exhaustion would occur given a large
+       // number of separators. There is now a limit of 10,000.
+       _, err := Glob(os.DirFS("."), "/*"+strings.Repeat("/", 10001))
+       if err != path.ErrBadPattern {
+               t.Fatalf("Glob returned err=%v, want %v", err, path.ErrBadPattern)
+       }
+}
+
 // contains reports whether vector contains the string s.
 func contains(vector []string, s string) bool {
        for _, elem := range vector {