> Conventionally, in software security, Python is considered a memory-safe language. The piece makes the case that Python isn't memory safe when you FFI into a C library.
Interesting and largely unknown trivia: it's possible to invoke memory errors in the underlying C interpreter from pure Python code — no libraries and no imports needed!
One way of doing this is by creating new `code` objects with crafted bytecode. There is no bytecode verifier in Python to make sure, say, referenced stack variables in the VM are valid...
Is this because of a bug and might be fixed in the future or is it considered an unavoidable consequence of some design decision and will stay that way for the foreseeable future?
From what I understand about Rust, if something similar was possible in safe Rust it would be considered a bug and eventually fixed.
I think it will stay that way for the foreseeable future (but who can say). Ways to fix the particular hole:
(1) disable creating new `code` objects directly from Python. This probably would break lots of things.
(2) Add a bytecode verification mechanism that would reject `code` objects whose bytecode would result in memory errors when executed. This could be a lot of implementation work; I'm not sure.
You also don't need to FFI into some buggy C library to violate memory safety with ctypes. It's trivial to produce a segfault with it without using anything but ctypes itself, which is part of the standard library. I doubt I'd have much trouble finding other ways to make a segfault with pure python and the standard library (struct springs to mind).
CPython really isn't very safe at all. Its focus has always been on being a convenient, dynamic scripting language with minimal-fuss access to native code. It has never been hard to violate its internal assumptions and it probably never will be.
And I'm pretty comfortable with that, FWIW.