This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Integer overflow in _json_encode_unicode leads to crash (heap-buffer-overflow)
Type: security Stage: resolved
Components: Extension Modules Versions: Python 3.6, Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: Arfrever, benjamin.peterson, python-dev
Priority: normal Keywords:

Created on 2015-06-27 20:00 by benjamin.peterson, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (2)
msg245891 - (view) Author: Benjamin Peterson (benjamin.peterson) * (Python committer) Date: 2015-06-27 20:00
Reported by Brendon Tiszka on the security list:

# static PyObject *
# escape_unicode(PyObject *pystr)
# {
#     /* Take a PyUnicode pystr and return a new escaped PyUnicode */
#     Py_ssize_t i;
#     Py_ssize_t input_chars;
#     Py_ssize_t output_size;
#     Py_ssize_t chars;
#     PyObject *rval;
#     void *input;
#     int kind;
#     Py_UCS4 maxchar;
# 
#     if (PyUnicode_READY(pystr) == -1)
#         return NULL;
# 
#     maxchar = PyUnicode_MAX_CHAR_VALUE(pystr);
#     input_chars = PyUnicode_GET_LENGTH(pystr);
#     input = PyUnicode_DATA(pystr);
#     kind = PyUnicode_KIND(pystr);
# 
#     /* Compute the output size */
#     for (i = 0, output_size = 2; i < input_chars; i++) {
#         Py_UCS4 c = PyUnicode_READ(kind, input, i);
#         switch (c) {
#         case '\\': case '"': case '\b': case '\f':
#         case '\n': case '\r': case '\t':
#             output_size += 2;
#             break;
#         default:
#             if (c <= 0x1f)
#                 output_size += 6;
#             else
#                 output_size++;
#         }
#     }
#
#     rval = PyUnicode_New(output_size, maxchar);
#
# 1.) if c is <= 0x1f then output_size += 6. There are no overflow checks on this variable.
# 2.) rval buffer is too small to hold results
#
# Crash:
# ------
#
# Program received signal SIGSEGV, Segmentation fault.
# 0xb7a2e9be in escape_unicode (pystr=pystr@entry=0x8cf81018)
#     at /home/pail/cpython/Modules/_json.c:306
# 306	       ENCODE_OUTPUT;
#
# OS info
# --------
#  %./python -V
#  > Python 3.6.0a0
# % uname -a
# Linux Pail0verflow 3.13.0-52-generic #85-Ubuntu SMP Wed Apr 29 16:44:56 UTC 2015 i686 i686 i686 GNU/Linux
#
# ASAN Info (details in other file)
# =================================================================
# ==6512== ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb5c00000 at pc 0xb5f17356 bp 0xbfaa0eb8 sp 0xbfaa0eac
# WRITE of size 1 at 0xb5c00000 thread T0

import json

sp = "\x13"*715827883 #((2**32)/6 + 1)
json.dumps([sp], ensure_ascii=False)
msg245892 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2015-06-27 20:01
New changeset 0540e14c4b64 by Benjamin Peterson in branch '3.5':
prevent integer overflow in escape_unicode (closes #24522)
https://hg.python.org/cpython/rev/0540e14c4b64

New changeset fc799b2edf21 by Benjamin Peterson in branch 'default':
merge 3.5 (#24522)
https://hg.python.org/cpython/rev/fc799b2edf21
History
Date User Action Args
2022-04-11 14:58:18adminsetgithub: 68710
2015-06-28 12:43:16Arfreversetnosy: + Arfrever
2015-06-27 20:01:23python-devsetstatus: open -> closed

nosy: + python-dev
messages: + msg245892

resolution: fixed
stage: resolved
2015-06-27 20:00:12benjamin.petersoncreate