Hi,

This email was forwarded to you as suggested by simon@josefsson.org as I was forwarded to this person when contacting security@gnu.org



Hi,

I’m a security researcher and I’ve searched for a way to contact the emacs security team but I’ve not found any information online, so I’m reporting this issue here.
I’ve discovered a buffer overflow in GNU Emacs 28.0.50 (at the time of writing the exploit still works on GNU Emacs 28.2)
The issue is inside the --dump-file functionality of emacs, in particular dump_make_lv_from_reloc at pdumper.c:5239
Attached to this email there's is payload used to make the vulnerability work (if emacs complains about a signature error you need to replace the hex bytes inside the payload with the expected one, since every emacs binary will expect a different signature).
This issue has been assigned CVE-2021-36699 and thus I’m notifying you of this. (I do not think the emacs team is aware of this security issue)
The POC is simple:
Launch emacs --dump-file exploit, where exploit is a custom crafted emacs dump file
Here's the program execution via GDB
Starting program: /home/fuomag9/emacs-std/src/emacs --dump-file
exploit_p1/3_1.dat
ERROR: Could not find ELF base!
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x000055555567d66e in dump_make_lv_from_reloc (reloc=...,
dump_base=140737341673472) at pdumper.c:5239
5239 && reloc.type < RELOC_DUMP_TO_EMACS_LV)
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────────────[
REGISTERS ]─────────────────────────────────────────────────────────────────────────────
RAX 0x24
RBX 0x555555b19ed8 (globals+2008) ◂— 0x0
RCX 0x9
RDX 0x7ffff7bcafe0 (deflateParams+320) ◂— mov dword ptr [rdi + rdx*2], eax
RDI 0x8000089de224
RSI 0x7ffff741d000 ◂— 'DUMPEDGNUEMACS'
R8 0x555555b6c8b0 ◂— 0x0
R9 0x555555b6c8b0 ◂— 0x0
R10 0x12
R11 0x7ffff7b2ac00 (main_arena+96) —▸ 0x555555b6c970 ◂— 0x0
R12 0x7ffff7bcafe4 (deflateParams+324) ◂— mov edx, eax
R13 0x7ffff741d000 ◂— 'DUMPEDGNUEMACS'
R14 0x7ffff7d49e78 ◂— add byte ptr [rax], al
R15 0x7ffff751d000 ◂— 0x0
RBP 0x555555b1c2e0 (lispsym) ◂— 0x0
RSP 0x7fffffffdf30 —▸ 0x7fffffffe0c0 ◂— 0x3
RIP 0x55555567d66e (dump_do_all_dump_reloc_for_phase+78) ◂— mov rdx,
qword ptr [rdi]
──────────────────────────────────────────────────────────────────────────────[
DISASM ]──────────────────────────────────────────────────────────────────────────────
► 0x55555567d66e mov rdx, qword ptr [rdi] <0x7ffff7bcafe0>
0x55555567d671 and eax, 0x1f
0x55555567d674 cmp al, 7
0x55555567d676 ja dump_do_all_dump_reloc_for_phase+224
<dump_do_all_dump_reloc_for_phase+224>

0x55555567d700 sub ecx, 0xd
0x55555567d703 lea rax, [rdx + rbx]
0x55555567d707 jmp dump_do_all_dump_reloc_for_phase+100
<dump_do_all_dump_reloc_for_phase+100>

