Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 37346b2

Browse files
committed
python#3643 add a few more checks to _testcapi to prevent segfaults
Author: Victor Stinner Reviewer: Benjamin Peterson
1 parent 7161cbf commit 37346b2

2 files changed

Lines changed: 26 additions & 4 deletions

File tree

Misc/NEWS

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ Library
2525

2626
- Fixed two format strings in the _collections module.
2727

28+
Extension Modules
29+
-----------------
30+
31+
- Issue #3643: Added a few more checks to _testcapi to prevent segfaults by
32+
exploitation of poor argument checking.
33+
2834

2935
What's New in Python 2.6 beta 3?
3036
================================

Modules/_testcapimodule.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -600,6 +600,10 @@ raise_exception(PyObject *self, PyObject *args)
600600
if (!PyArg_ParseTuple(args, "Oi:raise_exception",
601601
&exc, &num_args))
602602
return NULL;
603+
if (!PyExceptionClass_Check(exc)) {
604+
PyErr_Format(PyExc_TypeError, "an exception class is required");
605+
return NULL;
606+
}
603607

604608
exc_args = PyTuple_New(num_args);
605609
if (exc_args == NULL)
@@ -628,14 +632,17 @@ raise_exception(PyObject *self, PyObject *args)
628632
*/
629633
static PyThread_type_lock thread_done = NULL;
630634

631-
static void
635+
static int
632636
_make_call(void *callable)
633637
{
634638
PyObject *rc;
639+
int success;
635640
PyGILState_STATE s = PyGILState_Ensure();
636641
rc = PyObject_CallFunction((PyObject *)callable, "");
642+
success = (rc != NULL);
637643
Py_XDECREF(rc);
638644
PyGILState_Release(s);
645+
return success;
639646
}
640647

641648
/* Same thing, but releases `thread_done` when it returns. This variant
@@ -652,10 +659,17 @@ static PyObject *
652659
test_thread_state(PyObject *self, PyObject *args)
653660
{
654661
PyObject *fn;
662+
int success = 1;
655663

656664
if (!PyArg_ParseTuple(args, "O:test_thread_state", &fn))
657665
return NULL;
658666

667+
if (!PyCallable_Check(fn)) {
668+
PyErr_Format(PyExc_TypeError, "'%s' object is not callable",
669+
fn->ob_type->tp_name);
670+
return NULL;
671+
}
672+
659673
/* Ensure Python is set up for threading */
660674
PyEval_InitThreads();
661675
thread_done = PyThread_allocate_lock();
@@ -666,10 +680,10 @@ test_thread_state(PyObject *self, PyObject *args)
666680
/* Start a new thread with our callback. */
667681
PyThread_start_new_thread(_make_call_from_thread, fn);
668682
/* Make the callback with the thread lock held by this thread */
669-
_make_call(fn);
683+
success &= _make_call(fn);
670684
/* Do it all again, but this time with the thread-lock released */
671685
Py_BEGIN_ALLOW_THREADS
672-
_make_call(fn);
686+
success &= _make_call(fn);
673687
PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */
674688
Py_END_ALLOW_THREADS
675689

@@ -679,14 +693,16 @@ test_thread_state(PyObject *self, PyObject *args)
679693
*/
680694
Py_BEGIN_ALLOW_THREADS
681695
PyThread_start_new_thread(_make_call_from_thread, fn);
682-
_make_call(fn);
696+
success &= _make_call(fn);
683697
PyThread_acquire_lock(thread_done, 1); /* wait for thread to finish */
684698
Py_END_ALLOW_THREADS
685699

686700
/* Release lock we acquired above. This is required on HP-UX. */
687701
PyThread_release_lock(thread_done);
688702

689703
PyThread_free_lock(thread_done);
704+
if (!success)
705+
return NULL;
690706
Py_RETURN_NONE;
691707
}
692708
#endif

0 commit comments

Comments
 (0)