Skip to content

bpo-43916: Add _PyType_DisabledNew to prevent new heap types from being created uninitialised #25653

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

Closed
wants to merge 17 commits into from

Conversation

erlend-aasland
Copy link
Contributor

@erlend-aasland erlend-aasland commented Apr 27, 2021

TODO

  • SSL/crypo: Christan will take care of this
  • missing dbm/gdbm tests UPDATE: gdbm test added
  • missing multibytecodec tests: suggesting to drop this
  • missing _functools._lru_list_elem test: suggesting to drop this
  • missing _thread._localdummy test: suggesting to drop this
  • convert old workarounds in curses/tkinter to use _PyType_DisabledNew
  • news/what's new UPDATE: Draft NEWS entry added
  • add _PyType_DisabledNew to the internal C API
  • declare _PyType_DisabledNew with extern iso. PyAPI_FUNC: bpo-43916: Add _PyType_DisabledNew to prevent new heap types from being created uninitialised #25653 (comment)
  • fix Windows builds
  • _tkinter fails because Py_BUILD_CORE is not set on Travis

https://bugs.python.org/issue43916

Copy link
Member

@tiran tiran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't like the state->typeobject->tp_new approach. It looks like a hack. Does this work?

keyobject_type_slots[] = {
    {Py_tp_null, NULL},
    ...
}

@bedevere-bot
Copy link

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@erlend-aasland
Copy link
Contributor Author

I don't like the state->typeobject->tp_new approach. It looks like a hack.

I don't like it either, but that's how it has been fixed earlier.

Does this work?

keyobject_type_slots[] = {
    {Py_tp_null, NULL},
    ...
}

Unfortunately, no. Also, Py_tp_null => Py_tp_new :)

How about this:

  1. We add an internal C API function (somewhere in Include/internal/) a la your _disabled_new in _hashopenssl.c.
  2. Add {Py_tp_new, <pointer to new func>}, to affected types

Feels less like a hack, and will be easily greppable.

@tiran
Copy link
Member

tiran commented Apr 27, 2021

Yes, that would be my preferred solution. We have PyType_GenericNew, how about PyType_DisabledNew?

@erlend-aasland
Copy link
Contributor Author

Yes, that would be my preferred solution. We have PyType_GenericNew, how about PyType_DisabledNew?

I like it, but I think we should add it as _PyType_DisabledNew in Include/cpython.

cc. @pablogsal

@shreyanavigyan
Copy link
Contributor

Doesn't this change require a news entry?

@vstinner
Copy link
Member

@tiran @pablogsal: Disabling the constructor is commonly used in Python, so I would not be surprised if this feature would be needed outside CPython code base. I'm fine with adding directly a public function. I understand that @tiran is ok with that, what about you @pablogsal?

@pablogsal
Copy link
Member

pablogsal commented Apr 28, 2021

what about you @pablogsal?

I am still -1, this can be done manually and I prefer to stop growing the C-API when possible unless is very clear that is needed, like with the GC functions.

@vstinner
Copy link
Member

@pablogsal: Sorry, I missed your earlier comment "Can we move this to the inernal API maybe? @vstinner what do you think?".

Ok, let's keep it internal for now. We can revisit that later.

@rhettinger rhettinger removed their request for review April 28, 2021 17:52
@erlend-aasland
Copy link
Contributor Author

erlend-aasland commented Apr 28, 2021

Ok, let's keep it internal for now. We can revisit that later.

All right. I need help landing this PR; see my questions regarding extern raised in this thread: #25653 (comment)

Perhaps it would be easier if I split it up in three:

  1. Add the new API
  2. Apply it to the affected types (except Christian's stuff)
  3. Apply it to _curses_panel and _tkinter

It up to the reviewers :)

@shreyanavigyan
Copy link
Contributor

This time the error is FSCTL_SET_REPARSE_POINT not found

@shreyanavigyan
Copy link
Contributor

Try #include winioctl.h and see if the tests run correctly.

