Repository navigation
skip cffi objects reached as module attributes -- the int-as-pointer surface --blacklist misses - #268
Merged
Conversation
…surface --blacklist misses --blacklist excludes _cffi_backend / _rawffi / ctypes by MODULE NAME, but PyPy's stdlib hands out live cffi objects as module ATTRIBUTES -- resource.ffi, _ssl.ffi, _sqlite3._ffi, _lzma.ffi, _gdbm.ffi, _curses.ffi, _tkinter.tkffi, _sha3._ffi, _posixshmem.ffi and their matching .lib -- so the surface is reachable regardless of the module blacklist. ffi.memmove(int, int, n) treats its arguments as raw pointers and dies by contract on whatever integer it is handed, exactly as CPython's ctypes does, so a fault there is never a target defect. Four consecutive PyPy fleets kept dirs from it (05, 06, 07, 08), which is why this is being applied now rather than flagged a fifth time. skip_trivial_type is already emitted into every generated script and already consulted at all three object/class dive sites, so the change is one condition there. It matches on the TYPE's defining module, not on the attribute name: an OBJECT_BLACKLIST entry for "ffi"/"lib"/"_ffi"/"tkffi" would match those names on unrelated targets that legitimately expose them, and there is a test pinning that distinction. Two things worth noting for future edits here: The first version of the comment used the words "segfault"/"segfaults", and SelfNoiseVocabularyTests caught it. That guard exists because help() echoes emitted comments through inspect.getcomments, so fusil's own crash vocabulary in a generated comment manufactures a crash -- the comment now says so in place, since this is the second time that trap has been walked into. The emitted function is SOURCE, so a golden snapshot cannot catch a logic error in it. The new tests parse it out of the generated script, exec it, and exercise it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The last of the four items left open by the fleet_08 triage that I can act on alone. Flagged in
the fleet_05, _06, _07 and _08 reports without being applied, because it changes the default
fuzzing surface — applying it now that it has cost dirs in four consecutive fleets.
The gap
--blacklistexcludes_cffi_backend/_rawffi/ctypesby module name. But PyPy'sstdlib hands out live cffi objects as module attributes, so the surface is reachable
regardless. Measured on PyPy 7.3.23:
ffi.memmove(int, int, n)treats its arguments as raw pointers and dies by contract onwhatever integer it is handed — exactly as CPython's
ctypesdoes on the same input. A faultthere is never a target defect. It is the same shape as the
socketint-as-fd family fixedin #266, one level down.
The change
skip_trivial_typeis already emitted into every generated script and already consulted at allthree object/class dive sites, so this is one condition there.
It matches on the type's defining module, not on the attribute name. An
OBJECT_BLACKLISTentry for
"ffi"/"lib"/"_ffi"/"tkffi"would match those names on unrelated targetsthat legitimately expose them — there is a test pinning that distinction
(
test_an_attribute_merely_NAMED_ffi_is_not_skipped).Tests
The emitted function is source text, so the golden snapshot alone cannot catch a logic
error in it. The new tests parse
skip_trivial_typeout of the generated script,execit,and exercise it: a cffi-typed object is skipped, an ordinary object is not, the trivial types
still are, and an object merely named
ffiis not.The golden snapshot is updated; its only diff is this guard.
One trap worth recording
My first version of the comment used the words "segfault"/"segfaults", and
SelfNoiseVocabularyTestsfailed the build. That guard exists becausehelp()echoes emittedcomments through
inspect.getcomments, so fusil's own crash vocabulary inside a generatedcomment manufactures a crash — a PyPy fleet kept a
_sitebuiltins-segfaultdir exactly thatway. The comment now says so in place, since that is the second time the trap has been walked
into.
Checks
1284 tests OK,
ruff checkandruff format --checkboth clean.