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

[3.8] gh-95778: CVE-2020-10735: Prevent DoS by very large int() #96503

Merged
merged 17 commits into from Sep 5, 2022

Conversation

gpshead
Copy link
Member

@gpshead gpshead commented Sep 2, 2022

Integer to and from text conversions via CPython's bignum int type is not safe against denial of service attacks due to malicious input. Very large input strings with hundred thousands of digits can consume several CPU seconds.

This PR comes fresh from a pile of work done in our private PSRT security response team repo.

This backports #96499 aka 511ca94

Signed-off-by: Christian Heimes [Red Hat] christian@python.org
Tons-of-polishing-up-by: Gregory P. Smith [Google] greg@krypto.org
Reviews via the private PSRT repo via many others (see the NEWS entry in the PR).

I wrote up a one pager for the release managers.

@tiran tiran added the 🔨 test-with-buildbots Test the PR with the buildbot fleet and report in the status section label Sep 2, 2022
@bedevere-bot
Copy link

bedevere-bot commented Sep 2, 2022

🤖 New build scheduled with the buildbot fleet by @tiran for commit 0504ecb 🤖

If you want to schedule another build, you need to add the "🔨 test-with-buildbots" label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test the PR with the buildbot fleet and report in the status section label Sep 2, 2022
@gpshead gpshead marked this pull request as ready for review Sep 2, 2022
@gpshead gpshead requested a review from rhettinger as a code owner Sep 2, 2022
@gpshead gpshead removed their assignment Sep 2, 2022
@gpshead
Copy link
Member Author

gpshead commented Sep 4, 2022

wait for #96537 to be integrated into this PR before merging, i'll remove the do-not-merge label then.

gpshead and others added 5 commits Sep 4, 2022
Per mdickinson@'s comment on the main branch PR.
…#96537)

Converting a large enough `int` to a decimal string raises `ValueError` as expected. However, the raise comes _after_ the quadratic-time base-conversion algorithm has run to completion. For effective DOS prevention, we need some kind of check before entering the quadratic-time loop. Oops! =)

The quick fix: essentially we catch _most_ values that exceed the threshold up front. Those that slip through will still be on the small side (read: sufficiently fast), and will get caught by the existing check so that the limit remains exact.

The justification for the current check. The C code check is:
```c
max_str_digits / (3 * PyLong_SHIFT) <= (size_a - 11) / 10
```

In GitHub markdown math-speak, writing $M$ for `max_str_digits`, $L$ for `PyLong_SHIFT` and $s$ for `size_a`, that check is:
$$\left\lfloor\frac{M}{3L}\right\rfloor \le \left\lfloor\frac{s - 11}{10}\right\rfloor$$

From this it follows that
$$\frac{M}{3L} < \frac{s-1}{10}$$
hence that
$$\frac{L(s-1)}{M} > \frac{10}{3} > \log_2(10).$$
So
$$2^{L(s-1)} > 10^M.$$
But our input integer $a$ satisfies $|a| \ge 2^{L(s-1)}$, so $|a|$ is larger than $10^M$. This shows that we don't accidentally capture anything _below_ the intended limit in the check.

<!-- gh-issue-number: pythongh-95778 -->
* Issue: pythongh-95778
<!-- /gh-issue-number -->

Co-authored-by: Gregory P. Smith [Google LLC] <greg@krypto.org>
@gpshead gpshead added the 🔨 test-with-buildbots Test the PR with the buildbot fleet and report in the status section label Sep 4, 2022
@bedevere-bot
Copy link

bedevere-bot commented Sep 4, 2022

🤖 New build scheduled with the buildbot fleet by @gpshead for commit c9212d5 🤖

If you want to schedule another build, you need to add the "🔨 test-with-buildbots" label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test the PR with the buildbot fleet and report in the status section label Sep 4, 2022
@ambv
Copy link
Contributor

ambv commented Sep 5, 2022

@tiran can wasm32 failures be ignored here? This is a 3.8 backport and that version is not supported on WASM?

Those fail to build with errors like Invalid configuration wasm32-unknown-emscripten': system emscripten' not recognized , configure: error: cross build not supported for wasm32-unknown-emscripten, and configure: WARNING: unrecognized options: --with-emscripten-target, --enable-wasm-dynamic-linking, --disable-wasm-pthreads.

@ambv
Copy link
Contributor

ambv commented Sep 5, 2022

Unfortunately, there are legitimate failures here.

Arch ASAN Debug https://buildbot.python.org/all/#/builders/586/builds/778:

0:24:11 load avg: 1.56 Re-running test_crypt in verbose mode
Fatal Python error: Segmentation fault

Arch ASAN https://buildbot.python.org/all/#/builders/581/builds/779:

==1967496==ERROR: AddressSanitizer: heap-use-after-free on address 0x60c000459a62 at pc 0x55c4e355a2eb bp 0x7ffd1eb1aec0 sp 0x7ffd1eb1aeb0

Arch USAN https://buildbot.python.org/all/#/builders/720/builds/676:

/buildbot/buildarea/pull_request.pablogsal-arch-x86_64.clang-ubsan/build/Modules/_sha3/kcp/KeccakP-1600-opt64.c:467:9: runtime error: load of misaligned address 0x555beeca9b27 for type 'UINT64' (aka 'unsigned long'), which requires 8 byte alignment

FreeBSD Shared https://buildbot.python.org/all/#/builders/203/builds/821:

ModuleNotFoundError: No module named '_sysconfigdata_d_freebsd14_x86_64-unknown-freebsd14'

s390x https://buildbot.python.org/all/#/builders/111/builds/784:

  File "/home/dje/cpython-buildarea/pull_request.edelsohn-fedora-z.clang/build/Lib/test/pickletester.py", line 3273 in __getattr__
  File "/home/dje/cpython-buildarea/pull_request.edelsohn-fedora-z.clang/build/Lib/test/pickletester.py", line 3273 in __getattr__
  File "/home/dje/cpython-buildarea/pull_request.edelsohn-fedora-z.clang/build/Lib/test/pickletester.py", line 3273 in __getattr__
  ...
make: *** [Makefile:1173: buildbottest] Segmentation fault (core dumped)

Gentoo with X https://buildbot.python.org/all/#/builders/344/builds/803:

FAIL: test_up_at_top (test.test_gdb.StackNavigationTests)
Verify handling of "py-up" at the top of the stack

At least the ASAN and USAN failures are definitely related to this change, the others might be related indirectly.

@gpshead
Copy link
Member Author

gpshead commented Sep 5, 2022

what makes you think those are related to this change?

Arch ASAN 3.8 both: https://buildbot.python.org/all/#/builders/590 and https://buildbot.python.org/all/#/builders/580 show red for six months on 3.8.

and Arch USAN has not 3.8 bot and history at all.

@gpshead
Copy link
Member Author

gpshead commented Sep 5, 2022

If you want a baseline for those bots on 3.8 with no changes, I ran them via #96586.

@ambv
Copy link
Contributor

ambv commented Sep 5, 2022

We looked into this. 3.7 and 3.8 are typically not running address and undefined behavior sanitizers on buildbots. The label-driven trigger on PRs is overly broad and runs configurations that aren't used by us for the oldest branches in regular testing. At least 3.8 fails ASAN and UBSAN without #96503 applied as well. I'm landing this.

@ambv ambv merged commit b5e331f into python:3.8 Sep 5, 2022
70 of 80 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants