Skip to content

Commit 4bac43a

Browse files
authored
zstd: Fix quick reject on long backmatches (#787)
When m.s was extended far back we could read out of bounds. Fixes #786 Re-enables accidentally disabled fuzz tests.
1 parent 31b99fb commit 4bac43a

File tree

4 files changed

+32
-15
lines changed

4 files changed

+32
-15
lines changed

.github/workflows/go.yml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,15 @@ jobs:
3535
- name: Test Noasm
3636
run: go test -tags=noasm ./...
3737

38-
- name: Test Race
38+
- name: Test Race 1 CPU
3939
env:
4040
CGO_ENABLED: 1
41-
run: go test -cpu="1,4" -short -race -v ./...
41+
run: go test -cpu=1 -short -race -v ./...
42+
43+
- name: Test Race 4 CPU
44+
env:
45+
CGO_ENABLED: 1
46+
run: go test -cpu=4 -short -race -v ./...
4247

4348
generate:
4449
strategy:
@@ -163,7 +168,7 @@ jobs:
163168
run: go test -run=none -fuzz=FuzzNoBMI2Dec -fuzztime=500000x -test.fuzzminimizetime=10ms ./zstd/.
164169

165170
- name: zstd/FuzzEncoding
166-
run: go test -run=none -fuzz=FuzzEncoding -fuzztime=250000x -test.fuzzminimizetime=10ms ./zstd/.
171+
run: cd zstd&&go test -run=none -fuzz=FuzzEncoding -fuzztime=250000x -test.fuzzminimizetime=10ms -fuzz-end=3&&cd ..
167172

168173
- name: zstd/FuzzDecodeAll/noasm
169174
run: go test -tags=noasm -run=none -fuzz=FuzzDecodeAll -fuzztime=500000x -test.fuzzminimizetime=10ms ./zstd/.
@@ -172,7 +177,10 @@ jobs:
172177
run: go test -tags=noasm -run=none -fuzz=FuzzDecoder -fuzztime=500000x -test.fuzzminimizetime=10ms ./zstd/.
173178

174179
- name: zstd/FuzzEncoding/noasm
175-
run: go test -tags=noasm -run=none -fuzz=FuzzEncoding -fuzztime=250000x -test.fuzzminimizetime=10ms ./zstd/.
180+
run: cd zstd&&go test -tags=noasm -run=none -fuzz=FuzzEncoding -fuzztime=250000x -test.fuzzminimizetime=10ms -fuzz-end=3&&cd ..
181+
182+
- name: zstd/FuzzEncodingBest
183+
run: cd zstd&&go test -run=none -fuzz=FuzzEncoding -fuzztime=25000x -test.fuzzminimizetime=10ms -fuzz-start=4&&cd ..
176184

177185
fuzz-other:
178186
env:

zstd/enc_best.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,11 @@ encodeLoop:
212212
if left <= 0 {
213213
return
214214
}
215-
if left > 2 {
215+
checkLen := m.length - (s - m.s) - 8
216+
if left > 2 && checkLen > 4 {
216217
// Check 4 bytes, 4 bytes from the end of the current match.
217-
a := load3232(src, offset+m.length-8)
218-
b := load3232(src, s+m.length-8)
218+
a := load3232(src, offset+checkLen)
219+
b := load3232(src, s+checkLen)
219220
if a != b {
220221
return
221222
}

zstd/fuzz_test.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -133,13 +133,10 @@ func FuzzEncoding(f *testing.F) {
133133
const (
134134
// Test a subset of encoders.
135135
startFuzz = SpeedFastest
136-
endFuzz = SpeedBetterCompression
136+
endFuzz = SpeedBestCompression
137137

138138
// Also tests with dictionaries...
139139
testDicts = true
140-
141-
// Max input size:
142-
maxSize = 1 << 20
143140
)
144141

145142
var dec *Decoder
@@ -152,16 +149,20 @@ func FuzzEncoding(f *testing.F) {
152149
dicts = readDicts(f, zr)
153150
}
154151

152+
if testing.Short() && *fuzzEndF > int(SpeedBetterCompression) {
153+
*fuzzEndF = int(SpeedBetterCompression)
154+
}
155+
155156
initEnc := func() func() {
156157
var err error
157-
dec, err = NewReader(nil, WithDecoderConcurrency(2), WithDecoderDicts(dicts...), WithDecoderMaxWindow(64<<10), WithDecoderMaxMemory(maxSize))
158+
dec, err = NewReader(nil, WithDecoderConcurrency(2), WithDecoderDicts(dicts...), WithDecoderMaxWindow(64<<10), WithDecoderMaxMemory(uint64(*fuzzMaxF)))
158159
if err != nil {
159160
panic(err)
160161
}
161162
for level := startFuzz; level <= endFuzz; level++ {
162163
encs[level], err = NewWriter(nil, WithEncoderCRC(true), WithEncoderLevel(level), WithEncoderConcurrency(2), WithWindowSize(64<<10), WithZeroFrames(true), WithLowerEncoderMem(true))
163164
if testDicts {
164-
encsD[level], err = NewWriter(nil, WithEncoderCRC(true), WithEncoderLevel(level), WithEncoderConcurrency(2), WithWindowSize(64<<10), WithZeroFrames(true), WithEncoderDict(dicts[level]), WithLowerEncoderMem(true), WithLowerEncoderMem(true))
165+
encsD[level], err = NewWriter(nil, WithEncoderCRC(true), WithEncoderLevel(level), WithEncoderConcurrency(2), WithWindowSize(64<<10), WithZeroFrames(true), WithEncoderDict(dicts[int(level)%len(dicts)]), WithLowerEncoderMem(true), WithLowerEncoderMem(true))
165166
}
166167
}
167168
return func() {
@@ -193,7 +194,7 @@ func FuzzEncoding(f *testing.F) {
193194
t.Fatalf("%v:\n%v", r, string(stack))
194195
}
195196
}()
196-
if len(data) > maxSize {
197+
if len(data) > *fuzzMaxF {
197198
return
198199
}
199200
var bufSize = len(data)
@@ -205,7 +206,7 @@ func FuzzEncoding(f *testing.F) {
205206
}
206207
}
207208

208-
for level := startFuzz; level <= endFuzz; level++ {
209+
for level := *fuzzStartF; level <= *fuzzEndF; level++ {
209210
enc := encs[level]
210211
dst.Reset()
211212
enc.Reset(&dst)

zstd/zstd_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package zstd
55

66
import (
7+
"flag"
78
"fmt"
89
"os"
910
"runtime"
@@ -14,7 +15,13 @@ import (
1415

1516
var isRaceTest bool
1617

18+
// Fuzzing tweaks:
19+
var fuzzStartF = flag.Int("fuzz-start", int(SpeedFastest), "Start fuzzing at this level")
20+
var fuzzEndF = flag.Int("fuzz-end", int(SpeedBestCompression), "End fuzzing at this level (inclusive)")
21+
var fuzzMaxF = flag.Int("fuzz-max", 1<<20, "Maximum input size")
22+
1723
func TestMain(m *testing.M) {
24+
flag.Parse()
1825
ec := m.Run()
1926
if ec == 0 && runtime.NumGoroutine() > 2 {
2027
n := 0

0 commit comments

Comments
 (0)