blob: 8dfad7dd42ba610696213b6fc94abbf2941a9d5e [file] [log] [blame] [edit]
Change 542907937 by sungyc@sungyc:fig-export-icing-153-change-362:5570:citc on 2023/06/23 11:09:48
[hunspell] Fix bad numaliasm which causes out of memory error
## Test plan
```
sso_client -location 'https://clusterfuzz.corp.google.com/testcase-detail/download-testcase?id=5985909065252864' > /tmp/testcase-5985909065252864 && \
blaze --blazerc=/dev/null test --config=asan-fuzzer --test_strategy=local --test_sharding_strategy=disabled \
--test_env=ENABLE_BLAZE_TEST_FUZZING=1 --test_arg=-rss_limit_mb=2560 --test_arg=-timeout=90 --test_arg=-runs=100 --test_arg=/tmp/testcase-5985909065252864 \
//third_party/hunspell/fuzzers:dict_fuzzer
```
## Description
This problem is triggered by bad `numaliasm` (the test data has 328420866).
- We succeeded to allocate `328420866 * sizeof(char *)` in the first round of test, but due to some issues (probably free() delay?), the allocation in the second round fails.
- Since:
- It is unlikely to have such large input.
- We've limited the input byte size in the test (see [codeptr](https://source.corp.google.com/piper///depot//fuzzers/dict_fuzzer.cc;l=9-11)) to be at most `2 << 13` (it is 2^14, 16384 actually).
- Let's add `kMaxNumAliasm` and enforce the check. Use 65536 as the limit.
PRESUBMIT=passed
BUG=280375760
R=tjbarron
CC=mghiware
APPROVED=tjbarron
REQUIRED_REVIEW=1
DELTA=8 (6 added, 0 deleted, 2 changed)
DELTA_BY_EXTENSION=cxx=6,hxx=2
OCL=540730895
FIG_CHANGESET=553a88a54a5f92d4fc948f5c616238bb0cd91ee7
FIG_WORKSPACE=sungyc/153:icing
MARKDOWN=true
Affected files ...
... //depot//src/hunspell/hashmgr.cxx#11 edit
... //depot//src/hunspell/hashmgr.hxx#4 edit
==== //depot//src/hunspell/hashmgr.cxx#10 - /google/src/files/542907937/depot//src/hunspell/hashmgr.cxx ====
--- /google/src/files/541956676/depot//src/hunspell/hashmgr.cxx 2023-06-20 12:47:53.000000000 -0400
+++ /google/src/files/542907937/depot//src/hunspell/hashmgr.cxx 2023-06-23 14:09:48.000000000 -0400
@@ -34,7 +34,11 @@
numaliasm = 0;
aliasm = NULL;
forbiddenword = FORBIDDENWORD; // forbidden word signing flag
- load_config(apath, key);
+ if (load_config(apath, key)) {
+ // Early return if load config fails.
+ return;
+ }
+
int ec = load_tables(tpath, key);
if (ec) {
/* error condition - what should we do here */
@@ -840,7 +844,7 @@
case 0: { np++; break; }
case 1: {
numaliasm = atoi(piece);
- if (numaliasm < 1) {
+ if (numaliasm < 1 || numaliasm > kMaxNumAliasm) {
free_aliasm();
HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n", af->getlinenum());
return 1;
==== //depot//src/hunspell/hashmgr.hxx#3 - /google/src/files/542907937/depot//src/hunspell/hashmgr.hxx ====
--- /google/src/files/541956676/depot//src/hunspell/hashmgr.hxx 2023-06-20 12:47:53.000000000 -0400
+++ /google/src/files/542907937/depot//src/hunspell/hashmgr.hxx 2023-06-23 14:09:48.000000000 -0400
@@ -53,6 +53,8 @@
char * get_aliasm(int index);
private:
+ static constexpr int kMaxNumAliasm = 1 << 16; // 65536
+
int get_clen_and_captype(const char * word, int wbl, int * captype);
int load_tables(const char * tpath, const char * key);
int add_word(const char * word, int wbl, int wcl, unsigned short * ap,