-
Notifications
You must be signed in to change notification settings - Fork 476
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rework syscall invocation for proper behavior under typeguard #1672
Conversation
Previously, using Typeguard with Manticore would break several emulated syscalls. With this commit, it does not. Some background information: When a syscall is made from an emulated binary, Manticore uses the syscall number to look up the appropriate Python method that models that syscall, and then uses Python introspection to massage arguments to that syscall model function as deemed appropriate. Previously, this mechanism used the deprecated `inspect.getfullargspec` to determine the number of arguments to the model function, and whether or not it takes varargs. However, `inspect.getfullargspec` doesn't look through wrapper functions; it looks only at exactly the function object it is given. This is an issue, however, when trying to inspect _decorated_ functions. (The use of a decorator in Python introduces a _new_ function object that wraps the decorated item.) How did that break Manticore when using Typeguard? It turns out that When using Typeguard via the `--typeguard-packages=manticore` option to `pytest`, the Typeguard plugin implicitly adds a `@typeguard.check_types` decorator on _every_ function & method in the `manticore` package. In this way, each syscall implementation function in Manticore ends up with a wrapper around it, and the syscall invocation mechanism based on `inspect.getfullargspec` would somewhat quietly cause syscalls to break. Now, instead of using `inspect.getfullargspec`, Manticore's syscall invocation mechansim uses the non-deprecated `inspect.signature` API to get the needed information. This API _does_ look through wrapper functions. Additionally, it allows us to get rid of some conditional logic, about whether `self` appears in a function's parameter list or not.
Wondering: Do we still need |
We only were using `wrapt` in a single place -- to implement the `unimplemented` syscall decorator. That dependency was added in #1384, so that the old syscall mechanism could work with the decorator. Now, with the rework of Manticore's syscall mechanism, this is no longer necessary, and a "regular" Python decorator implemented using `functools.wraps` should work just fine.
@ehennenfent I looked at this a bit closer, and I don't think it's necessary any more! So I've rephrased the single use of |
Additionally, add some extra tests for the decorator, to get better coverage from where it is used.
(found with `mypy --check-untyped-defs` and some grep)
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
* master: (28 commits) Rework syscall invocation for proper behavior under typeguard (#1672) printable_bytes (#1671) Fix several incorrect type hints (#1668) Add type hints to several parts of Manticore (#1667) Fix type confusion in manual CPU tests; delete dead testing code (#1669) Rework WASM Imports and Fix Typos (#1666) Work on "Model is not Available" errors in tests (#1659) Fix TypeGuard Errors in WASM Module (#1601) Remove unused arg ans separate output from workspace (#1651) Add a badge to README.md for LGTM (#1647) Fix 2 problems in Linux `sys_open` support & add type hints (#1657) Fix LGTM Errors (#1656) Delay WASM Branch Condition Concretization (#1641) Add feature for SymbolicSocket through sys_accept (#1618) Add a bunch of type hints & fix a few issues with Linux platform emulation (#1645) Bump to CheckoutV2 (#1654) Add support for `sys_arm_fadvise64_64` (#1648) Add __slots__ to expressions (#1635) Swap remaining uses of `Z3Solver()` to use the singleton interface (#1649) CI: have pytest report 100 slowest tests (#1646) ...
Previously, using Typeguard with Manticore would break several emulated syscalls. With this commit, it does not.
Some background information:
When a syscall is made from an emulated binary, Manticore uses the syscall number to look up the appropriate Python method that models that syscall, and then uses Python introspection to massage arguments to that syscall model function as deemed appropriate.
Previously, this mechanism used the deprecated
inspect.getfullargspec
to determine the number of arguments to the model function, and whether or not it takes varargs.However,
inspect.getfullargspec
doesn't look through wrapper functions; it looks only at exactly the function object it is given. This is an issue, however, when trying to inspect decorated functions. (The use of a decorator in Python introduces a new function object that wraps the decorated item.)How did that break Manticore when using Typeguard? It turns out that when using Typeguard via the
--typeguard-packages=manticore
option topytest
, the Typeguard plugin implicitly adds a@typeguard.check_types
decorator on every function & method in themanticore
package.In this way, each syscall implementation function in Manticore ends up with a wrapper around it, and the syscall invocation mechanism based on
inspect.getfullargspec
would somewhat quietly cause syscalls to break.Now, instead of using
inspect.getfullargspec
, Manticore's syscall invocation mechansim uses the non-deprecatedinspect.signature
API to get the needed information. This API does look through wrapper functions. Additionally, it allows us to get rid of some conditional logic, about whetherself
appears in a function's parameter list or not.