# Negative size to memcpy/memset

Signed or wrapped length reaching a copy, fill, or offset without a non-negative and capacity check

_Area: Memory corruption and native code. Seen in 9 disclosed reports; 6 confirmed bounties, median $500, range $100-$40,000; latest 2022-05-19. Updated 2026-10-23._

## How it works
A length or size is computed or parsed as a signed value, checked only against an upper bound (or not at all), then handed to memcpy, memset, or used as an array offset. A negative value passes the check because it is "less than" the limit; reinterpreted as an unsigned size it becomes enormous, or as an index it points before the buffer. The broken assumption is that a length that passed a bounds check is non-negative and sane. Signed arithmetic that wraps (e.g. adding padding to a near-INT_MAX length) produces the same negative size without any explicit negative input.

## Where it shows up
- Length fields read as signed types (int8_t, int) from packets or input, checked only against bytes-remaining [E3](https://bugbountylibrary.com/r/h1%3A489102.md).
- Size arithmetic like `width - 1` or `x + count` on user-controlled values that can underflow or wrap [E4](https://bugbountylibrary.com/r/h1%3A191328.md)[E2](https://bugbountylibrary.com/r/h1%3A816637.md).
- Error returns (-1) or negative out-params from crypto/API calls stored into a length and later used as a copy size or index [E5](https://bugbountylibrary.com/r/h1%3A248609.md).
- Padding or block-size addition on a caller-supplied int length overflowing to a negative outlen returned with success [E6](https://bugbountylibrary.com/r/h1%3A1113025.md).
- Clamping helpers like Py_MIN(n, cap) that do not reject negative n before passing it to a C API [E7](https://bugbountylibrary.com/r/h1%3A159690.md).
- Negative size into a container that overflows to a zero-capacity singleton, then a flatten memcpy of 0xffffffff bytes [E1](https://bugbountylibrary.com/r/blog%3Ablog-ret2-io-2022-05-19-pwn2own-2021-parallels-desktop-exploit.md).
- Negative length used directly as an offset for a null-terminator write [E8](https://bugbountylibrary.com/r/h1%3A141212.md).

## How to review
For every memcpy/memset/offset write, trace the size back to its source. Check the declared type of the length variable (signed vs unsigned), whether it is range-checked on both ends (non-negative AND within destination capacity), and whether the destination buffer size is known and compared at the call site. The invariant: the size must be validated as non-negative and within the destination's remaining capacity before use, using unsigned or explicitly clamped arithmetic. Confirm size arithmetic cannot wrap, and that error returns are never stored as lengths.

## Variants seen
- Signed packet length bypassing a remaining-bytes check, overflowing a fixed MAX_* stack buffer [E3](https://bugbountylibrary.com/r/h1%3A489102.md).
- `width-1` underflow in a printf reimplementation feeding memset [E4](https://bugbountylibrary.com/r/h1%3A191328.md).
- Signed accumulator `x+count` wrapping negative to bypass a column bound [E2](https://bugbountylibrary.com/r/h1%3A816637.md).
- API padding addition overflowing INT_MAX to a negative outlen returned with success [E6](https://bugbountylibrary.com/r/h1%3A1113025.md).
- Py_MIN cap defeated by a negative length passed to ncurses [E7](https://bugbountylibrary.com/r/h1%3A159690.md).
- Negative size into a container triggering a huge memcpy [E1](https://bugbountylibrary.com/r/blog%3Ablog-ret2-io-2022-05-19-pwn2own-2021-parallels-desktop-exploit.md).
- Negative length used as an offset for an out-of-bounds null write [E8](https://bugbountylibrary.com/r/h1%3A141212.md).

## Impact and severity
Ranged from crashes to heap/stack corruption [E3](https://bugbountylibrary.com/r/h1%3A489102.md)[E4](https://bugbountylibrary.com/r/h1%3A191328.md)[E5](https://bugbountylibrary.com/r/h1%3A248609.md), guest-to-host VM escape [E1](https://bugbountylibrary.com/r/blog%3Ablog-ret2-io-2022-05-19-pwn2own-2021-parallels-desktop-exploit.md), and out-of-bounds writes [E2](https://bugbountylibrary.com/r/h1%3A816637.md)[E8](https://bugbountylibrary.com/r/h1%3A141212.md). Severity rises when the primitive is repeatable and the target has no fault isolation; a wild memcpy becomes exploitable when the faulting thread's exception handling can be redirected [E1](https://bugbountylibrary.com/r/blog%3Ablog-ret2-io-2022-05-19-pwn2own-2021-parallels-desktop-exploit.md).

## Evidence
- E1: https://bugbountylibrary.com/r/blog%3Ablog-ret2-io-2022-05-19-pwn2own-2021-parallels-desktop-exploit.md
- E2: https://bugbountylibrary.com/r/h1%3A816637.md
- E3: https://bugbountylibrary.com/r/h1%3A489102.md
- E4: https://bugbountylibrary.com/r/h1%3A191328.md
- E5: https://bugbountylibrary.com/r/h1%3A248609.md
- E6: https://bugbountylibrary.com/r/h1%3A1113025.md
- E7: https://bugbountylibrary.com/r/h1%3A159690.md
- E8: https://bugbountylibrary.com/r/h1%3A141212.md
