Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segmentation fault while reading a RAR file #2087

Open
eriklax opened this issue Mar 8, 2024 · 1 comment
Open

Segmentation fault while reading a RAR file #2087

eriklax opened this issue Mar 8, 2024 · 1 comment

Comments

@eriklax
Copy link

eriklax commented Mar 8, 2024

On Linux and FreeBSD, while reading a specific "RAR archive data, v4, os: Win32" file, and while not reading all data in all files (hence skipping over with archive_read_data_skip). When reaching a specific file in a archive this crash occurres.

Important! If not skipping file < 141, and reading all data, it does not crash

Backtrace:

Program received signal SIGSEGV, Segmentation fault.
Address not mapped to object.
0x00000008004b621f in memcpy () from /lib/libc.so.7
(gdb) bt
#0  0x00000008004b621f in memcpy () from /lib/libc.so.7
#1  0x00000008002db819 in copy_from_lzss_window_to_unp (a=0x80121a000, buffer=0x7fffffffe988, startpos=1280, length=-855)
    at /build/libarchive/libarchive/archive_read_support_format_rar.c:3102
#2  0x00000008002db642 in read_data_compressed (a=0x80121a000, buff=0x7fffffffe988, size=0x7fffffffe980, offset=0x7fffffffe978, looper=1)
    at /build/libarchive/libarchive/archive_read_support_format_rar.c:2204
#3  0x00000008002d8417 in archive_read_format_rar_read_data (a=0x80121a000, buff=0x7fffffffe988, size=0x7fffffffe980, offset=0x7fffffffe978)
    at /build/libarchive/libarchive/archive_read_support_format_rar.c:1130
#4  0x00000008002a1a82 in _archive_read_data_block (_a=0x80121a000, buff=0x7fffffffe988, size=0x7fffffffe980, offset=0x7fffffffe978)
    at /build/libarchive/libarchive/archive_read.c:986
#5  0x00000008003090f6 in archive_read_data_block (a=0x80121a000, buff=0x7fffffffe988, s=0x7fffffffe980, o=0x7fffffffe978) at /build/libarchive/libarchive/archive_virtual.c:161
#6  0x0000000000201c83 in main ()

ret = expand(a, &end);
if (ret != ARCHIVE_OK)
return (ret);

This expand() make the end go from

start = 1280 end = 1792
to
start = 1280 end = 425

Explaining the length=-855 from the gdb backtrace

#include <archive.h>
#include <archive_entry.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char* argv[])
{
	struct archive* archive = archive_read_new();
	archive_read_support_filter_all(archive);
	archive_read_support_format_all(archive);

	if (archive_read_open_filename(archive, argv[1], 10240) != ARCHIVE_OK)
		return 1;

	struct archive_entry *entry;
	const void *buff = NULL;
	size_t size = 0;
	off_t offset = 0;
	int r;

	size_t y = 0;
	while (++y)
	{
		int r = archive_read_next_header(archive, &entry);
		if (r != ARCHIVE_OK)
		{
			if (r == ARCHIVE_EOF)
				break;
			return 1;
		}

		if (archive_read_data_block(archive, &buff, &size, &offset) != ARCHIVE_OK)
			break;

		if (y < 141)
			continue;

		while ((r = archive_read_data_block(archive, &buff, &size, &offset)) == ARCHIVE_OK) // crashes here
			;
	}
	archive_read_free(archive);
	return 0;
}
@nexvium
Copy link

nexvium commented Mar 11, 2024

I just ran into this issue last week as well. Making the change below to right after the expand()/if code seemed to fix crash:

-      rar->bytes_uncopied = end - start;
+      rar->bytes_uncopied = end > start ? end - start : 0;

but I don't know if that has any unintended side effect. Would be good to get an "official" fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants