Closed ProbeFuzzer closed 2 years ago
This was assigned CVE-2018-5786
Fixed generically with other safeguards.
Hi,
Sorry to dig old bugs, I'm part of Debian LTS (Long Term Support) and while looking at this issue, it seems it never got fixed, despite safeguards such as 399336eba.
During my tests I couldn't find a lrzip version that avoids the infinite loop.
Note: unlike all other CVEs fixes surrounding this one, this CVE is triggered with the -i
flag (not -t
).
Current master (e5e9a61f) debug log:
# gdb --args ../master/lrzip/lrzip -i lrzip_0-631_lrzip_infinite-loop_get_fileinfo.lrz
(gdb) run
Starting program: /usr/src/lrzip/master/lrzip/lrzip -i lrzip_0-631_lrzip_infinite-loop_get_fileinfo
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
^C
Program received signal SIGINT, Interrupt.
0x00007ffff736e210 in __read_nocancel () from /lib/x86_64-linux-gnu/libpthread.so.0
(gdb) bt
#0 0x00007ffff736e210 in __read_nocancel () from /lib/x86_64-linux-gnu/libpthread.so.0
#1 0x000055555555d74a in get_header_info (control=control@entry=0x5555557989c0 <local_control>, fd_in=fd_in@entry=3, ctype=ctype@entry=0x7fffffffe1e7 "\003\032",
c_len=c_len@entry=0x7fffffffe1f0, u_len=u_len@entry=0x7fffffffe1e8, last_head=last_head@entry=0x7fffffffe1f8, chunk_bytes=2) at lrzip.c:956
#2 0x000055555555df72 in get_fileinfo (control=0x5555557989c0 <local_control>) at lrzip.c:1103
#3 0x0000555555558147 in main (argc=<optimized out>, argv=<optimized out>) at main.c:722
(gdb) frame 2
#2 0x000055555555df72 in get_fileinfo (control=0x5555557989c0 <local_control>) at lrzip.c:1103
1103 if (unlikely(!get_header_info(control, fd_in, &ctype, &c_len, &u_len,
(gdb) list
1098 second_last = last_head;
1099 if (unlikely(last_head + ofs > infile_size))
1100 failure_goto(("Offset greater than archive size, likely corrupted/truncated archive.\n"), error);
1101 if (unlikely((head_off = lseek(fd_in, last_head + ofs, SEEK_SET)) == -1))
1102 fatal_goto(("Failed to seek to header data in get_fileinfo\n"), error);
1103 if (unlikely(!get_header_info(control, fd_in, &ctype, &c_len, &u_len,
1104 &last_head, chunk_byte)))
1105 return false;
1106 if (unlikely(last_head < 0 || c_len < 0 || u_len < 0))
1107 failure_goto(("Entry negative, likely corrupted archive.\n"), error);
Can you confirm?
Thanks. The check looks incomplete in the info version. Will check again shortly.
This works for me. Thank you.
On latest version (0.631) and the master branch, there is an infinite loop and application hang in the get_fileinfo function (src/lrzip.c), which can be triggered by the POC with command: lrzip -i $POC
Looking into the get_fileinfo function (src/lrzip.c), we found that: in the "do {} while(last_head)" loop, the "last_head" variable is affected by the POC file and always non-zero, and "lseek" in line 1041 continuously moves file cursor to the same position. That means, "last_head" is always assigned the value from the same file position, resulting in infinite loop.
POC: https://github.com/ProbeFuzzer/poc/blob/master/lrzip/lrzip_0-631_lrzip_infinite-loop_get_fileinfo.lrz