Skip to content

Commit e9b5dbb

Browse files
committed
Add fuzzer for dbm module
1 parent 71ede86 commit e9b5dbb

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
all : fuzzer-html fuzzer-email fuzzer-httpclient fuzzer-json fuzzer-difflib fuzzer-csv fuzzer-decode fuzzer-ast fuzzer-tarfile fuzzer-tarfile-hypothesis fuzzer-zipfile fuzzer-zipfile-hypothesis fuzzer-re fuzzer-configparser fuzzer-tomllib fuzzer-plistlib fuzzer-xml fuzzer-zoneinfo
1+
all : fuzzer-html fuzzer-email fuzzer-httpclient fuzzer-json fuzzer-difflib fuzzer-csv fuzzer-decode fuzzer-ast fuzzer-tarfile fuzzer-tarfile-hypothesis fuzzer-zipfile fuzzer-zipfile-hypothesis fuzzer-re fuzzer-configparser fuzzer-tomllib fuzzer-plistlib fuzzer-xml fuzzer-zoneinfo fuzzer-dbm
22

33
PYTHON_CONFIG_PATH=$(CPYTHON_INSTALL_PATH)/bin/python3-config
44
CXXFLAGS += $(shell $(PYTHON_CONFIG_PATH) --cflags)
5-
LDFLAGS += -rdynamic $(shell $(PYTHON_CONFIG_PATH) --ldflags --embed)
5+
LDFLAGS += -rdynamic $(shell $(PYTHON_CONFIG_PATH) --ldflags --embed) $(CPYTHON_MODLIBS) -Wl,--allow-multiple-definition
66

77
fuzzer-html:
88
clang++ $(CXXFLAGS) $(LIB_FUZZING_ENGINE) -std=c++17 fuzzer.cpp -DPYTHON_HARNESS_PATH="\"html.py\"" -ldl $(LDFLAGS) -o fuzzer-html
@@ -40,3 +40,6 @@ fuzzer-xml:
4040
clang++ $(CXXFLAGS) $(LIB_FUZZING_ENGINE) -std=c++17 fuzzer.cpp -DPYTHON_HARNESS_PATH="\"xml.py\"" -ldl $(LDFLAGS) -o fuzzer-xml
4141
fuzzer-zoneinfo:
4242
clang++ $(CXXFLAGS) $(LIB_FUZZING_ENGINE) -std=c++17 fuzzer.cpp -DPYTHON_HARNESS_PATH="\"zoneinfo.py\"" -ldl $(LDFLAGS) -o fuzzer-zoneinfo
43+
44+
fuzzer-dbm:
45+
clang++ $(CXXFLAGS) $(LIB_FUZZING_ENGINE) -std=c++17 fuzzer.cpp -DPYTHON_HARNESS_PATH="\"dbm.py\"" -ldl $(LDFLAGS) -o fuzzer-dbm

dbm.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from fuzzeddataprovider import FuzzedDataProvider
2+
import os
3+
import dbm
4+
import tempfile
5+
6+
OP_STORE = 0
7+
OP_GET = 1
8+
OP_LIST_KEYS = 2
9+
OP_DELETE = 3
10+
OP_ITERATE = 4
11+
12+
13+
# Fuzzes the _gdbm C module (Modules/_gdbmmodule.c).
14+
# Exercises key-value store operations on a temporary GDBM database:
15+
# store, get, key listing, deletion, and iteration with fuzzed
16+
# keys and values.
17+
def FuzzerRunOne(FuzzerInput):
18+
if len(FuzzerInput) < 1 or len(FuzzerInput) > 0x10000:
19+
return
20+
fdp = FuzzedDataProvider(FuzzerInput)
21+
try:
22+
with tempfile.TemporaryDirectory() as tmpdir:
23+
dbpath = os.path.join(tmpdir, "fuzzdb")
24+
with dbm.open(dbpath, "c") as db:
25+
num_ops = fdp.ConsumeIntInRange(1, 20)
26+
for _ in range(num_ops):
27+
if fdp.remaining_bytes() == 0:
28+
break
29+
op = fdp.ConsumeIntInRange(OP_STORE, OP_ITERATE)
30+
if op == OP_STORE:
31+
n = fdp.ConsumeIntInRange(1, min(fdp.remaining_bytes(), 100))
32+
key = fdp.ConsumeBytes(n)
33+
n2 = (
34+
fdp.ConsumeIntInRange(1, min(fdp.remaining_bytes(), 1000))
35+
if fdp.remaining_bytes() > 0
36+
else 0
37+
)
38+
val = fdp.ConsumeBytes(n2) if n2 > 0 else b""
39+
db[key] = val
40+
elif op == OP_GET:
41+
n = fdp.ConsumeIntInRange(1, min(fdp.remaining_bytes(), 100))
42+
key = fdp.ConsumeBytes(n)
43+
_ = db.get(key)
44+
elif op == OP_LIST_KEYS:
45+
_ = list(db.keys())
46+
elif op == OP_DELETE:
47+
n = fdp.ConsumeIntInRange(1, min(fdp.remaining_bytes(), 100))
48+
key = fdp.ConsumeBytes(n)
49+
if key in db:
50+
del db[key]
51+
elif op == OP_ITERATE:
52+
for k in db:
53+
_ = db[k]
54+
break
55+
except Exception:
56+
pass

fuzz_targets.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
ast ast.py
22
configparser configparser.py
33
csv csv.py
4+
dbm dbm.py
45
decode decode.py
56
difflib difflib.py
67
email email.py

0 commit comments

Comments
 (0)