Buffer over overflow in fax2ps -- by misuse of the option "-p"

fax2ps heap-buffer-overflow - by misuse of the option "-p"

When the program input contains the option of two and more times "-p", the program will cause heap-buffer-overflow.

libtiff/fax2ps.c Line 349:361

case 'p':		/* print specific page */
    pageNumber = (uint16_t)atoi(optarg);
    if (pages)
	pages = (uint16_t*) realloc(pages, (npages + 1) * sizeof(uint16_t));
    else
	pages = (uint16_t*) malloc(sizeof(uint16_t));
    if( pages == NULL )
    {
	fprintf(stderr, "Out of memory\n");
	exit(EXIT_FAILURE);
    }
    pages[npages++] = pageNumber;
    break;
}
381 : qsort(pages, npages, sizeof(uint16_t), pcompar);

In Line 381, the program calls qsort to sort pages with sort function pomper. pomper does type conversion. As a result, the program will occur heap buffer overflow.

Test Environment

Ubuntu 20.04, 64 bit Libtiff/fax2ps (version: 4.4.0)

How to trigger

  1. Compile the program with AddressSanitizer
  2. Run command $ ./fax2ps -p2 -p2

Details

ASAN report

$ ./fax2ps -p2 -p2
=================================================================
==945815==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000032 at pc 0x0000004deb34 bp 0x7fff4f678560 sp 0x7fff4f678558
READ of size 4 at 0x602000000032 thread T0
    #0 0x4deb33 in pcompar /home/root/libtiff/sourcecode/libtiff/tools/fax2ps.c:321:19
    #1 0x47e83b in qsort_r /local/mnt/workspace/bcain_clang_hu-bcain-lv_22036/final/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:10054:7
    #2 0x4de073 in main /home/root/libtiff/sourcecode/libtiff/tools/fax2ps.c:380:2
    #3 0x7f9060fe8082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
    #4 0x41d50d in _start (/home/root/libtiff/sourcecode/libtiff/build_new/install/bin/fax2ps+0x41d50d)

0x602000000034 is located 0 bytes to the right of 4-byte region [0x602000000030,0x602000000034)
allocated by thread T0 here:
    #0 0x4a0046 in __interceptor_realloc /local/mnt/workspace/bcain_clang_hu-bcain-lv_22036/final/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:85:3
    #1 0x4ddc17 in main /home/root/libtiff/sourcecode/libtiff/tools/fax2ps.c:351:23
    #2 0x7f9060fe8082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/root/libtiff/sourcecode/libtiff/tools/fax2ps.c:321:19 in pcompar
Shadow bytes around the buggy address:
  0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa fd fa fa fa[04]fa fa fa fa fa fa fa fa fa
  0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==945815==ABORTING