Skip to content

Commit

Permalink
[release-branch.go1.18] io/fs: fix stack exhaustion in Glob
Browse files Browse the repository at this point in the history
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 golang#53720
Updates golang#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 <[email protected]>
(cherry picked from commit fdccc5d7bd0f276d0a8de3a818ca844f0bed5d97)
Reviewed-on: https://go-review.googlesource.com/c/go/+/417058
Run-TryBot: Michael Knyszek <[email protected]>
TryBot-Result: Gopher Robot <[email protected]>
Reviewed-by: Heschi Kreinick <[email protected]>
  • Loading branch information
julieqiu authored and bradfitz committed Jul 14, 2022
1 parent e82b129 commit ce3b008
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
14 changes: 12 additions & 2 deletions src/io/fs/glob.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
Expand Down
10 changes: 10 additions & 0 deletions src/io/fs/glob_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
. "io/fs"
"os"
"path"
"strings"
"testing"
)

Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit ce3b008

Please sign in to comment.