Memory leaks in function vim_strsave in vim/vim


Reported on

Jun 16th 2022


Memory leaks in function vim_strsave at strings.c:27

vim version

git log
commit 83497f875881973df772cc4cc593766345df6c4a (HEAD -> master, tag: v8.2.5105, origin/master, origin/HEAD)


root@fuzz-vm0-187:/home/fuzz/fuzz/vim/afl/src# ./vim -u NONE -i NONE -n -m -X -Z -e -s -S /mnt/share/max/fuzz/poc/vim/poc_ml3_s.dat -c :qa!

==31529==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 8 byte(s) in 4 object(s) allocated from:
    #0 0x499cad in malloc (/home/fuzz/fuzz/vim/afl/src/vim+0x499cad)
    #1 0x4cb382 in lalloc /home/fuzz/fuzz/vim/afl/src/alloc.c:246:11
    #2 0x4cb26a in alloc /home/fuzz/fuzz/vim/afl/src/alloc.c:151:12
    #3 0xf8cbd6 in vim_strsave /home/fuzz/fuzz/vim/afl/src/strings.c:27:9
    #4 0x6a6984 in typval2string /home/fuzz/fuzz/vim/afl/src/eval.c:502:11
    #5 0x6a6d7f in eval_to_string_eap /home/fuzz/fuzz/vim/afl/src/eval.c:528:11
    #6 0x6a6e9f in eval_to_string /home/fuzz/fuzz/vim/afl/src/eval.c:541:12
    #7 0xcec814 in vim_regsub_both /home/fuzz/fuzz/vim/afl/src/regexp.c:2049:17
    #8 0xcf06eb in vim_regsub_multi /home/fuzz/fuzz/vim/afl/src/regexp.c:1915:14
    #9 0x7b3650 in ex_substitute /home/fuzz/fuzz/vim/afl/src/ex_cmds.c:4420:12
    #10 0x7dd249 in do_one_cmd /home/fuzz/fuzz/vim/afl/src/ex_docmd.c:2570:2
    #11 0x7ca105 in do_cmdline /home/fuzz/fuzz/vim/afl/src/ex_docmd.c:992:17
    #12 0x115857c in call_user_func /home/fuzz/fuzz/vim/afl/src/userfunc.c:2900:2
    #13 0x115466d in call_user_func_check /home/fuzz/fuzz/vim/afl/src/userfunc.c:3048:2
    #14 0x114ea14 in call_func /home/fuzz/fuzz/vim/afl/src/userfunc.c:3612:11
    #15 0x114bdb3 in get_func_tv /home/fuzz/fuzz/vim/afl/src/userfunc.c:1833:8
    #16 0x6e4b90 in eval_func /home/fuzz/fuzz/vim/afl/src/eval.c:2113:8
    #17 0x6e2cfe in eval9 /home/fuzz/fuzz/vim/afl/src/eval.c:4027:9
    #18 0x6eea19 in eval8 /home/fuzz/fuzz/vim/afl/src/eval.c:3596:11
    #19 0x6ec808 in eval7 /home/fuzz/fuzz/vim/afl/src/eval.c:3388:9
    #20 0x6e975f in eval6 /home/fuzz/fuzz/vim/afl/src/eval.c:3151:9
    #21 0x6e82b2 in eval5 /home/fuzz/fuzz/vim/afl/src/eval.c:3040:9
    #22 0x6e6aac in eval4 /home/fuzz/fuzz/vim/afl/src/eval.c:2891:9
    #23 0x6e51af in eval3 /home/fuzz/fuzz/vim/afl/src/eval.c:2752:9
    #24 0x6c0b9f in eval2 /home/fuzz/fuzz/vim/afl/src/eval.c:2626:9
    #25 0x6a2aff in eval1 /home/fuzz/fuzz/vim/afl/src/eval.c:2472:9
    #26 0x6bfa55 in eval0_retarg /home/fuzz/fuzz/vim/afl/src/eval.c:2389:11
    #27 0x6a0097 in eval0 /home/fuzz/fuzz/vim/afl/src/eval.c:2364:12
    #28 0x6a6cf5 in eval_to_string_eap /home/fuzz/fuzz/vim/afl/src/eval.c:524:9
    #29 0x6a6e9f in eval_to_string /home/fuzz/fuzz/vim/afl/src/eval.c:541:12

