aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulie Qiu <julieqiu@google.com>2022-06-23 23:17:53 +0000
committerMichael Knyszek <mknyszek@google.com>2022-07-12 15:20:37 +0000
commit8c1d8c836270615cfb5b229932269048ef59ac07 (patch)
tree2137c8220879aa479bcf56198a297918265f7991
parent0117dee7dccbbd7803d88f65a2ce8bd686219ad3 (diff)
downloadgo-8c1d8c836270615cfb5b229932269048ef59ac07.tar.gz
go-8c1d8c836270615cfb5b229932269048ef59ac07.zip
[release-branch.go1.17] io/fs: fix stack exhaustion in Glob
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 #53719 Updates #53415 Fixes CVE-2022-30630 Change-Id: I5a9d02591fed90cd3d52627f5945f1301e53465d Reviewed-on: https://team-review.git.corp.google.com/c/golang/go-private/+/1497588 Reviewed-by: Roland Shoemaker <bracewell@google.com> (cherry picked from commit fdccc5d7bd0f276d0a8de3a818ca844f0bed5d97) Reviewed-on: https://go-review.googlesource.com/c/go/+/417072 Reviewed-by: Heschi Kreinick <heschi@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Michael Knyszek <mknyszek@google.com>
-rw-r--r--src/io/fs/glob.go14
-rw-r--r--src/io/fs/glob_test.go10
2 files changed, 22 insertions, 2 deletions
diff --git a/src/io/fs/glob.go b/src/io/fs/glob.go
index 45d9cb61b9..0e529cd05d 100644
--- a/src/io/fs/glob.go
+++ b/src/io/fs/glob.go
@@ -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)
diff --git a/src/io/fs/glob_test.go b/src/io/fs/glob_test.go
index f19bebed77..d052eab371 100644
--- a/src/io/fs/glob_test.go
+++ b/src/io/fs/glob_test.go
@@ -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 {