This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author pablogsal
Recipients Mark.Shannon, christian.heimes, jdemeyer, lukasz.langa, pablogsal, petr.viktorin, pitrou, vstinner
Date 2019-09-02.12:34:51
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1567427691.78.0.937566676122.issue38006@roundup.psfhosted.org>
In-reply-to
Content
I think the real problem is in vectorcall. tp_clear will make sure all internal pointers are either NULL or valid (by using Py_CLEAR, which also protects against re-entrancy) and it the responsibility of the object or its users to check that the fields that are needed are valid. From the docs on tp_clear:

> The Py_CLEAR() macro should be used, because clearing references is delicate: the reference to the contained object must not be decremented until after the pointer to the contained object is set to NULL. This is because decrementing the reference count may cause the contained object to become trash, triggering a chain of reclamation activity that may include invoking arbitrary Python code (due to finalizers, or weakref callbacks, associated with the contained object). If it’s possible for such code to reference self again, it’s important that the pointer to the contained object be NULL at that time, so that self knows the contained object can no longer be used. 

Notice the "so that self knows the contained object can no longer be used". I think _PyFunction_Vectorcall is missing the check "to see of the contained object can or cannot be used". Here the contained object being everything that has being cleaned before:

    Py_CLEAR(op->func_code);
    Py_CLEAR(op->func_globals);
    Py_CLEAR(op->func_module);
    Py_CLEAR(op->func_name);
    Py_CLEAR(op->func_defaults);
    Py_CLEAR(op->func_kwdefaults);
    Py_CLEAR(op->func_doc);
    Py_CLEAR(op->func_dict);
    Py_CLEAR(op->func_closure); <----- Everything before this
    Py_CLEAR(op->func_annotations);
    Py_CLEAR(op->func_qualname);

I think it will be enough to make a check for func_code being NULL in _PyFunction_Vectorcall or before.
History
Date User Action Args
2019-09-02 12:34:51pablogsalsetrecipients: + pablogsal, pitrou, vstinner, christian.heimes, petr.viktorin, lukasz.langa, Mark.Shannon, jdemeyer
2019-09-02 12:34:51pablogsalsetmessageid: <1567427691.78.0.937566676122.issue38006@roundup.psfhosted.org>
2019-09-02 12:34:51pablogsallinkissue38006 messages
2019-09-02 12:34:51pablogsalcreate