| 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, |