Headline
CVE-2021-46171: NULL Pointer Dereference in set_create_id() · Issue #8 · nimble-code/Modex
Modex v2.11 was discovered to contain a NULL pointer dereference in set_create_id() at xtract.c.
NULL Pointer Dereference in set_create_id()****Description
NULL Pointer Dereference in set_create_id()
at xtract.c:3797.
If there is no &
in the first argument of pthread_t()
, s
will be NULL and the next strchr()
will crash.
void set_create_id(void) // from the 1st ‘&(' to the 1st '),’ in OutBuf { char *s, *e;
join\_id = 0;
s = strchr(OutBuf, '&');
e = strchr(s+1, ')');
if (!e || e-s <= 1) { return; }
join\_id = (char \*) e\_malloc((e-s) \* sizeof(char));
strncpy(join\_id, s+2, (e-s)-1\-1);
}
pthread_create(&t, 0, thread, 0); ► 0x55555556aa76 <set_create_id+35> call strchr@plt strchr@plt s: 0x5555555a2080 (OutBuf) ◂— 'F: pthread_create((&(Pp_main->t)),0,Pp_main->thread,0)' c: 0x26
pthread_create(a, 0, thread, 0); ► 0x55555556aa76 <set_create_id+35> call strchr@plt strchr@plt s: 0x5555555a2080 (OutBuf) ◂— 'F: pthread_create(Pp_main->a,0,Pp_main->thread,0)' c: 0x26
version
acfa291
./modex -V
MODEX Version 2.11 - 3 November 2017
System information
Ubuntu 20.04 focal, AMD EPYC 7742 64-Core @ 16x 2.25GHz
poc
#include <stdio.h> #include <pthread.h> void *thread(){ puts(“hello world”); } int main(void) { pthread_t t; pthread_t* a; a = &t; while(1) { pthread_create(a, 0, thread, 0); } }
command
Result
./modex ./poc.c
MODEX Version 2.11 - 3 November 2017
[1] 2056163 segmentation fault ./modex ./poc.c
gdb
pwndbg>
0x000055555556aa8f 3797 e = strchr(s+1, ')');
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────[ REGISTERS ]─────────────────────────────────────────────
RAX 0x1
RBX 0x55555558c0f0 (__libc_csu_init) ◂— endbr64
RCX 0x0
RDX 0x0
*RDI 0x1
RSI 0x29
R8 0x212
R9 0x5555555a2080 (OutBuf) ◂— 'F: pthread_create(Pp_main->t,0,Pp_main->thread,0)'
R10 0x1e
R11 0x7fffffffb757 ◂— 0x4c16e0b189dd0030 /* '0' */
R12 0x5555555585c0 (_start) ◂— endbr64
R13 0x7fffffffe0f0 ◂— 0x2
R14 0x0
R15 0x0
RBP 0x7fffffffbea0 —▸ 0x7fffffffbee0 —▸ 0x7fffffffc140 —▸ 0x7fffffffc5b0 —▸ 0x7fffffffc5d0 ◂— ...
RSP 0x7fffffffbe90 ◂— 0x0
*RIP 0x55555556aa8f (set_create_id+60) ◂— call 0x555555558410
──────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────
0x55555556aa7b <set_create_id+40> mov qword ptr [rbp - 0x10], rax
0x55555556aa7f <set_create_id+44> mov rax, qword ptr [rbp - 0x10]
0x55555556aa83 <set_create_id+48> add rax, 1
0x55555556aa87 <set_create_id+52> mov esi, 0x29
0x55555556aa8c <set_create_id+57> mov rdi, rax
► 0x55555556aa8f <set_create_id+60> call strchr@plt <strchr@plt>
s: 0x1
c: 0x29
0x55555556aa94 <set_create_id+65> mov qword ptr [rbp - 8], rax
0x55555556aa98 <set_create_id+69> cmp qword ptr [rbp - 8], 0
0x55555556aa9d <set_create_id+74> je set_create_id+155 <set_create_id+155>
0x55555556aa9f <set_create_id+76> mov rax, qword ptr [rbp - 8]
0x55555556aaa3 <set_create_id+80> sub rax, qword ptr [rbp - 0x10]
──────────────────────────────────────────[ SOURCE (CODE) ]───────────────────────────────────────────
In file: /home/aidai/fuzzing/model_checking/Modex-test/Src/xtract.c
3792 set_create_id(void) // from the 1st '&(' to the 1st '),' in OutBuf
3793 { char *s, *e;
3794
3795 join_id = 0;
3796 s = strchr(OutBuf, '&');
► 3797 e = strchr(s+1, ')');
3798 if (!e || e-s <= 1) { return; }
3799
3800 join_id = (char *) e_malloc((e-s) * sizeof(char));
3801 strncpy(join_id, s+2, (e-s)-1-1);
3802 }
──────────────────────────────────────────────[ STACK ]───────────────────────────────────────────────
00:0000│ rsp 0x7fffffffbe90 ◂— 0x0
01:0008│ 0x7fffffffbe98 ◂— 0x0
02:0010│ rbp 0x7fffffffbea0 —▸ 0x7fffffffbee0 —▸ 0x7fffffffc140 —▸ 0x7fffffffc5b0 —▸ 0x7fffffffc5d0 ◂— ...
03:0018│ 0x7fffffffbea8 —▸ 0x55555556b0ce (handle_pthread_create+20) ◂— call 0x55555556aaf1
04:0020│ 0x7fffffffbeb0 ◂— 0x0
05:0028│ 0x7fffffffbeb8 ◂— 0x5558c0f0
06:0030│ 0x7fffffffbec0 —▸ 0x7fffffffc140 —▸ 0x7fffffffc5b0 —▸ 0x7fffffffc5d0 —▸ 0x7fffffffca40 ◂— ...
07:0038│ 0x7fffffffbec8 —▸ 0x5555555585c0 (_start) ◂— endbr64
────────────────────────────────────────────[ BACKTRACE ]─────────────────────────────────────────────
► f 0 0x55555556aa8f set_create_id+60
f 1 0x55555556b0ce handle_pthread_create+20
f 2 0x55555556cc32 modex_recur+4535
f 3 0x55555556ee66 modex_node+266
f 4 0x55555557050c modex_any+85
f 5 0x55555556f98c modex_node+3120
f 6 0x55555557050c modex_any+85
f 7 0x55555556f894 modex_node+2872
──────────────────────────────────────────────────────────────────────────────────────────────────────
pwndbg> bt
#0 0x000055555556aa8f in set_create_id () at xtract.c:3797
#1 0x000055555556b0ce in handle_pthread_create (which=0) at xtract.c:3966
#2 0x000055555556cc32 in modex_recur (root=0x7ffff7b6e3d8) at xtract.c:4425
#3 0x000055555556ee66 in modex_node (node=0x7ffff7b6e3d8, tabs=2) at xtract.c:5197
#4 0x000055555557050c in modex_any (child=0x7ffff7b6e3d8, tabs=2) at xtract.c:5746
#5 0x000055555556f98c in modex_node (node=0x7ffff7b6e658, tabs=2) at xtract.c:5505
#6 0x000055555557050c in modex_any (child=0x7ffff7b6e658, tabs=2) at xtract.c:5746
#7 0x000055555556f894 in modex_node (node=0x7ffff7b6e6f8, tabs=2) at xtract.c:5484
#8 0x000055555557050c in modex_any (child=0x7ffff7b6e6f8, tabs=2) at xtract.c:5746
#9 0x000055555556f8af in modex_node (node=0x7ffff7b6e108, tabs=2) at xtract.c:5485
#10 0x000055555557050c in modex_any (child=0x7ffff7b6e108, tabs=2) at xtract.c:5746
#11 0x0000555555570357 in modex_for (forn=0x7ffff7b6e1f8, tabs=1) at xtract.c:5701
#12 0x0000555555570545 in modex_any (child=0x7ffff7b6e1f8, tabs=1) at xtract.c:5756
#13 0x000055555556f98c in modex_node (node=0x7ffff7b6e6a8, tabs=1) at xtract.c:5505
#14 0x000055555557050c in modex_any (child=0x7ffff7b6e6a8, tabs=1) at xtract.c:5746
#15 0x0000555555570b19 in modex_tree (root=0x7ffff7b6e6a8, lut=0x55555558d215 "none.lut") at xtract.c:5852
#16 0x000055555555f962 in main (argc=2, argv=0x7fffffffe0f8) at modex.c:1337
#17 0x00007ffff7c980b3 in __libc_start_main (main=0x55555555f510 <main>, argc=2, argv=0x7fffffffe0f8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe0e8) at ../csu/libc-start.c:308
#18 0x00005555555585ee in _start ()
fix
Should we add some code here to handle it?
If there is no &
,get the substring from the 1st '(' to the 1st ‘,’ in OutBuf.
void set_create_id(void) // from the 1st ‘&(' to the 1st '),’ in OutBuf or from the 1st '(' to the 1st ‘,’ in OutBuf { char *s, *e;
join\_id = 0;
s = strchr(OutBuf, '&');
if (s != NULL)
{ e = strchr(s+1, ')');
}
else
{
s = strchr(OutBuf, '(')-1;
e = strchr(s+1, ',');
}
if (!e || e-s <= 1) { return; }
join\_id = (char \*) e\_malloc((e-s) \* sizeof(char));
strncpy(join\_id, s+2, (e-s)-1\-1);
}