@shreyanavigyan
Copy link
Contributor

shreyanavigyan commented Apr 29, 2021

Looks like windows.h was conflicting with FSCTL_SET_REPARSE_POINT. Now the build is successful.

@erlend-aasland
Copy link
Contributor Author

Try #include winioctl.h and see if the tests run correctly.

The fix is similar to the issue in Modules/posixmodule.c:

#ifdef MS_WINDOWS
/* include <windows.h> early to avoid conflict with pycore_condvar.h:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
FSCTL_GET_REPARSE_POINT is not exported with WIN32_LEAN_AND_MEAN. */
# include <windows.h>
# include <pathcch.h>
#endif

There's a conflict between pycore_condvar.h and windows.h. The former is implicitly included via pycore_object.h. The solution is to reorder the includes.

If a missing Windows include was the problem, the Windows build would have been broken all over.

@erlend-aasland erlend-aasland marked this pull request as ready for review April 29, 2021 08:39
@erlend-aasland
Copy link
Contributor Author

erlend-aasland commented Apr 29, 2021

@pablogsal, @vstinner: I've marked this as ready for review. Test coverage is not complete, but I'm not sure how much time we should put into extracting all the implementation specific types; they are normally hidden from the APIs anyway, and one really has to put an effort into snatching the type and then trying to create it uninitialised. Consenting adults and so on.

I refer to Pablos's comment regarding my problems with declaring _PyType_DisabledNew using extern: #25653 (comment)

@tiran will take care of his stuff, presumably in a separate PR.

I still think the PR is too large, but that's up to you two to decide :)

BTW, _tkinter fails because Py_BUILD_CORE is not set on Travis; I'll have a look at setup.py and Modules/Setup. UPDATE: Fixed in ce16da5

@tiran
Copy link
Member

tiran commented Apr 29, 2021

Urks, extra_compile_args = ['-DPy_BUILD_CORE_MODULE'] is wrong. This shouldn't be an extra compiler arg.

@erlend-aasland
Copy link
Contributor Author

Urks, extra_compile_args = ['-DPy_BUILD_CORE_MODULE'] is wrong. This shouldn't be an extra compiler arg.

I can use define_macros instead, but there's a lot of precedence in setup.py where extra_compile_args is used.

@tiran
Copy link
Member

tiran commented Apr 29, 2021

I have opened PR GH-25713 to address the problem. I'll rebase my PR after you have landed your PR. Let's land your PR first.

@erlend-aasland
Copy link
Contributor Author

I have opened PR GH-25713 to address the problem. I'll rebase my PR after you have landed your PR. Let's land your PR first.

Thank you, Christian!

@erlend-aasland
Copy link
Contributor Author

Thanks for reviewing, @tiran. I have made the requested changes; please review again.

@bedevere-bot
Copy link

Thanks for making the requested changes!

@tiran: please review the changes made to this pull request.

@bedevere-bot bedevere-bot requested a review from tiran April 29, 2021 09:19
Copy link
Member

@tiran tiran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, good work!

@tiran
Copy link
Member

tiran commented Apr 29, 2021

@pablogsal @vstinner Do you want to double check the PR or should I merge it?

@erlend-aasland
Copy link
Contributor Author

LGTM, good work!

Thanks! Actually, you should add attribution to yourself; I've based the core solution off of your work :)

@@ -58,6 +58,13 @@ def tearDown(self):
os_helper.unlink(teardown_file)
self._warnings_manager.__exit__(None, None, None)

@support.cpython_only
def test_uninitialised_new(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is already tested in test_os.

@vstinner
Copy link
Member

I propose a different solution: PR #25721 adds Py_TPFLAGS_DISABLE_NEW type flag.

@erlend-aasland erlend-aasland changed the title bpo-43916: Prevent new heap types from being created uninitialised bpo-43916: Add _PyType_DisabledNew to prevent new heap types from being created uninitialised Apr 30, 2021
@erlend-aasland
Copy link
Contributor Author

Closing in favour of #25721

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants