tags 878512 + moreinfo pending thanks Hi Jakub,
> pax crashes on some malformed tar archives: only on platforms with 32-bit off_t, but I was able to reproduce this on i386. Thanks! Turns out this was a classical integer overflow, but a band-aid should suffice as long as we’re not talking UB. > Found using American Fuzzy Lop: > http://lcamtuf.coredump.cx/afl/ I’m inlining the patch below. Could you please do me a favour and test again with that patch applied to check whether there are any more issues before I do the whole upstream release plus Debian upload dance? This is certainly low importance enough to not require an immediate upload. Thanks in advance! Index: src/bin/pax/pax.c diff -up src/bin/pax/pax.c:1.24 src/bin/pax/pax.c:1.25 --- src/bin/pax/pax.c:1.24 Sat Oct 14 21:26:54 2017 +++ src/bin/pax/pax.c Sat Oct 14 22:03:31 2017 @@ -56,7 +56,6 @@ __RCSID("$MirOS$"); static int gen_init(void); -static void sig_cleanup(int) __attribute__((__noreturn__)); /* * PAX main routines, general globals and some simple start up routines @@ -309,7 +308,7 @@ main(int argc, char **argv) * never.... */ -static void +void sig_cleanup(int which_sig) { /* @@ -332,6 +331,9 @@ sig_cleanup(int which_sig) if (which_sig == SIGXCPU) strlcpy(errbuf, "CPU time limit reached, cleaning up.\n", sizeof errbuf); + else if (!which_sig) + strlcpy(errbuf, "Cowardly giving up, trying to clean up.\n", + sizeof errbuf); else strlcpy(errbuf, "Signal caught, cleaning up.\n", sizeof errbuf); Index: src/bin/pax/pax.h diff -up src/bin/pax/pax.h:1.18 src/bin/pax/pax.h:1.19 --- src/bin/pax/pax.h:1.18 Mon Aug 7 20:10:17 2017 +++ src/bin/pax/pax.h Sat Oct 14 22:03:32 2017 @@ -322,4 +322,6 @@ typedef unsigned long long ot_type; typedef unsigned long ot_type; #endif +void sig_cleanup(int) __attribute__((__noreturn__)); + #endif Index: src/bin/pax/buf_subs.c diff -up src/bin/pax/buf_subs.c:1.9 src/bin/pax/buf_subs.c:1.10 --- src/bin/pax/buf_subs.c:1.9 Tue Aug 8 16:42:49 2017 +++ src/bin/pax/buf_subs.c Sat Oct 14 22:03:32 2017 @@ -394,6 +394,11 @@ rd_skip(off_t skcnt) off_t cnt; off_t skipped = 0; + if (skcnt < 0) { + paxwarn(1, "Trying to skip backwards; corrupt archive likely"); + sig_cleanup(0); + } + /* * consume what data we have in the buffer. If we have to move forward * whole records, we call the low level skip function to see if we can