agl / jbig2enc

JBIG2 Encoder
Other
251 stars 86 forks source link

NULL Pointer Dereference in jbig2_add_page #65

Closed andreafioraldi closed 4 years ago

andreafioraldi commented 4 years ago

Hi, My fuzzer found a testcase that causes a NULL Pointer Dereference when using the "-s" parameter.

The file content (encoded in base64) that crashes the program is the following: UDIjTAo2CTM2CTMK

The program output under Valgrind is the following:

Error in pixReadStreamPnm: read abend
Error in pixThresholdToBinary: pixs must be 4 or 8 bpp
Error in pixClone: pixs not defined
Error in jbAddPage: pixs not defined or not 1 bpp
==58840== Invalid read of size 4
==58840==    at 0x10EF52: jbig2_add_page(jbig2ctx*, Pix*) (jbig2enc.cc:505)
==58840==    by 0x10CC7D: main (jbig2.cc:472)
==58840==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

Although the crash point is the same as https://github.com/agl/jbig2enc/issues/61 it seems a different issue.

The concatenation of the first 3 errors in libleptonica causes pixCLone to return NULL and so the variable bw is null when jbAddPage is called (that, in fact, print an error).

Breakpoint 1, jbig2_add_page (ctx=0x555555936c20, input=<optimized out>) at jbig2enc.cc:504
504 in jbig2enc.cc
(gdb) p bw
$4 = (PIX *) 0x0

So the crash is at line 505 (ctx->page_width.push_back(bw->w);) cause bw->w is a NULL dereference.

As you can see in the snippet the problem is that you trust the returned value of pixClone assuming that pixClone returns without errors. A possible fix is a check against NULL.

void
jbig2_add_page(struct jbig2ctx *ctx, struct Pix *input) {
  PIX *bw;

  if (false /*ctx->xres >= 300*/) {
    bw = remove_flyspecks(input, (int) (0.0084*ctx->xres));
  } else {
    bw = pixClone(input);
  }

  if (ctx->refinement) {
    ctx->baseindexes.push_back(ctx->classer->baseindex);
  }

  jbAddPage(ctx->classer, bw);
  ctx->page_width.push_back(bw->w);
agl commented 4 years ago

Thanks! Should be fixed by the referenced commit: the code didn't handle the case where thresholding to binary didn't work, but Leptonica doesn't support thresholding two-bit images.