SUMMARY: AddressSanitizer: 8 byte(s) leaked in 4 allocation(s).



Memory leaks result in general software reliability problems, but if an attacker can intentionally trigger a memory leak, the attacker might be able to launch a denial of service attack (by crashing or hanging the program) or take advantage of other unexpected program behavior resulting from a low memory condition.

We are processing your report and will contact the vim team within 24 hours. 10 days ago
We have contacted a member of the vim team and are waiting to hear back 9 days ago
Bram Moolenaar
7 days ago


The POC is very complicated. Please reduce it to the minimum needed to reproduce the problem.

6 days ago


The POC was reduced via afl-tmin. It seems could not be reduced anymore with the afl-tmin command.

afl-tmin -e -i /mnt/share/max/fuzz/poc/vim/poc_ml3_s.dat -o /mnt/share/max/fuzz/poc/vim/poc_ml1_s.dat -- ./vim -u NONE -i NONE -n -m -X -Z -e -s -S @@ -c :qa!
afl-tmin++4.01a by Michal Zalewski

[+] Read 211 bytes from '/mnt/share/max/fuzz/poc/vim/poc_ml3_s.dat'.
[*] Spinning up the fork server...
[+] All right - fork server is up.
[*] Target map size: 110345
[*] Performing dry run (mem limit = 0 MB, timeout = 1000 ms, edges only)...
[+] Program terminates normally, minimizing in instrumented mode.
[*] Stage #0: One-time block normalization...
[+] Block normalization complete, 0 bytes replaced.
[*] --- Pass #1 ---
[*] Stage #1: Removing blocks of data...
    Block length = 16, remaining size = 211
    Block length = 8, remaining size = 211
    Block length = 4, remaining size = 211
    Block length = 2, remaining size = 211
    Block length = 1, remaining size = 211
[+] Block removal complete, 0 bytes deleted.
[*] Stage #2: Minimizing symbols (50 code points)...
[+] Symbol minimization finished, 0 symbols (0 bytes) replaced.
[*] Stage #3: Character minimization...
[+] Character minimization done, 0 bytes replaced.

     File size reduced by : 0.00% (to 211 bytes)
    Characters simplified : 0.00%
     Number of execs done : 658
          Fruitless execs : path=655 crash=0 hang=2

[*] Writing output to '/mnt/share/max/fuzz/poc/vim/poc_ml1_s.dat'...
[+] We're done here. Have a nice day!
We have sent a follow up to the vim team. We will try again in 7 days. 6 days ago
Bram Moolenaar
6 days ago


The POC can defenitely be made shorter. I tried deleting one line with "R" and the same valgrind output results. When fixing a problem I should add a regression test, but this POC can't possibly be used as a test.

5 days ago


Manually reduced the POC to 28 bytes: poc_ml4.dat

./vim -u NONE -i NONE -n -m -X -Z -e -s -S ./poc_ml4.dat -c :qa!

