From d47be9dea453b824aa16992eab34edc2e7921f51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 25 Jan 2025 11:55:20 +0100 Subject: [PATCH 1/3] fix UBSan failures for LZMA objects --- Modules/_lzmamodule.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index 97f3a8f03da9a8..ece6f5fa286b0a 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -126,6 +126,9 @@ typedef struct { PyThread_type_lock lock; } Decompressor; +#define _Compressor_CAST(op) ((Compressor *)(op)) +#define _Decompressor_CAST(op) ((Decompressor *)(op)) + /* Helper functions. */ static int @@ -857,14 +860,15 @@ Compressor_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) } static void -Compressor_dealloc(Compressor *self) +Compressor_dealloc(PyObject *op) { + Compressor *self = _Compressor_CAST(op); lzma_end(&self->lzs); if (self->lock != NULL) { PyThread_free_lock(self->lock); } PyTypeObject *tp = Py_TYPE(self); - tp->tp_free((PyObject *)self); + tp->tp_free(self); Py_DECREF(tp); } @@ -875,7 +879,7 @@ static PyMethodDef Compressor_methods[] = { }; static int -Compressor_traverse(Compressor *self, visitproc visit, void *arg) +Compressor_traverse(PyObject *self, visitproc visit, void *arg) { Py_VISIT(Py_TYPE(self)); return 0; @@ -1304,8 +1308,9 @@ _lzma_LZMADecompressor_impl(PyTypeObject *type, int format, } static void -Decompressor_dealloc(Decompressor *self) +Decompressor_dealloc(PyObject *op) { + Decompressor *self = _Decompressor_CAST(op); if(self->input_buffer != NULL) PyMem_Free(self->input_buffer); @@ -1315,12 +1320,12 @@ Decompressor_dealloc(Decompressor *self) PyThread_free_lock(self->lock); } PyTypeObject *tp = Py_TYPE(self); - tp->tp_free((PyObject *)self); + tp->tp_free(self); Py_DECREF(tp); } static int -Decompressor_traverse(Decompressor *self, visitproc visit, void *arg) +Decompressor_traverse(PyObject *self, visitproc visit, void *arg) { Py_VISIT(Py_TYPE(self)); return 0; From f9fc53d67870dbb0369be8b913dfe0c5aa26d7a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 25 Jan 2025 11:55:41 +0100 Subject: [PATCH 2/3] suppress unused return values --- Modules/_lzmamodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index ece6f5fa286b0a..4a595bb1cbacaa 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -1638,7 +1638,7 @@ lzma_clear(PyObject *module) static void lzma_free(void *module) { - lzma_clear((PyObject *)module); + (void)lzma_clear((PyObject *)module); } static PyModuleDef _lzmamodule = { From 9a206254a76bb0ba336cc25c86d45cb16626642e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A9n=C3=A9dikt=20Tran?= <10796600+picnixz@users.noreply.github.com> Date: Sat, 8 Feb 2025 10:11:40 +0100 Subject: [PATCH 3/3] Do not use `_` + capital letter in new code as it is also UB. --- Modules/_lzmamodule.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Modules/_lzmamodule.c b/Modules/_lzmamodule.c index 4a595bb1cbacaa..0058e2eec2ef16 100644 --- a/Modules/_lzmamodule.c +++ b/Modules/_lzmamodule.c @@ -126,8 +126,8 @@ typedef struct { PyThread_type_lock lock; } Decompressor; -#define _Compressor_CAST(op) ((Compressor *)(op)) -#define _Decompressor_CAST(op) ((Decompressor *)(op)) +#define Compressor_CAST(op) ((Compressor *)(op)) +#define Decompressor_CAST(op) ((Decompressor *)(op)) /* Helper functions. */ @@ -862,7 +862,7 @@ Compressor_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) static void Compressor_dealloc(PyObject *op) { - Compressor *self = _Compressor_CAST(op); + Compressor *self = Compressor_CAST(op); lzma_end(&self->lzs); if (self->lock != NULL) { PyThread_free_lock(self->lock); @@ -1310,7 +1310,7 @@ _lzma_LZMADecompressor_impl(PyTypeObject *type, int format, static void Decompressor_dealloc(PyObject *op) { - Decompressor *self = _Decompressor_CAST(op); + Decompressor *self = Decompressor_CAST(op); if(self->input_buffer != NULL) PyMem_Free(self->input_buffer);