Skip to content

Commit b5b211f

Browse files
committed
ffi: fix PyStatus._type
The field wasn't defined previously. And the enum wasn't defined as `[repr(C)]`. This missing field could result in memory corruption if a Rust-allocated `PyStatus` was passed to a Python API, which could perform an out-of-bounds write. In my code, the out-of-bounds write corrupted a variable on the stack, leading to a segfault due to illegal memory access. However, this crash only occurred on Rust 1.54! So I initially mis-attribted it as a compiler bug / regression. It appears that a low-level Rust change in 1.54.0 changed the LLVM IR in such a way to cause LLVM optimization passes to produce sufficiently different assembly code, tickling the crash. See rust-lang/rust#87947 if you want to see the wild goose chase I went on in Rust / LLVM land to potentially pin this on a compiler bug. Lessen learned: Rust crashes are almost certainly due to use of `unsafe`.
1 parent d69912b commit b5b211f

File tree

2 files changed

+3
-0
lines changed

2 files changed

+3
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1616

1717
- Restrict FFI definitions `PyGILState_Check` and `Py_tracefunc` to the unlimited API. [#1787](https://github.com/PyO3/pyo3/pull/1787)
1818
- Raise `AttributeError` to avoid panic when calling `del` on a `[setter]` defined class property. [#1775](https://github.com/PyO3/pyo3/issues/1775)
19+
- Add missing `_type` field to `PyStatus` struct definition.
1920

2021
## [0.14.2] - 2021-08-09
2122

src/ffi/cpython/initconfig.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use crate::ffi::Py_ssize_t;
44
use libc::wchar_t;
55
use std::os::raw::{c_char, c_int, c_ulong};
66

7+
#[repr(C)]
78
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
89
pub enum _PyStatus_TYPE {
910
_PyStatus_TYPE_OK = 0,
@@ -14,6 +15,7 @@ pub enum _PyStatus_TYPE {
1415
#[repr(C)]
1516
#[derive(Copy, Clone)]
1617
pub struct PyStatus {
18+
pub _type: _PyStatus_TYPE,
1719
pub func: *const c_char,
1820
pub err_msg: *const c_char,
1921
pub exitcode: c_int,

0 commit comments

Comments
 (0)