summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
authorcolorfulappl <colorfulappl@qq.com>2022-11-24 14:01:26 (GMT)
committerGitHub <noreply@github.com>2022-11-24 14:01:26 (GMT)
commit8dbe08eb7c807f484fe9870f5b7f5ae2881fd966 (patch)
treee8a735022f12ba4a1b73dc2449d6e5e40383bded /Modules
parent69f6cc77d0f1664f983a83b6ae707d99a99f5c4f (diff)
downloadcpython-8dbe08eb7c807f484fe9870f5b7f5ae2881fd966.zip
cpython-8dbe08eb7c807f484fe9870f5b7f5ae2881fd966.tar.gz
cpython-8dbe08eb7c807f484fe9870f5b7f5ae2881fd966.tar.bz2
gh-99240: Fix double-free bug in Argument Clinic str_converter generated code (GH-99241)
Fix double-free bug mentioned at https://github.com/python/cpython/issues/99240, by moving memory clean up out of "exit" label. Automerge-Triggered-By: GH:erlend-aasland
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_testclinic.c79
-rw-r--r--Modules/clinic/_testclinic.c.h72
2 files changed, 150 insertions, 1 deletions
diff --git a/Modules/_testclinic.c b/Modules/_testclinic.c
index a23ece2..56eddfd 100644
--- a/Modules/_testclinic.c
+++ b/Modules/_testclinic.c
@@ -551,6 +551,64 @@ error:
}
+/*[clinic input]
+str_converter_encoding
+
+ a: str(encoding="idna")
+ b: str(encoding="idna", accept={bytes, bytearray, str})
+ c: str(encoding="idna", accept={bytes, bytearray, str}, zeroes=True)
+ /
+
+[clinic start generated code]*/
+
+static PyObject *
+str_converter_encoding_impl(PyObject *module, char *a, char *b, char *c,
+ Py_ssize_t c_length)
+/*[clinic end generated code: output=af68766049248a1c input=0c5cf5159d0e870d]*/
+{
+ assert(!PyErr_Occurred());
+ PyObject *out[3] = {NULL,};
+ int i = 0;
+ PyObject *arg;
+
+ arg = PyUnicode_FromString(a);
+ assert(arg || PyErr_Occurred());
+ if (!arg) {
+ goto error;
+ }
+ out[i++] = arg;
+
+ arg = PyUnicode_FromString(b);
+ assert(arg || PyErr_Occurred());
+ if (!arg) {
+ goto error;
+ }
+ out[i++] = arg;
+
+ arg = PyUnicode_FromStringAndSize(c, c_length);
+ assert(arg || PyErr_Occurred());
+ if (!arg) {
+ goto error;
+ }
+ out[i++] = arg;
+
+ PyObject *tuple = PyTuple_New(3);
+ if (!tuple) {
+ goto error;
+ }
+ for (int j = 0; j < 3; j++) {
+ PyTuple_SET_ITEM(tuple, j, out[j]);
+ }
+ return tuple;
+
+error:
+ for (int j = 0; j < i; j++) {
+ Py_DECREF(out[j]);
+ }
+ return NULL;
+}
+
+
static PyObject *
bytes_from_buffer(Py_buffer *buf)
{
@@ -927,6 +985,25 @@ gh_99233_refcount_impl(PyObject *module, PyObject *args)
}
+/*[clinic input]
+gh_99240_double_free
+
+ a: str(encoding="idna")
+ b: str(encoding="idna")
+ /
+
+Proof-of-concept of GH-99240 double-free bug.
+
+[clinic start generated code]*/
+
+static PyObject *
+gh_99240_double_free_impl(PyObject *module, char *a, char *b)
+/*[clinic end generated code: output=586dc714992fe2ed input=23db44aa91870fc7]*/
+{
+ Py_RETURN_NONE;
+}
+
+
static PyMethodDef tester_methods[] = {
TEST_EMPTY_FUNCTION_METHODDEF
OBJECTS_CONVERTER_METHODDEF
@@ -951,6 +1028,7 @@ static PyMethodDef tester_methods[] = {
DOUBLE_CONVERTER_METHODDEF
PY_COMPLEX_CONVERTER_METHODDEF
STR_CONVERTER_METHODDEF
+ STR_CONVERTER_ENCODING_METHODDEF
PY_BUFFER_CONVERTER_METHODDEF
KEYWORDS_METHODDEF
KEYWORDS_KWONLY_METHODDEF
@@ -970,6 +1048,7 @@ static PyMethodDef tester_methods[] = {
KEYWORD_ONLY_PARAMETER_METHODDEF
VARARG_AND_POSONLY_METHODDEF
GH_99233_REFCOUNT_METHODDEF
+ GH_99240_DOUBLE_FREE_METHODDEF
{NULL, NULL}
};
diff --git a/Modules/clinic/_testclinic.c.h b/Modules/clinic/_testclinic.c.h
index eb42582..9aad445 100644
--- a/Modules/clinic/_testclinic.c.h
+++ b/Modules/clinic/_testclinic.c.h
@@ -1165,6 +1165,43 @@ exit:
return return_value;
}
+PyDoc_STRVAR(str_converter_encoding__doc__,
+"str_converter_encoding($module, a, b, c, /)\n"
+"--\n"
+"\n");
+
+#define STR_CONVERTER_ENCODING_METHODDEF \
+ {"str_converter_encoding", _PyCFunction_CAST(str_converter_encoding), METH_FASTCALL, str_converter_encoding__doc__},
+
+static PyObject *
+str_converter_encoding_impl(PyObject *module, char *a, char *b, char *c,
+ Py_ssize_t c_length);
+
+static PyObject *
+str_converter_encoding(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ char *a = NULL;
+ char *b = NULL;
+ char *c = NULL;
+ Py_ssize_t c_length;
+
+ if (!_PyArg_ParseStack(args, nargs, "esetet#:str_converter_encoding",
+ "idna", &a, "idna", &b, "idna", &c, &c_length)) {
+ goto exit;
+ }
+ return_value = str_converter_encoding_impl(module, a, b, c, c_length);
+ /* Post parse cleanup for a */
+ PyMem_FREE(a);
+ /* Post parse cleanup for b */
+ PyMem_FREE(b);
+ /* Post parse cleanup for c */
+ PyMem_FREE(c);
+
+exit:
+ return return_value;
+}
+
PyDoc_STRVAR(py_buffer_converter__doc__,
"py_buffer_converter($module, a, b, /)\n"
"--\n"
@@ -2353,4 +2390,37 @@ exit:
Py_XDECREF(__clinic_args);
return return_value;
}
-/*[clinic end generated code: output=a5c9f181f3a32d85 input=a9049054013a1b77]*/
+
+PyDoc_STRVAR(gh_99240_double_free__doc__,
+"gh_99240_double_free($module, a, b, /)\n"
+"--\n"
+"\n"
+"Proof-of-concept of GH-99240 double-free bug.");
+
+#define GH_99240_DOUBLE_FREE_METHODDEF \
+ {"gh_99240_double_free", _PyCFunction_CAST(gh_99240_double_free), METH_FASTCALL, gh_99240_double_free__doc__},
+
+static PyObject *
+gh_99240_double_free_impl(PyObject *module, char *a, char *b);
+
+static PyObject *
+gh_99240_double_free(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
+{
+ PyObject *return_value = NULL;
+ char *a = NULL;
+ char *b = NULL;
+
+ if (!_PyArg_ParseStack(args, nargs, "eses:gh_99240_double_free",
+ "idna", &a, "idna", &b)) {
+ goto exit;
+ }
+ return_value = gh_99240_double_free_impl(module, a, b);
+ /* Post parse cleanup for a */
+ PyMem_FREE(a);
+ /* Post parse cleanup for b */
+ PyMem_FREE(b);
+
+exit:
+ return return_value;
+}
+/*[clinic end generated code: output=49dced2c99bcd0fb input=a9049054013a1b77]*/