Bug 101500

Summary: Division by 0 at Function.cc:1626 and Function.cc:1662
Product: poppler Reporter: foca <foca>
Component: generalAssignee: poppler-bugs <poppler-bugs>
Status: RESOLVED FIXED QA Contact:
Severity: minor    
Priority: medium    
Version: unspecified   
Hardware: All   
OS: All   
Whiteboard:
i915 platform: i915 features:
Attachments: Proof of concept

Description foca@salesforce.com 2017-06-19 17:18:37 UTC
Created attachment 132064 [details]
Proof of concept

There is a division by 0 that leads to a SIGFPE.

The vulnerability is in the Function.cc:1626 in the PostScriptFunction::exec function below.

1623          case psOpIdiv:
1624            i2 = stack->popInt();
1625            i1 = stack->popInt();
1626            stack->pushInt(i1 / i2);

popInt() is called twice and the value is stored in i2 and i1. In both cases a 0 is returned causing i1/i2 to SIGFPE. PopInt is seen below. The 0 is returned because the if condition does not satisfy. checkType returns 0.

int popInt()
  {
    if (checkUnderflow() && checkType(psInt, psInt)) {
      return stack[sp++].intg;
    }
    return 0;
  }

CheckType validates that the object being popped is the same type as the function requests (popInt). This check is failed because the type at the stack[sp] is psReal.

GBool checkType(PSObjectType t1, PSObjectType t2)
  {
    if (stack[sp].type != t1 && stack[sp].type != t2) {
      error(-1, "Type mismatch in PostScript function");
      return gFalse;
    }
    return gTrue;
  }
  PSObject stack[psStackSize];
  int sp;
};

The solution could be to check for i2 != 0 before doing the division.

PoC attached.

This vulnerability has been found by Offensive Research at Salesforce.com:
Alberto Garcia (@algillera), Francisco Oca (@francisco_oca) & Suleman Ali (@Salbei_)
Comment 1 foca@salesforce.com 2017-06-19 17:21:24 UTC
A similar bug exists a few lines below at Function.cc:1662
1659          case psOpMod:
1660            i2 = stack->popInt();
1661            i1 = stack->popInt();
1662            stack->pushInt(i1 % i2);
1663            break;

Again a solution could be just to check if i2 is different than 0.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.