# Python: imageop Unsafe Arithmetic

Integer division truncation in imageop's check_multiply_size let grey2rgb pass a bad length check, overflowing a 36-byte buffer with 64 bytes and corrupting memory.

- Payout: $1,000
- Severity: high
- Program: Internet Bug Bounty
- Credited: johnleitch
- Disclosed: 2015-05-31
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/73258
- Library page: https://bugbountylibrary.com/r/h1%3A73258
- Tags: domain:oss impact:dos impact:rce kind:bounty platform:hackerone sev:high tech:python technique:fuzzing technique:source-review vuln:memory-corruption

**Target:** imageop module (grey2rgb and related functions)
**Root cause:** check_multiply_size() validates size == (product/y)/x using integer division that discards remainders, so non-divisible products pass the check; grey2rgb then loops len times writing 4 bytes each into a buffer sized x*y*4.
**Steps:**
1. Call `imageop.grey2rgb(data, 1, 9)` with a 16-byte data string (x=1, y=9, len=16).
2. check_multiply(16,1,9) fails but check_multiply_size(36,1,9,4) passes because (36/9)/1 == 4 == size.
3. Buffer allocated is x*y*4 = 36 bytes.
4. Loop iterates len=16 times, writing 4 bytes per iteration = 64 bytes into the 36-byte buffer.
5. Heap corruption occurs; observed access violation in update_refs on 0x00444444.
**How found:** Researcher read check_multiply_size() and noticed the division-based size check ignores remainders; confirmed in WinDbg that idiv truncates (16/9=1, remainder 7) so size==1 passes, then traced grey2rgb's loop to show 64 bytes written into a 36-byte buffer.
**Exploitation:** Attacker supplies crafted x/y/len to imageop functions (e.g. grey2rgb) causing heap buffer overflow; fuzzing produced DEP access violations indicating potential arbitrary code execution.
**Insight:** When auditing size/divisibility checks, look for integer division used as a multiplication validator: `size == (product/y)/x` silently accepts non-divisible values. Verify with a remainder-producing input like product=16, y=9.
