Skip to content
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

Importing ssl After Reinitializing Crashes #122334

Closed
ericsnowcurrently opened this issue Jul 26, 2024 · 6 comments
Closed

Importing ssl After Reinitializing Crashes #122334

ericsnowcurrently opened this issue Jul 26, 2024 · 6 comments
Labels
3.12 bugs and security fixes 3.13 bugs and security fixes 3.14 new features, bugs and security fixes type-crash A hard crash of the interpreter, possibly with a core dump

Comments

@ericsnowcurrently
Copy link
Member

ericsnowcurrently commented Jul 26, 2024

Crash report

What happened?

Using 3.13b4 and main (5592399):

$ Programs/_testembed test_repeated_init_exec 'import ssl'
--- Loop #1 ---
--- Loop #2 ---
Segmentation fault (core dumped)

Using 3.12:

$ Programs/_testembed test_repeated_init_exec 'import ssl'
--- Loop #1 ---
--- Loop #2 ---
_testembed: Python/getargs.c:2052: parser_init: Assertion `parser->kwtuple != NULL' failed.
Aborted (core dumped)

The 3.12 output implies a problem related to argument clinic and the kwarg names tuple that gets cached.

CPython versions tested on:

CPython main branch

Operating systems tested on:

No response

Output from running 'python -VV' on the command line:

No response

Linked PRs

@ericsnowcurrently ericsnowcurrently added type-crash A hard crash of the interpreter, possibly with a core dump 3.12 bugs and security fixes 3.13 bugs and security fixes 3.14 new features, bugs and security fixes labels Jul 26, 2024
@neonene
Copy link
Contributor

neonene commented Jul 29, 2024

The following command crashes as well:

_testembed test_repeated_init_exec "import _ssl; _ssl.txt2obj(txt='1.3')"

Related clinic code (actually unchanged since Python 3.5):

static PyObject *
_ssl_txt2obj(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
{
    ...
    static const char * const _keywords[] = {"txt", "name", NULL};
    static _PyArg_Parser _parser = {
        .keywords = _keywords,
        .fname = "txt2obj",
        .kwtuple = KWTUPLE,  // KWTUPLE: NULL
    };
    ...
    args = _PyArg_UnpackKeywords(..., &_parser, ...);  // segfault

Python/getargs.c:

PyObject * const *
_PyArg_UnpackKeywords(..., struct _PyArg_Parser *parser, ...)
{
    PyObject *kwtuple;
    ...
    if (parser_init(parser) < 0) {  // set `parser->kwtuple` only once
        return NULL;
    }
    kwtuple = parser->kwtuple;      // get NULL after restarting interp
    ...
    maxargs = posonly + (int)PyTuple_GET_SIZE(kwtuple);  // segfault

Currently, _PyArg_Fini() clears parser->kwtuple only:

void
_PyArg_Fini(void)
{
    struct _PyArg_Parser *tmp, *s = _PyRuntime.getargs.static_parsers;
    while (s) {
        tmp = s->next;
        s->next = NULL;
        parser_clear(s);
        s = tmp;
    }
    _PyRuntime.getargs.static_parsers = NULL;
}

// 3.13+
static void
parser_clear(struct _PyArg_Parser *parser)
{
    if (parser->is_kwtuple_owned) {
        Py_CLEAR(parser->kwtuple);
    }
}

// 3.12
static void
parser_clear(struct _PyArg_Parser *parser)
{
    if (parser->initialized == 1) {
        Py_CLEAR(parser->kwtuple);
    }
}

IIUC, clearing parser->once.v or parser->initialized there will allow parser_init() to run again, which would work around the issue.

@ericsnowcurrently
Copy link
Member Author

Good sleuthing!

kumaraditya303 pushed a commit that referenced this issue Aug 2, 2024
)

* Fix crash when importing ssl after re-initialization
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Aug 2, 2024
…pythonGH-122481)

* Fix crash when importing ssl after re-initialization
(cherry picked from commit 9fc1c99)

Co-authored-by: neonene <53406459+neonene@users.noreply.github.com>
kumaraditya303 pushed a commit that referenced this issue Aug 2, 2024
GH-122481) (#122495)

Fix crash when importing ssl after re-initialization

The current METH_FASTCALL|METH_KEYWORDS functions in a non-builtin module can cause segfaults after restarting the main interpreter, invoking _PyArg_UnpackKeywords() with an insufficiently cleared _PyArg_Parser struct.

This patch fixes the invalidation of the static argument parsers.
kumaraditya303 pushed a commit that referenced this issue Aug 2, 2024
GH-122481) (#122614)

gh-122334: Fix crash when importing ssl after re-initialization (GH-122481)

* Fix crash when importing ssl after re-initialization
(cherry picked from commit 9fc1c99)

Co-authored-by: neonene <53406459+neonene@users.noreply.github.com>
@neonene
Copy link
Contributor

neonene commented Aug 2, 2024

Some buildbots fail the test_embed without building _ssl module.
https://buildbot.python.org/#/builders/1366/builds/1792

encukou pushed a commit that referenced this issue Aug 3, 2024
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Aug 3, 2024
…honGH-122630)

(cherry picked from commit 50b3603)

Co-authored-by: neonene <53406459+neonene@users.noreply.github.com>
Co-authored-by: Wulian233 <1055917385@qq.com>
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Aug 3, 2024
…honGH-122630)

(cherry picked from commit 50b3603)

Co-authored-by: neonene <53406459+neonene@users.noreply.github.com>
Co-authored-by: Wulian233 <1055917385@qq.com>
Yhg1s pushed a commit that referenced this issue Aug 6, 2024
…-122630) (#122648)

gh-122334: Fix test_embed failure when missing _ssl module (GH-122630)
(cherry picked from commit 50b3603)

Co-authored-by: neonene <53406459+neonene@users.noreply.github.com>
Co-authored-by: Wulian233 <1055917385@qq.com>
Yhg1s pushed a commit that referenced this issue Aug 6, 2024
…-122630) (#122647)

gh-122334: Fix test_embed failure when missing _ssl module (GH-122630)
(cherry picked from commit 50b3603)

Co-authored-by: neonene <53406459+neonene@users.noreply.github.com>
Co-authored-by: Wulian233 <1055917385@qq.com>
@neonene
Copy link
Contributor

neonene commented Aug 7, 2024

I think there is nothing left to do here.

@encukou
Copy link
Member

encukou commented Aug 7, 2024

Indeed. Thank you for the fix!

@encukou encukou closed this as completed Aug 7, 2024
brandtbucher pushed a commit to brandtbucher/cpython that referenced this issue Aug 7, 2024
brandtbucher pushed a commit to brandtbucher/cpython that referenced this issue Aug 7, 2024
@diegorusso
Copy link
Contributor

diegorusso commented Aug 20, 2024

This is the same issue of #121087 Thanks for fixing it!

I tested the code on that issue and it is passing. In that case the problem was that the once.v wasn't reset to 0. Is it worth adding that test in the test_embed?

blhsing pushed a commit to blhsing/cpython that referenced this issue Aug 22, 2024
blhsing pushed a commit to blhsing/cpython that referenced this issue Aug 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.12 bugs and security fixes 3.13 bugs and security fixes 3.14 new features, bugs and security fixes type-crash A hard crash of the interpreter, possibly with a core dump
Projects
None yet
Development

No branches or pull requests

4 participants