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

Skip to content

Reference count leak when there is an error in the BUILD_MAP opcode #109216

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
timofej673 opened this issue Sep 10, 2023 · 2 comments
Closed

Reference count leak when there is an error in the BUILD_MAP opcode #109216

timofej673 opened this issue Sep 10, 2023 · 2 comments
Labels
type-bug An unexpected behavior, bug, or error

Comments

@timofej673
Copy link

timofej673 commented Sep 10, 2023

Bug report

Bug description:

        inst(BUILD_MAP, (values[oparg*2] -- map)) {
            map = _PyDict_FromItems(
                    values, 2,
                    values+1, 2,
                    oparg);
            if (map == NULL)     <--------------
                goto error; <------------------

            DECREF_INPUTS();
            ERROR_IF(map == NULL, error);
        }

If an error occurs, the number of links will not decrease

CPython versions tested on:

CPython main branch

Operating systems tested on:

Windows

Linked PRs

@timofej673 timofej673 added the type-bug An unexpected behavior, bug, or error label Sep 10, 2023
@sobolevn
Copy link
Member

Generated code is also wrong:

        TARGET(BUILD_MAP) {
            PyObject **values;
            PyObject *map;
            values = stack_pointer - oparg*2;
            map = _PyDict_FromItems(
                    values, 2,
                    values+1, 2,
                    oparg);
            if (map == NULL)
                goto error;

            for (int _i = oparg*2; --_i >= 0;) {
                Py_DECREF(values[_i]);
            }
            if (map == NULL) { STACK_SHRINK(oparg*2); goto error; }
            STACK_SHRINK(oparg*2);
            STACK_GROW(1);
            stack_pointer[-1] = map;
            DISPATCH();
        }

Here's how BUILD_CONST_KEY_MAP is defined:

        inst(BUILD_CONST_KEY_MAP, (values[oparg], keys -- map)) {
            if (!PyTuple_CheckExact(keys) ||
                PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) {
                _PyErr_SetString(tstate, PyExc_SystemError,
                                 "bad BUILD_CONST_KEY_MAP keys argument");
                goto error;  // Pop the keys and values.
            }
            map = _PyDict_FromItems(
                    &PyTuple_GET_ITEM(keys, 0), 1,
                    values, 1, oparg);
            DECREF_INPUTS();
            ERROR_IF(map == NULL, error);
        }

It seems to generate correct code:

        TARGET(BUILD_CONST_KEY_MAP) {
            PyObject *keys;
            PyObject **values;
            PyObject *map;
            keys = stack_pointer[-1];
            values = stack_pointer - 1 - oparg;
            if (!PyTuple_CheckExact(keys) ||
                PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) {
                _PyErr_SetString(tstate, PyExc_SystemError,
                                 "bad BUILD_CONST_KEY_MAP keys argument");
                goto error;  // Pop the keys and values.
            }
            map = _PyDict_FromItems(
                    &PyTuple_GET_ITEM(keys, 0), 1,
                    values, 1, oparg);
            for (int _i = oparg; --_i >= 0;) {
                Py_DECREF(values[_i]);
            }
            Py_DECREF(keys);
            if (map == NULL) { STACK_SHRINK(oparg); goto pop_1_error; }
            STACK_SHRINK(oparg);
            stack_pointer[-1] = map;
            DISPATCH();
        }

sobolevn added a commit to sobolevn/cpython that referenced this issue Sep 11, 2023
@gvanrossum gvanrossum changed the title The number of links does not decrease when there is an error in the BUILD_MAP opcode Reference count leak when there is an error in the BUILD_MAP opcode Sep 12, 2023
@timofej673
Copy link
Author

This bug is present from python 3.11

sobolevn added a commit to sobolevn/cpython that referenced this issue Sep 12, 2023
sobolevn added a commit to sobolevn/cpython that referenced this issue Sep 12, 2023
vstinner pushed a commit to vstinner/cpython that referenced this issue Sep 13, 2023
kumaraditya303 added a commit to sobolevn/cpython that referenced this issue Oct 12, 2023
kumaraditya303 added a commit that referenced this issue Oct 12, 2023
* [3.11] gh-109216: Fix possible memory leak in `BUILD_MAP`

* Add NEWS

* Update Python/ceval.c

Co-authored-by: Kumar Aditya <[email protected]>

---------

Co-authored-by: Kumar Aditya <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

3 participants