Repository navigation
Reject float format precision near INT_MAX #158446
Description
Bug report
(edit: description added now that the fix has been released)
Formatting a float with 'f' and a precision just below INT_MAX writes up to ~280 value-chosen digit bytes past a 28-byte buffer in dtoa.c. The only precondition is untrusted control of a float precision, %-template or format spec -- inputs applications commonly accept because %-formatting is assumed inert. The demonstrated result is a crash, but the byte-exact overflow length permits partial pointer overwrites into interpreter state, so we would not assume it stops there. The fix is a small precision bound check in PyOS_double_to_string() raising ValueError, as the format parsers already do above INT_MAX.
Workarounds
applications running on unpatched Pythons can work around this by sanitizing format strings. But doing so correctly without leaving gaps is hard. I'm not sure this list is actually exhaustive or accurate enough -gpshead:
- If users choose a precision / "decimal places" value, bound it before it reaches formatting (
p = min(int(p), 1000)or reject). The dangerous band starts atINT_MAX - 309; nothing legitimate needs more than a few hundred. - If users (or translators, theme/report authors, etc.) supply %-style templates, or standalone format specs (
format(x, spec),f'{x:{spec}}'), that are applied to floats: reject any containing a run of 10 or more decimal digits, and reject*in %-templates. Match with\donstr, not[0-9]: the format-spec parser accepts any Unicode decimal digit (format(1.5, '.214748364\uff17e')is parsed as precisionINT_MAX), while the %-parsers accept ASCII only.re.search(r'\d{10}', template)over the whole string is sufficient for these two cases, and unlike "parse the directives with a regex" guards it is immune to%(key)s/ nested-parenthesis parsing subtleties. - That check is NOT sufficient for user-authored
str.formattemplates: nested replacement fields inside a format spec can assemble the digits from fill characters or arguments ('{0:.{0!s:2>1.0}{0!s:1>1.0}...f}'), so no digit run ever appears in the template. Additionally reject any{inside a format spec, or better, do not accept such templates at all: they can also read attributes of the arguments. Preferstring.Templateor an allow-listed spec grammar. - Running untrusted Python code in-process is out of scope for CPython's security model; use OS/process isolation.
Credit
Discovered by Peter Bailis, in collaboration with Claude and Anthropic Research.
CPython versions tested on:
3.10, 3.15, 3.11, 3.12, CPython main branch, 3.14, 3.13
Operating systems tested on:
No response
Linked PRs
- gh-158446: Reject float format precision near INT_MAX #158474
- [3.15] gh-158446: Reject float format precision near INT_MAX (GH-158474) #158476
- [3.14] gh-158446: Reject float format precision near INT_MAX (GH-158474) #158477
- [3.13] gh-158446: Reject float format precision near INT_MAX (GH-158474) #158478
- [3.12] gh-158446: Reject float format precision near INT_MAX (GH-158474) #158479
- [3.11] gh-158446: Reject float format precision near INT_MAX (GH-158474) #158480
- [3.10] gh-158446: Reject float format precision near INT_MAX (GH-158474) #158482
Metadata
Metadata
Assignees
Labels
Projects
- StatusShow more project fieldsDone
Activity
gh-158446: Reject float format precision near INT_MAX (GH-158474)
pythongh-158446: Fix the new test_format test on 3.12
pythongh-158446: Fix the new test_format test on 3.11
2 remaining items
[3.13] gh-158446: Reject float format precision near INT_MAX (GH-158474…
[3.15] gh-158446: Reject float format precision near INT_MAX (GH-158474…
[3.14] gh-158446: Reject float format precision near INT_MAX (GH-158474…
[-]placeholder for a security issue[/-][+]Use-after-free for server-side deallocated SSLContext with sni_callback[/+][3.12] gh-158446: Reject float format precision near INT_MAX (GH-158474…
[-]Use-after-free for server-side deallocated SSLContext with sni_callback[/-][+]Reject float format precision near INT_MAX[/+][3.10] gh-158446: Reject float format precision near INT_MAX (GH-158474…
[3.11] gh-158446: Reject float format precision near INT_MAX (GH-158474…