Skip to content

Commit d12cb9a

Browse files
authored
rar: fix UB negation overflow for INT32_MIN address (libarchive#2235)
certain rar files seem to have the lowest possible address here, so flip the argument order to correctly evaluate this instead of invoking UB (caught via sanitize=undefined) --- the backtrace looks something like: ``` * frame #0: 0x00007a1e3898727b libarchive.so.13`execute_filter [inlined] execute_filter_e8(filter=<unavailable>, vm=<unavailable>, pos=<unavailable>, e9also=<unavailable>) at archive_read_support_format_rar.c:3640:47 frame #1: 0x00007a1e3898727b libarchive.so.13`execute_filter(a=<unavailable>, filter=0x00007a1e39e2f090, vm=0x00007a1e31b1efd0, pos=<unavailable>) at archive_read_support_format_rar.c:0 frame #2: 0x00007a1e38983ac3 libarchive.so.13`read_data_compressed [inlined] run_filters(a=0x00007a1e34209700) at archive_read_support_format_rar.c:3395:8 frame libarchive#3: 0x00007a1e38983a9e libarchive.so.13`read_data_compressed(a=0x00007a1e34209700, buff=0x00007a1e31a01fd8, size=0x00007a1e31a01fd0, offset=0x00007a1e31a01fc0, looper=1) at archive_read_support_format_rar.c:2083:12 frame libarchive#4: 0x00007a1e38981b10 libarchive.so.13`archive_read_format_rar_read_data(a=0x00007a1e34209700, buff=0x00007a1e31a01fd8, size=0x00007a1e31a01fd0, offset=0x00007a1e31a01fc0) at archive_read_support_format_rar.c:1130:11 frame libarchive#5: 0x00006158bc5d30d3 file-roller`extract_archive_thread(result=0x00007a1e3711e2b0, object=<unavailable>, cancellable=0x00007a1e3870bf20) at fr-archive-libarchive.c:999:17 frame libarchive#6: 0x00007a1e39928d6d libgio-2.0.so.0`run_in_thread(job=<unavailable>, c=<unavailable>, _data=0x00007a1e326e9740) at gsimpleasyncresult.c:899:5 frame libarchive#7: 0x00007a1e3990614e libgio-2.0.so.0`io_job_thread(task=<unavailable>, source_object=<unavailable>, task_data=0x00007a1e2307fc20, cancellable=<unavailable>) at gioscheduler.c:75:16 frame libarchive#8: 0x00007a1e399433bf libgio-2.0.so.0`g_task_thread_pool_thread(thread_data=0x00007a1e35c18ab0, pool_data=<unavailable>) at gtask.c:1583:3 frame libarchive#9: 0x00007a1e39db77e8 libglib-2.0.so.0`g_thread_pool_thread_proxy(data=<unavailable>) at gthreadpool.c:336:15 frame libarchive#10: 0x00007a1e39db5bfb libglib-2.0.so.0`g_thread_proxy(data=0x00007a1e378147d0) at gthread.c:835:20 frame libarchive#11: 0x00007a1e3a0b5c7b ld-musl-x86_64.so.1`start(p=0x00007a1e31a02170) at pthread_create.c:208:17 frame libarchive#12: 0x00007a1e3a0b8a8b ld-musl-x86_64.so.1`__clone + 47 ``` note the 0xd which is 14 which is NegateOverflow in ubsan: ``` (lldb) x/1i $pc -> 0x7a1e3898727b: 67 0f b9 40 0d other ud1l 0xd(%eax), %eax ``` for reference, the totally legal rar file is https://img.ayaya.dev/05WYGFOcRPN9 , and this seems to only crash when extracted via file-roller (or inside nautilus)
1 parent e3c0c8d commit d12cb9a

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

libarchive/archive_read_support_format_rar.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3681,7 +3681,7 @@ execute_filter_e8(struct rar_filter *filter, struct rar_virtual_machine *vm, siz
36813681
{
36823682
uint32_t currpos = (uint32_t)pos + i + 1;
36833683
int32_t address = (int32_t)vm_read_32(vm, i + 1);
3684-
if (address < 0 && currpos >= (uint32_t)-address)
3684+
if (address < 0 && currpos >= -(uint32_t)address)
36853685
vm_write_32(vm, i + 1, address + filesize);
36863686
else if (address >= 0 && (uint32_t)address < filesize)
36873687
vm_write_32(vm, i + 1, address - currpos);

0 commit comments

Comments
 (0)