==2403==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 2 byte(s) in 1 object(s) allocated from:
    #0 0x499cbd in malloc (/home/fuzz/fuzz/vim/afl/src/vim+0x499cbd)
    #1 0x4cb392 in lalloc /home/fuzz/fuzz/vim/afl/src/alloc.c:246:11
    #2 0x4cb27a in alloc /home/fuzz/fuzz/vim/afl/src/alloc.c:151:12
    #3 0xf8d4e6 in vim_strsave /home/fuzz/fuzz/vim/afl/src/strings.c:27:9
    #4 0x6a6a54 in typval2string /home/fuzz/fuzz/vim/afl/src/eval.c:502:11
    #5 0x6a6e4f in eval_to_string_eap /home/fuzz/fuzz/vim/afl/src/eval.c:528:11
    #6 0x6a6f6f in eval_to_string /home/fuzz/fuzz/vim/afl/src/eval.c:541:12
    #7 0xcecdb4 in vim_regsub_both /home/fuzz/fuzz/vim/afl/src/regexp.c:2050:17
    #8 0xcf0c8b in vim_regsub_multi /home/fuzz/fuzz/vim/afl/src/regexp.c:1916:14
    #9 0x7b3750 in ex_substitute /home/fuzz/fuzz/vim/afl/src/ex_cmds.c:4420:12
    #10 0x7dd349 in do_one_cmd /home/fuzz/fuzz/vim/afl/src/ex_docmd.c:2570:2
    #11 0x7ca205 in do_cmdline /home/fuzz/fuzz/vim/afl/src/ex_docmd.c:992:17
    #12 0x1158fbc in call_user_func /home/fuzz/fuzz/vim/afl/src/userfunc.c:2900:2
    #13 0x11550ad in call_user_func_check /home/fuzz/fuzz/vim/afl/src/userfunc.c:3057:2
    #14 0x114f454 in call_func /home/fuzz/fuzz/vim/afl/src/userfunc.c:3613:11
    #15 0x114c7f3 in get_func_tv /home/fuzz/fuzz/vim/afl/src/userfunc.c:1833:8
    #16 0x6e4c60 in eval_func /home/fuzz/fuzz/vim/afl/src/eval.c:2113:8
    #17 0x6e2dce in eval9 /home/fuzz/fuzz/vim/afl/src/eval.c:4027:9
    #18 0x6eeae9 in eval8 /home/fuzz/fuzz/vim/afl/src/eval.c:3596:11
    #19 0x6ec8d8 in eval7 /home/fuzz/fuzz/vim/afl/src/eval.c:3388:9
    #20 0x6e982f in eval6 /home/fuzz/fuzz/vim/afl/src/eval.c:3151:9
    #21 0x6e8382 in eval5 /home/fuzz/fuzz/vim/afl/src/eval.c:3040:9
    #22 0x6e6b7c in eval4 /home/fuzz/fuzz/vim/afl/src/eval.c:2891:9
    #23 0x6e527f in eval3 /home/fuzz/fuzz/vim/afl/src/eval.c:2752:9
    #24 0x6c0c6f in eval2 /home/fuzz/fuzz/vim/afl/src/eval.c:2626:9
    #25 0x6a2bcf in eval1 /home/fuzz/fuzz/vim/afl/src/eval.c:2472:9
    #26 0x6bfb25 in eval0_retarg /home/fuzz/fuzz/vim/afl/src/eval.c:2389:11
    #27 0x6a0167 in eval0 /home/fuzz/fuzz/vim/afl/src/eval.c:2364:12
    #28 0x6a6dc5 in eval_to_string_eap /home/fuzz/fuzz/vim/afl/src/eval.c:524:9
    #29 0x6a6f6f in eval_to_string /home/fuzz/fuzz/vim/afl/src/eval.c:541:12

SUMMARY: AddressSanitizer: 2 byte(s) leaked in 1 allocation(s).
Bram Moolenaar
4 days ago


Thanks, now I can reproduce it. Looks like this happens because vim_regsub_both() is called only once, the static string copy then is lost.

Bram Moolenaar
4 days ago


Fixed with patch 8.2.5146. Used the POC as a regression test. This may also fix previously reported problems in a better way.

Bram Moolenaar validated this vulnerability 4 days ago
TDHX ICS Security has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
Bram Moolenaar
4 days ago


Hmm, the "Mark as fixed" button is broken... Github commit: 44ddf19ec0ff59c969658ec7d9ed42070c59c51b

Bram Moolenaar confirmed that a fix has been merged on 44ddf1 3 days ago
Bram Moolenaar has been awarded the fix bounty
to join this conversation