cpython/Include/internal
Gregory P. Smith cec1e9dfd7
[3.9] gh-95778: CVE-2020-10735: Prevent DoS by very large int() (#96502)
* Correctly pre-check for int-to-str conversion (#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: gh-95778 -->
* Issue: gh-95778
<!-- /gh-issue-number -->

Co-authored-by: Gregory P. Smith [Google LLC] <greg@krypto.org>
Co-authored-by: Christian Heimes <christian@python.org>
Co-authored-by: Mark Dickinson <dickinsm@gmail.com>
2022-09-05 11:21:03 +02:00
..
pegen_interface.h bpo-40334: Make the PyPegen* and PyParser* APIs more consistent (GH-19839) 2020-05-01 18:30:51 +01:00
pycore_abstract.h bpo-40170: Add _PyIndex_Check() internal function (GH-19426) 2020-04-08 02:01:56 +02:00
pycore_accu.h bpo-36635: Change pyport.h for Py_BUILD_CORE_MODULE define (GH-12853) 2019-04-17 23:02:26 +02:00
pycore_atomic.h bpo-38353: Cleanup includes in the internal C API (GH-16548) 2019-10-02 23:51:20 +02:00
pycore_bytes_methods.h bpo-35081: Move bytes_methods.h to the internal C API (GH-18492) 2020-02-12 22:32:34 +01:00
pycore_byteswap.h bpo-41617: Add _Py__has_builtin() macro (GH-23260) (GH-23262) 2020-11-13 16:38:06 +01:00
pycore_call.h bpo-38644: Add _PyObject_Call() (GH-17089) 2019-11-14 13:36:21 +01:00
pycore_ceval.h [3.9] bpo-45806: Fix recovery from stack overflow for 3.9. Again. (GH-29640) 2021-11-19 19:51:50 +01:00
pycore_code.h [3.9] Remove trailing spaces (GH-28710) 2021-10-03 20:04:38 +03:00
pycore_condvar.h bpo-36635: Change pyport.h for Py_BUILD_CORE_MODULE define (GH-12853) 2019-04-17 23:02:26 +02:00
pycore_context.h bpo-38353: Cleanup includes in the internal C API (GH-16548) 2019-10-02 23:51:20 +02:00
pycore_dtoa.h bpo-35081: Move dtoa.h header to the internal C API (GH-18489) 2020-02-12 22:54:42 +01:00
pycore_fileutils.h [3.9] bpo-43667: Fix broken Unicode encoding in non-UTF locales on Solaris (GH-25096) (GH-25847) 2021-05-21 16:59:39 +02:00
pycore_gc.h bpo-40428: Remove PyTuple_ClearFreeList() function (GH-19769) 2020-04-29 02:29:20 +02:00
pycore_getopt.h bpo-36763: Cleanup precmdline in _PyCoreConfig_Read() (GH-13371) 2019-05-17 03:15:12 +02:00
pycore_gil.h bpo-38353: Cleanup includes in the internal C API (GH-16548) 2019-10-02 23:51:20 +02:00
pycore_hamt.h gh-93065: Fix HAMT to iterate correctly over 7-level deep trees (GH-93066) (#93147) 2022-05-24 10:52:49 +02:00
pycore_hashtable.h bpo-40602: Write unit tests for _Py_hashtable_t (GH-20091) 2020-05-14 21:55:47 +02:00
pycore_import.h bpo-40232: Update PyOS_AfterFork_Child() to use _PyThread_at_fork_reinit() (GH-19450) 2020-04-15 01:16:24 +09:00
pycore_initconfig.h [3.9] gh-95778: CVE-2020-10735: Prevent DoS by very large int() (#96502) 2022-09-05 11:21:03 +02:00
pycore_interp.h [3.9] gh-95778: CVE-2020-10735: Prevent DoS by very large int() (#96502) 2022-09-05 11:21:03 +02:00
pycore_long.h [3.9] gh-95778: CVE-2020-10735: Prevent DoS by very large int() (#96502) 2022-09-05 11:21:03 +02:00
pycore_object.h [3.9] bpo-45083: Include the exception class qualname when formatting an exception (GH-28119) (GH-28135) 2021-09-03 18:56:05 +02:00
pycore_pathconfig.h bpo-39372: Clean header files of declared interfaces with no implementations (GH-18037) 2020-01-18 03:14:59 +00:00
pycore_pyerrors.h bpo-40696: Fix a hang that can arise after gen.throw() (GH-20287) 2020-05-22 14:35:22 -07:00
pycore_pyhash.h bpo-36635: Change pyport.h for Py_BUILD_CORE_MODULE define (GH-12853) 2019-04-17 23:02:26 +02:00
pycore_pylifecycle.h bpo-41686: Always create the SIGINT event on Windows (GH-23344) (GH-23347) 2020-11-17 18:58:12 +01:00
pycore_pymem.h bpo-44184: Fix subtype_dealloc() for freed type (GH-26274) 2021-07-15 16:36:51 -07:00
pycore_pystate.h [3.9] bpo-40826: PyOS_InterruptOccurred() requires GIL (GH-20578) (GH-20618) 2020-06-03 20:16:39 +02:00
pycore_runtime.h [3.9] bpo-40514: Remove --with-experimental-isolated-subinterpreters in 3.9 (GH-20228) 2020-05-20 00:27:46 +02:00
pycore_sysmodule.h bpo-38644: Add _PySys_Audit() which takes tstate (GH-19180) 2020-03-26 18:57:32 +01:00
pycore_traceback.h [3.9] Fix typos in the Include directory (GH-28745) (GH-28788) 2021-10-07 06:01:05 -07:00
pycore_tupleobject.h bpo-38353: Cleanup includes in the internal C API (GH-16548) 2019-10-02 23:51:20 +02:00
pycore_warnings.h bpo-39796: Fix _warnings module initialization (GH-18739) 2020-03-02 15:02:18 +01:00