| Change 621067117 by sungyc@sungyc:fig-export-icing-153-change-479:7398:citc on 2024/04/01 23:29:44 |
| |
| [hunspell][vulnerability fix] Fix memory freeing on uninitialized address value |
| |
| ## Test plan |
| ``` |
| sso_client -location 'https://clusterfuzz.corp.google.com/testcase-detail/download-testcase?id=5472705942454272' > /tmp/testcase-5472705942454272 && \ |
| blaze --blazerc=/dev/null test -c opt --config=fuzztest-msan --copt=-DNDEBUG \ |
| --test_strategy=local \ |
| --test_sharding_strategy=disabled \ |
| --test_env=FUZZTEST_REPLAY=/tmp/testcase-5472705942454272 \ |
| --test_filter=LLVMFuzzer.TestOneInput \ |
| //third_party/hunspell/fuzzers:dict_fuzzer |
| ``` |
| |
| ## Description |
| This bug is "use-of-uninitialized-value", caused by using (freeing) uninitialized address in `reptable[j].pattern`. |
| - Use calloc for `reptable` to initialize all members to 0, so `reptable[j].pattern` will have NULL value. |
| - Add NULL check before `free()`. |
| - Change `reptable[j].pattern` to NULL after `free()`, to avoid double free error (except for destructor). |
| |
| PRESUBMIT=passed |
| BUG=325665488 |
| R=mghiware |
| APPROVED=mghiware |
| REQUIRED_REVIEW=1 |
| DELTA=11 (8 added, 0 deleted, 3 changed) |
| DELTA_BY_EXTENSION=cxx=11 |
| OCL=621036222 |
| FIG_CHANGESET=ed6bff931bde83fdddfff0d9a7e060af03209ee2 |
| FIG_WORKSPACE=sungyc/153:icing |
| MARKDOWN=true |
| |
| Affected files ... |
| |
| ... //depot//src/hunspell/affixmgr.cxx#19 edit |
| |
| ==== //depot//src/hunspell/affixmgr.cxx#18 - /google/src/files/621067117/depot//src/hunspell/affixmgr.cxx ==== |
| --- /google/src/files/615029530/depot//src/hunspell/affixmgr.cxx 2024-03-12 10:13:27.000000000 -0400 |
| +++ /google/src/files/621067117/depot//src/hunspell/affixmgr.cxx 2024-04-02 02:29:44.000000000 -0400 |
| @@ -179,9 +179,13 @@ |
| numbreak = 0; |
| if (reptable) { |
| for (int j=0; j < numrep; j++) { |
| + if (reptable[j].pattern) { |
| free(reptable[j].pattern); |
| + } |
| + if (reptable[j].pattern2) { |
| free(reptable[j].pattern2); |
| } |
| + } |
| free(reptable); |
| reptable = NULL; |
| } |
| @@ -3601,7 +3605,7 @@ |
| HUNSPELL_WARNING(stderr, "error: line %d: incorrect entry number\n", af->getlinenum()); |
| return 1; |
| } |
| - reptable = (replentry *) malloc(numrep * sizeof(struct replentry)); |
| + reptable = (replentry *) calloc(numrep, sizeof(replentry)); |
| if (!reptable) return 1; |
| np++; |
| break; |
| @@ -3661,9 +3665,13 @@ |
| for (int k=0; k < j; k++) { |
| free(reptable[k].pattern); |
| free(reptable[k].pattern2); |
| + reptable[k].pattern = NULL; |
| + reptable[k].pattern2 = NULL; |
| } |
| if (reptable[j].pattern) free(reptable[j].pattern); |
| if (reptable[j].pattern2) free(reptable[j].pattern2); |
| + reptable[j].pattern = NULL; |
| + reptable[j].pattern2 = NULL; |
| numrep = 0; |
| return 1; |
| } |