python / python/cpython

concurrent.interpreters: crash (NULL dereference) when an unpickled AttributeError has a non-string arg

未关闭
#151,862 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

3.14 3.15 3.16 interpreter-core topic-subinterpreters type-bug
主要语言
Python
星标
77.2k
派生
35.9k
PR 合并指标
PR 指标待抓取

描述

Python/crossinterp.c's check_missing___main___attr() passes the result of PyUnicode_AsUTF8() straight to strncmp() without a NULL check:

const char *err = PyUnicode_AsUTF8(msgobj);
// Check if it's a missing __main__ attr.
int cmp = strncmp(err, "module '__main__' has no attribute '", 36);

msgobj is args[0] of an AttributeError raised on the receive side of the cross-interpreter pickle fallback, reached when an object is moved between interpreters through a concurrent.interpreters queue or channel and its unpickling in the receiving interpreter fails.

PyUnicode_AsUTF8() returns NULL (and sets an exception) when args[0] is not a str — e.g. AttributeError(42), AttributeError(b'x'), AttributeError(None) — or is a str containing lone surrogates (AttributeError('\ud800')). When err == NULL, strncmp(NULL, ...) dereferences NULL and the interpreter crashes (SIGSEGV).

Reproduction

Put an object into a concurrent.interpreters queue whose unpickling on the receive side raises an AttributeError with a non-string (or surrogate) first argument, then get() it — the receiving interpreter segfaults instead of raising NotShareableError. A self-contained reproduction is added as a regression test (test_get_unpickle_fails_with_bad_attributeerror_arg in Lib/test/test_interpreters/test_queues.py), exercising args 42, b'x', None, and '\ud800'.

Scope

This is the check_missing___main___attr() NULL dereference reached through the queue/channel receive path. It does not by itself make every cross-interpreter unpickle failure safe — Interpreter.call() has a separate crash on its result-preserve path that I will report independently.

Fix

Add a NULL guard immediately after PyUnicode_AsUTF8, matching the correctly-checked sibling helper _copy_string_obj_raw(): on NULL, clear the exception (the function asserts !PyErr_Occurred() on entry), Py_DECREF(msgobj), and return 0 (not a missing-__main__ attribute).

Affected versions

concurrent.interpreters (PEP 734) is public in 3.14+; this reproduces on main and 3.14.

Linked PR

A PR follows.

Linked PRs
  • gh-151863

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

该 issue 指向 Python/crossinterp.c 和 check_missing___main___attr();将其对 PyUnicode_AsUTF8() 的处理与同级辅助函数 _copy_string_obj_raw() 的处理进行比较。运行 Lib/test/test_interpreters/test_queues.py,尤其是 test_get_unpickle_fails_with_bad_attributeerror_arg,并确认列出的格式错误的 AttributeError 参数会引发 NotShareableError,且不会导致崩溃。一个关联的 PR gh-151863 表明这项工作已经在进行中。

由索引模型根据 Issue 内容生成。

评估

技术栈
c, python
领域
compilers
Issue 类型
缺陷
难度
2/5
预计耗时
1-3 小时
活跃度
停滞
描述清晰度
描述清楚
新手友好度
25/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。