Closed cuu508 closed 2 years ago
Oh, thanks for the heads-up, we'll look into it.
Looks like this is specific to the 3.10 upgrade
I believe I've identified the issue. After instrumenting code, Atheris needs to fix-up instruction offsets. In one code path in adjust()
, the offsets are adjusted like this:
self.reference += size # type: ignore[operator]
self.arg += size
Calling self.arg += size
in 3.10 is incorrect, because the argument to jump instructions changed from a byte offset to an instruction offset.
The correct code is:
self.reference += size # type: ignore[operator]
self.arg = add_bytes_to_jump_arg(self.arg, size)
This wasn't detected during testing because this particular code path is only triggered in the unlikely event that (1) the argument is an offset for an absolute jump instruction, and (2) the argument was previously <256 but is now >=256.
Here's a minimum reproducer of this issue:
import atheris
@atheris.instrument_func
def _ord2ymd(n):
n -= 1
n400, n = divmod(n, 1)
year = n400 * 400 + 1
n100, n = divmod(n, 1)
n4, n = divmod(n, 1)
n1, n = divmod(n, 1)
leapyear = n1 == 3 and (n4 != 24 or n100 == 3)
assert leapyear == baz(year)
month = (n + 50) >> 5
preceding = baz[month] + (month > 2 and leapyear)
if preceding > n:
month -= 1
preceding -= bar[month] + (month == 2 and leapyear)
n -= preceding
assert 0 <= n < foo()
We'll validate that this fix is indeed correct, and if so cut a release, most likely tomorrow.
Issue fixed and released as 2.0.11.
Code:
Output: