https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=293177
Bug ID: 293177
Summary: Buffer Overflow in rpcgen (usr.bin/rpcgen/rpc_parse.c)
Product: Base System
Version: 14.3-RELEASE
Hardware: Any
OS: Any
Status: New
Severity: Affects Only Me
Priority: ---
Component: bin
Assignee: [email protected]
Reporter: [email protected]
Created attachment 268049
--> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=268049&action=edit
overflow
Dear FreeBSD Security Team,
I am reporting a potential security vulnerability in the rpcgen utility, which
is part of the FreeBSD base system. This appears to be a buffer overflow issue
during the parsing of RPC program definitions in .x files, leading to stack
corruption and potential local denial-of-service (DoS) or code execution.
The vulnerability occurs in rpc_parse.c, specifically in the
get_prog_declaration function (around line 478 in the source code). A
fixed-size buffer (char name[10]) is used to store argument names from tokens
parsed from the input .x file. The code copies the token string using
strcpy(name, tok.str) without bounds checking. If the argument name exceeds 9
characters (plus null terminator), this results in a buffer overflow,
corrupting adjacent stack memory.
This can be triggered by a maliciously crafted .x file with overly long
argument names in procedure definitions.
static void
get_prog_declaration(declaration *dec, defkind dkind, int num)
{
token tok;
char name[10]; /* argument name */ // BUFFER FIXO VULNERÁVEL:
Apenas 10 chars alocados
if (dkind == DEF_PROGRAM) {
peek(&tok);
if (tok.kind == TOK_RPAREN) { /* no arguments */
dec->rel = REL_ALIAS;
dec->type = "void";
dec->prefix = NULL;
dec->name = NULL;
return;
}
}
get_type(&dec->prefix, &dec->type, dkind);
dec->rel = REL_ALIAS;
if (peekscan(TOK_IDENT, &tok)) /* optional name of argument */
strcpy(name, tok.str); // LINHA VULNERÁVEL: strcpy sem bounds check.
Se tok.str > 9 chars, overflow na stack!
else
sprintf(name, "%s%d", ARGNAME, num); // LINHA VULNERÁVEL: sprintf pode
overflow se resultado > 9 chars
/* default name of argument */
dec->name = (char *) xstrdup(name);
if (streq(dec->type, "void")) {
return;
}
// ... (resto da função continua, mas o overflow já ocorreu aqui)
}
================================PoC============================================
$ uname -a
FreeBSD igor 14.3-RELEASE FreeBSD 14.3-RELEASE releng/14.3-n271432-8c9ce319fef7
GENERIC amd64
$ cat overflow.x
program OVERFLOW_PROG {
version OVERFLOW_VERS {
void PROCEDURE1(string
ARGUMENTO_MUITO_LONGO_PARA_OVERFLOW_NAME_BUFFER_HERE_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<1024>)
= 1;
} = 1;
} = 0x12345678;
igor@igor:~$ rpcgen overflow.x
Feb 14 07:36:41 igor rpcgen[5255]: stack overflow detected; terminated
Abort trap (core dumped)
igor@igor:~$
igor@igor:~$ valgrind --leak-check=full --show-leak-kinds=all
--track-origins=yes rpcgen overflow.x
==5232== Memcheck, a memory error detector
==5232== Copyright (C) 2002-2024, and GNU GPL'd, by Julian Seward et al.
==5232== Using Valgrind-3.25.1 and LibVEX; rerun with -h for copyright info
==5232== Command: rpcgen overflow.x
==5232==
==5232==
==5232== Process terminating with default action of signal 6 (SIGABRT): dumping
core
==5232== at 0x49AD45A: kill (in /lib/libc.so.7)
==5232== by 0x49B08AF: ??? (in /lib/libc.so.7)
==5232== by 0x49B081F: __stack_chk_fail (in /lib/libc.so.7)
==5232== by 0x400EBE2: ??? (in /usr/bin/rpcgen)
==5232== by 0x4141414141414140: ???
==5232== by 0x4141414141414140: ???
==5232== by 0x4141414141414140: ???
==5232== by 0x4141414141414140: ???
==5232== by 0x56202FF: ???
==5232== by 0x3: ???
==5232== by 0x56203CF: ???
==5232== by 0x24: ???
==5232==
==5232== HEAP SUMMARY:
==5232== in use at exit: 159,302 bytes in 27 blocks
==5232== total heap usage: 30 allocs, 3 frees, 238,723 bytes allocated
==5232==
==5232== 5 bytes in 1 blocks are still reachable in loss record 1 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4013A18: ??? (in /usr/bin/rpcgen)
==5232== by 0x401020C: ??? (in /usr/bin/rpcgen)
==5232== by 0x400FFB4: ??? (in /usr/bin/rpcgen)
==5232== by 0x400EB62: ??? (in /usr/bin/rpcgen)
==5232== by 0x4141414141414140: ???
==5232== by 0x4141414141414140: ???
==5232== by 0x4141414141414140: ???
==5232== by 0x4141414141414140: ???
==5232== by 0x56202FF: ???
==5232== by 0x3: ???
==5232== by 0x56203CF: ???
==5232==
==5232== 11 bytes in 1 blocks are still reachable in loss record 2 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4013A18: ??? (in /usr/bin/rpcgen)
==5232== by 0x4010384: ??? (in /usr/bin/rpcgen)
==5232== by 0x400FE87: ??? (in /usr/bin/rpcgen)
==5232== by 0x400F764: ??? (in /usr/bin/rpcgen)
==5232== by 0x400DE65: ??? (in /usr/bin/rpcgen)
==5232== by 0x4008924: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 14 bytes in 1 blocks are still reachable in loss record 3 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4013A18: ??? (in /usr/bin/rpcgen)
==5232== by 0x4010384: ??? (in /usr/bin/rpcgen)
==5232== by 0x400FE87: ??? (in /usr/bin/rpcgen)
==5232== by 0x400F764: ??? (in /usr/bin/rpcgen)
==5232== by 0x400DCD5: ??? (in /usr/bin/rpcgen)
==5232== by 0x4008924: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 14 bytes in 1 blocks are indirectly lost in loss record 4 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4013A18: ??? (in /usr/bin/rpcgen)
==5232== by 0x4010384: ??? (in /usr/bin/rpcgen)
==5232== by 0x400FE87: ??? (in /usr/bin/rpcgen)
==5232== by 0x400F764: ??? (in /usr/bin/rpcgen)
==5232== by 0x400DD57: ??? (in /usr/bin/rpcgen)
==5232== by 0x4008924: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 15 bytes in 1 blocks are still reachable in loss record 5 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4013A18: ??? (in /usr/bin/rpcgen)
==5232== by 0x400FA33: ??? (in /usr/bin/rpcgen)
==5232== by 0x400DC3E: ??? (in /usr/bin/rpcgen)
==5232== by 0x4008924: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 17 bytes in 1 blocks are still reachable in loss record 6 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4013A18: ??? (in /usr/bin/rpcgen)
==5232== by 0x400A134: ??? (in /usr/bin/rpcgen)
==5232== by 0x4008839: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 24 bytes in 1 blocks are still reachable in loss record 7 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4014315: ??? (in /usr/bin/rpcgen)
==5232== by 0x40087B4: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 24 bytes in 1 blocks are still reachable in loss record 8 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4014315: ??? (in /usr/bin/rpcgen)
==5232== by 0x40087C5: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 24 bytes in 1 blocks are still reachable in loss record 9 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4014315: ??? (in /usr/bin/rpcgen)
==5232== by 0x40087D6: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 24 bytes in 1 blocks are still reachable in loss record 10 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4014315: ??? (in /usr/bin/rpcgen)
==5232== by 0x40087E7: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 24 bytes in 1 blocks are still reachable in loss record 11 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4014315: ??? (in /usr/bin/rpcgen)
==5232== by 0x40087F8: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 24 bytes in 1 blocks are still reachable in loss record 12 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4014315: ??? (in /usr/bin/rpcgen)
==5232== by 0x4008809: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 24 bytes in 1 blocks are still reachable in loss record 13 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4014315: ??? (in /usr/bin/rpcgen)
==5232== by 0x400881A: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 46 (32 direct, 14 indirect) bytes in 1 blocks are definitely lost in
loss record 14 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4013A18: ??? (in /usr/bin/rpcgen)
==5232== by 0x400DD61: ??? (in /usr/bin/rpcgen)
==5232== by 0x4008924: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 64 bytes in 1 blocks are definitely lost in loss record 15 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4013A18: ??? (in /usr/bin/rpcgen)
==5232== by 0x400DE26: ??? (in /usr/bin/rpcgen)
==5232== by 0x4008924: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 72 bytes in 1 blocks are still reachable in loss record 16 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4013A18: ??? (in /usr/bin/rpcgen)
==5232== by 0x400DC2C: ??? (in /usr/bin/rpcgen)
==5232== by 0x4008924: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 92 bytes in 6 blocks are definitely lost in loss record 17 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4013A18: ??? (in /usr/bin/rpcgen)
==5232== by 0x400FA33: ??? (in /usr/bin/rpcgen)
==5232== by 0x400DC3E: ??? (in /usr/bin/rpcgen)
==5232== by 0x4008924: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 99 bytes in 1 blocks are still reachable in loss record 18 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4A3F4AC: strdup (in /lib/libc.so.7)
==5232== by 0x40143F8: ??? (in /usr/bin/rpcgen)
==5232== by 0x400EA8D: ??? (in /usr/bin/rpcgen)
==5232== by 0x4141414141414140: ???
==5232== by 0x4141414141414140: ???
==5232== by 0x4141414141414140: ???
==5232== by 0x4141414141414140: ???
==5232== by 0x56202FF: ???
==5232== by 0x3: ???
==5232== by 0x56203CF: ???
==5232== by 0x24: ???
==5232==
==5232== 99 bytes in 1 blocks are definitely lost in loss record 19 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x4013A18: ??? (in /usr/bin/rpcgen)
==5232== by 0x4010384: ??? (in /usr/bin/rpcgen)
==5232== by 0x400FE87: ??? (in /usr/bin/rpcgen)
==5232== by 0x400FFB4: ??? (in /usr/bin/rpcgen)
==5232== by 0x400EA55: ??? (in /usr/bin/rpcgen)
==5232== by 0x400DE94: ??? (in /usr/bin/rpcgen)
==5232== by 0x4008924: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 4,096 bytes in 1 blocks are still reachable in loss record 20 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x49902CD: ??? (in /lib/libc.so.7)
==5232== by 0x4992D90: ??? (in /lib/libc.so.7)
==5232== by 0x498C13C: fgets (in /lib/libc.so.7)
==5232== by 0x400F8E5: ??? (in /usr/bin/rpcgen)
==5232== by 0x400DC3E: ??? (in /usr/bin/rpcgen)
==5232== by 0x4008924: ??? (in /usr/bin/rpcgen)
==5232== by 0x40084A9: ??? (in /usr/bin/rpcgen)
==5232== by 0x48FBE33: __libc_start1 (in /lib/libc.so.7)
==5232== by 0x4007E30: ??? (in /usr/bin/rpcgen)
==5232== by 0x483C007: ???
==5232==
==5232== 23,432 bytes in 1 blocks are still reachable in loss record 21 of 22
==5232== at 0x4866304: malloc (vg_replace_malloc.c:450)
==5232== by 0x49A4D80: ??? (in /lib/libc.so.7)
==5232== by 0x49A5055: ??? (in /lib/libc.so.7)
==5232== by 0x492BA0A: ??? (in /lib/libc.so.7)
==5232== by 0x492B815: syslog (in /lib/libc.so.7)
==5232== by 0x49B086B: ??? (in /lib/libc.so.7)
==5232== by 0x49B081F: __stack_chk_fail (in /lib/libc.so.7)
==5232== by 0x400EBE2: ??? (in /usr/bin/rpcgen)
==5232== by 0x4141414141414140: ???
==5232== by 0x4141414141414140: ???
==5232== by 0x4141414141414140: ???
==5232== by 0x4141414141414140: ???
==5232==
==5232== LEAK SUMMARY:
==5232== definitely lost: 287 bytes in 9 blocks
==5232== indirectly lost: 14 bytes in 1 blocks
==5232== possibly lost: 0 bytes in 0 blocks
==5232== still reachable: 27,929 bytes in 16 blocks
==5232== suppressed: 131,072 bytes in 1 blocks
==5232==
==5232== For lists of detected and suppressed errors, rerun with: -s
==5232== ERROR SUMMARY: 4 errors from 4 contexts (suppressed: 0 from 0)
Abort trap
$
gdb -q --args rpcgen /home/igor/overflow.x
>r
[ Legend: Modified register | Code | Heap | Stack | String ]
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
registers ────
$rax : 0x0
$rbx : 0x00000008010ba644 → "stack overflow detected; terminated"
$rcx : 0x00000008011b12da → <getpid+000a> jb 0x8011b1178
$rdx : 0x0
$rsp : 0x00007fffffffe678 → 0x00000008011b48b0 → mov edi, 0x7f
$rbp : 0x00007fffffffe6c0 → 0x00007fffffffe6d0 → 0x00007fffffffe730 →
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
$rsi : 0x6
$rdi : 0x149a
$rip : 0x00000008011b145a → <kill+000a> jb 0x8011b1178
$r8 : 0x0
$r9 : 0x0
$r10 : 0x149a
$r11 : 0x206
$r12 : 0x5
$r13 : 0x0000000801267950 → 0xa48f7a7d8bd75962
$r14 : 0x00007fffffffe680 → 0xffffffffffffffdf
$r15 : 0x00007fffffffe6e0 → 0xa48f7a7d0000000a ("\n"?)
$eflags: [zero carry PARITY adjust sign trap INTERRUPT direction overflow
resume virtualx86 identification]
$cs: 0x43 $ss: 0x3b $ds: 0x3b $es: 0x3b $fs: 0x13 $gs: 0x1b
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
stack ────
0x00007fffffffe678│+0x0000: 0x00000008011b48b0 → mov edi, 0x7f ← $rsp
0x00007fffffffe680│+0x0008: 0xffffffffffffffdf ← $r14
0x00007fffffffe688│+0x0010: 0xffffffffffffffff
0x00007fffffffe690│+0x0018: 0x0000000000000000
0x00007fffffffe698│+0x0020: 0x0000000000000000
0x00007fffffffe6a0│+0x0028: 0x0000000000000000
0x00007fffffffe6a8│+0x0030: 0x0000000000000000
0x00007fffffffe6b0│+0x0038: 0x00007fffffffe7b0 → 0x0000000000000000
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
code:x86:64 ────
0x8011b1450 <kill+0000> mov eax, 0x25
0x8011b1455 <kill+0005> mov r10, rcx
0x8011b1458 <kill+0008> syscall
→ 0x8011b145a <kill+000a> jb 0x8011b1178 NOT taken [Reason:
!(C)]
0x8011b1460 <kill+0010> ret
0x8011b1461 int3
0x8011b1462 int3
0x8011b1463 int3
0x8011b1464 int3
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
threads ────
[#0] Id 1, stopped 0x8011b145a in kill (), reason: SIGABRT
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
trace ────
[#0] 0x8011b145a → kill()
[#1] 0x8011b48b0 → mov edi, 0x7f
[#2] 0x8011b4820 → __stack_chk_fail()
[#3] 0x102fbe3 → int3
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
gef➤
If applicable, I would like a CVE for this overflow.
Credits:
Author: Igor Gabriel Sousa e Souza
Email: [email protected]
LinkedIn: https://www.linkedin.com/in/igo0r
Thanks!
--
You are receiving this mail because:
You are the assignee for the bug.