0x55555567d684 mov rdx, rax
0x55555567d687 mov esi, ecx
0x55555567d689 sub rdx, rbp
0x55555567d68c add rax, rsi
──────────────────────────────────────────────────────────────────────────[
SOURCE (CODE) ]───────────────────────────────────────────────────────────────────────────
In file: /home/fuomag9/emacs-std/src/pdumper.c
5234 const struct dump_reloc reloc)
5235 {
5236 const dump_off reloc_offset = dump_reloc_get_offset (reloc);
5237 uintptr_t value = dump_read_word_from_dump (dump_base, reloc_offset);
5238 enum Lisp_Type lisp_type;
► 5239
5240 if (RELOC_DUMP_TO_DUMP_LV <= reloc.type
5241 && reloc.type < RELOC_DUMP_TO_EMACS_LV)
5242 {
5243 lisp_type = reloc.type - RELOC_DUMP_TO_DUMP_LV;
5244 value += dump_base;
──────────────────────────────────────────────────────────────────────────────[
STACK ]───────────────────────────────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffdf30 —▸ 0x7fffffffe0c0 ◂— 0x3
01:0008│ 0x7fffffffdf38 ◂— 0x3
02:0010│ 0x7fffffffdf40 —▸ 0x7fffffffdfc0 ◂— 'DUMPEDGNUEMACS'
03:0018│ 0x7fffffffdf48 —▸ 0x7fffffffe168 ◂— 0x3f /* '?' */
04:0020│ 0x7fffffffdf50 ◂— 0x0
05:0028│ 0x7fffffffdf58 —▸ 0x555555683e63 (pdumper_load+1523) ◂— mov
eax, dword ptr [rsp + 0xb4]
06:0030│ 0x7fffffffdf60 ◂— 0x60e99c8c
07:0038│ 0x7fffffffdf68 ◂— 0x60e9d68
────────────────────────────────────────────────────────────────────────────[
BACKTRACE ]─────────────────────────────────────────────────────────────────────────────
► f 0 0x55555567d66e dump_do_all_dump_reloc_for_phase+78
f 1 0x55555567d66e dump_do_all_dump_reloc_for_phase+78
f 2 0x55555567d66e dump_do_all_dump_reloc_for_phase+78
f 3 0x555555683e63 pdumper_load+1523
f 4 0x555555587c10 main+2880
f 5 0x555555587c10 main+2880
f 6 0x7ffff7972565 __libc_start_main+213

Below is the execution with the ASAN address sanitizer showing the
global buffer overflow:

==25852==ERROR: AddressSanitizer: global-buffer-overflow on address
0x56099125b830 at pc 0x7fc6db6862d3 bp 0x7ffe24fa83a0 sp
0x7ffe24fa7b48
WRITE of size 226929408 at 0x56099125b830 thread T0
#0 0x7fc6db6862d2 in __interceptor_memcpy
../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
#1 0x560990ba5258 in dump_do_emacs_relocation
(/home/fuomag9/emacs-asan/src/emacs+0x457258)
#2 0x560990ba5aa1 in dump_do_all_emacs_relocations
(/home/fuomag9/emacs-asan/src/emacs+0x457aa1)
#3 0x560990ba67ea in pdumper_load (/home/fuomag9/emacs-asan/src/emacs+0x4587ea)
#4 0x560990a5986a in load_pdump (/home/fuomag9/emacs-asan/src/emacs+0x30b86a)
#5 0x560990a5b167 in main (/home/fuomag9/emacs-asan/src/emacs+0x30d167)
#6 0x7fc6db006564 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x28564)
#7 0x56099082f00d in _start (/home/fuomag9/emacs-asan/src/emacs+0xe100d)
0x56099125b830 is located 0 bytes to the right of global variable
'globals' defined in 'alloc.c:283:22' (0x56099125aa80) of size 3504
0x56099125b830 is located 48 bytes to the left of global variable
'consing_until_gc' defined in 'alloc.c:287:11' (0x56099125b860) of
size 8
SUMMARY: AddressSanitizer: global-buffer-overflow
../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
in __interceptor_memcpy
Shadow bytes around the buggy address:
0x0ac1b22436b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ac1b22436c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ac1b22436d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ac1b22436e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0ac1b22436f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0ac1b2243700: 00 00 00 00 00 00[f9]f9 f9 f9 f9 f9 00 f9 f9 f9
0x0ac1b2243710: f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 01 f9 f9 f9
0x0ac1b2243720: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00
0x0ac1b2243730: 00 00 00 f9 f9 f9 f9 f9 00 00 00 00 00 00 00 f9
0x0ac1b2243740: f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9 00 f9 f9 f9
0x0ac1b2243750: f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9 00 f9 f9 f9
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
I look forward your promptly response.
Best regards,
fuomag9