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 https://github.com/rust-lang/rust/issues/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`.
This commit is contained in:
parent
254ea53f3f
commit
d3762a679f
|
@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- Restrict FFI definitions `PyGILState_Check` and `Py_tracefunc` to the unlimited API. [#1787](https://github.com/PyO3/pyo3/pull/1787)
|
- Restrict FFI definitions `PyGILState_Check` and `Py_tracefunc` to the unlimited API. [#1787](https://github.com/PyO3/pyo3/pull/1787)
|
||||||
|
- Add missing `_type` field to `PyStatus` struct definition.
|
||||||
|
|
||||||
## [0.14.2] - 2021-08-09
|
## [0.14.2] - 2021-08-09
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ use crate::ffi::Py_ssize_t;
|
||||||
use libc::wchar_t;
|
use libc::wchar_t;
|
||||||
use std::os::raw::{c_char, c_int, c_ulong};
|
use std::os::raw::{c_char, c_int, c_ulong};
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
pub enum _PyStatus_TYPE {
|
pub enum _PyStatus_TYPE {
|
||||||
_PyStatus_TYPE_OK = 0,
|
_PyStatus_TYPE_OK = 0,
|
||||||
|
@ -14,6 +15,7 @@ pub enum _PyStatus_TYPE {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct PyStatus {
|
pub struct PyStatus {
|
||||||
|
pub _type: _PyStatus_TYPE,
|
||||||
pub func: *const c_char,
|
pub func: *const c_char,
|
||||||
pub err_msg: *const c_char,
|
pub err_msg: *const c_char,
|
||||||
pub exitcode: c_int,
|
pub exitcode: c_int,
|
||||||
|
|
Loading…
Reference in a new issue