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