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

Fix a 7zip crash and a ISO9660 infinite loop #1120

Merged
merged 2 commits into from Jan 20, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Next
iso9660: Fail when expected Rockridge extensions is missing
A corrupted or malicious ISO9660 image can cause read_CE() to loop
forever.

read_CE() calls parse_rockridge(), expecting a Rockridge extension
to be read. However, parse_rockridge() is structured as a while
loop starting with a sanity check, and if the sanity check fails
before the loop has run, the function returns ARCHIVE_OK without
advancing the position in the file. This causes read_CE() to retry
indefinitely.

Make parse_rockridge() return ARCHIVE_WARN if it didn't read an
extension. As someone with no real knowledge of the format, this
seems more apt than ARCHIVE_FATAL, but both the call-sites escalate
it to a fatal error immediately anyway.

Found with a combination of AFL, afl-rb (FairFuzz) and qsym.
  • Loading branch information
daxtens committed Jan 16, 2019
commit 8312eaa576014cd9b965012af51bc1f967b12423
11 changes: 10 additions & 1 deletion libarchive/archive_read_support_format_iso9660.c
Expand Up @@ -2102,6 +2102,7 @@ parse_rockridge(struct archive_read *a, struct file_info *file,
const unsigned char *p, const unsigned char *end)
{
struct iso9660 *iso9660;
int entry_seen = 0;

iso9660 = (struct iso9660 *)(a->format->data);

Expand Down Expand Up @@ -2257,8 +2258,16 @@ parse_rockridge(struct archive_read *a, struct file_info *file,
}

p += p[2];
entry_seen = 1;
}

if (entry_seen)
return (ARCHIVE_OK);
else {
archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
"Tried to parse Rockridge extensions, but none found");
return (ARCHIVE_WARN);
}
return (ARCHIVE_OK);
}

static int
Expand Down