1
0
mirror of https://github.com/golang/go synced 2024-11-27 04:11:22 -07:00

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 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>
This commit is contained in:
Julie Qiu 2022-06-23 23:17:53 +00:00 committed by Michael Knyszek
parent 6fa37e98ea
commit fa2d41d0ca
2 changed files with 22 additions and 2 deletions

View 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)

View 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 {