cpython
cpython copied to clipboard
`LOAD_ATTR_SLOT` and `STORE_ATTR_SLOT` don't check the owner's type
When specializing LOAD_ATTR_SLOT, we don't check whether the given member descriptor is valid for the type we got it from.
Here is a problematic example, where one class "borrows" a slot from another:
>>> class Class:
... __slots__ = ("slot",)
...
>>> class Sneaky:
... borrowed = Class.slot
...
>>> def f(o):
... return o.borrowed
...
>>> o = Sneaky()
The unspecialized code behaves correctly:
>>> f(o)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
TypeError: descriptor 'slot' for 'Class' objects doesn't apply to a 'Sneaky' object
However, the specialized code crashes, since it is accessing memory past the end of the object:
>>> f(o)
Segmentation fault
We can fix this by performing the same check that the member descriptor performs (PyObject_TypeCheck(obj, descr->d_type)) when specializing.
CC @markshannon
- PR: gh-99258