classification
Title: Test for integer overflow on Py_ssize_t: explicitly cast to size_t
Type: Stage: resolved
Components: Versions: Python 3.7, Python 3.6, Python 3.5
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: serhiy.storchaka Nosy List: gregory.p.smith, neologix, python-dev, serhiy.storchaka, vstinner
Priority: normal Keywords: patch

Created on 2014-08-15 22:03 by vstinner, last changed 2017-07-11 04:44 by serhiy.storchaka. This issue is now closed.

Files
File name Uploaded Description Edit
test_overflow_ssize_t.patch vstinner, 2014-08-15 22:03 review
overflow2.patch vstinner, 2014-08-15 23:13 review
unicode.patch vstinner, 2014-08-17 22:43
unicode_2.patch serhiy.storchaka, 2014-08-24 10:19 review
issue22207_unicode_3.patch serhiy.storchaka, 2014-09-30 08:29 review
Pull Requests
URL Status Linked Edit
PR 2623 merged serhiy.storchaka, 2017-07-07 18:55
PR 2658 merged serhiy.storchaka, 2017-07-11 03:57
PR 2659 merged serhiy.storchaka, 2017-07-11 04:00
Messages (16)
msg225369 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2014-08-15 22:03
Python contains a lot of tests like this one:

    if (length > PY_SSIZE_T_MAX / 4)
         return PyErr_NoMemory();

where length type is Py_ssize_t.

This test uses signed integers. There is usually a "assert(length > 0);" before.

The issue #22110 enabled more compiler warnings and there are now warnings when the test uses an unsigned number. Example:

   if (size > PY_SSIZE_T_MAX - PyBytesObject_SIZE) ...

where PyBytesObject_SIZE is defined using offsetof() which returns a size_t.

I propose to always cast Py_ssize_t length to size_t to avoid undefined behaviour (I never know if the compiler chooses signed or unsigned at the end) to ensure that the test also fail for negative number. For example, the following test must fail for negative size:

   if ((size_t)size > (size_t)PY_SSIZE_T_MAX - PyBytesObject_SIZE) ...

Attached patch changes bytesobject.c, tupleobject.c and unicodeobject.c (and asdl.c). If the global approach is accepted, more files should be patched.
msg225372 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2014-08-15 23:13
overflow2.patch: more changes for this issue (it doesn't replace my previous patch).
msg225475 - (view) Author: Roundup Robot (python-dev) (Python triager) Date: 2014-08-17 22:41
New changeset 97c70528b604 by Victor Stinner in branch 'default':
Issue #22207: Fix "comparison between signed and unsigned integers" warning in
http://hg.python.org/cpython/rev/97c70528b604
msg225476 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2014-08-17 22:43
I commited the first part.

The remaining part is a long patch for unicodeobject.c.
msg225808 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2014-08-24 10:19
I think there are too many changes. Here is simpler patch which get rid of all warnings in Objects/unicodeobject.c on my computer (gcc 4.6.3, 32-bit Linux).
msg225859 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2014-08-25 01:22
> I think there are too many changes. Here is simpler patch which get rid of all warnings in Objects/unicodeobject.c on my computer (gcc 4.6.3, 32-bit Linux).

The purpose of my patch is not to make the compiler quiet, but to ensure that negative lengths are handled correctly: Python must raise an error if a length is negative.

For example, _PyUnicode_DecodeUnicodeInternal() doesn't check currently if the size is negative. I don't know exactly what happens if you pass a negative size.
msg227868 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2014-09-30 07:43
Gregory just has committed an equivalent of unicode_2.patch in a404bf4db6a6.
msg227869 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2014-09-30 07:52
modify it as you see fit, i hadn't noticed this issue; just the warnings.
msg227870 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2014-09-30 08:12
Yes, these warning annoyed me too. But Victor's patch is purposed to check 
input data of public C API functions.
msg227871 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2014-09-30 08:29
Here is original Victor's patch synchronized with the tip.
msg227873 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2014-09-30 09:43
I have reviewed the patch and found only few checks which looks good to me. Also I found two possible overflows (not fixed by the patch). All other changes looks redundant to me and just churn a code.
msg297116 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2017-06-28 01:29
Ok, let's close the issue in that case ;-)
msg297903 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-07-07 18:57
I extracted the cases that really can happen in PR 2623.
msg298113 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-07-11 03:55
New changeset 64e461be09e23705ecbab43a8b01722186641f71 by Serhiy Storchaka in branch 'master':
bpo-22207: Add checks for possible integer overflows in unicodeobject.c. (#2623)
https://github.com/python/cpython/commit/64e461be09e23705ecbab43a8b01722186641f71
msg298117 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-07-11 04:27
New changeset 82a907560011c7b784badccc78082cef70ea7128 by Serhiy Storchaka in branch '3.6':
[3.6] bpo-22207: Add checks for possible integer overflows in unicodeobject.c. (GH-2623) (#2658)
https://github.com/python/cpython/commit/82a907560011c7b784badccc78082cef70ea7128
msg298119 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-07-11 04:43
New changeset 44eb51e6fcf45f3c2bf21c16e18c4da48a23d2d3 by Serhiy Storchaka in branch '3.5':
[3.5] bpo-22207: Add checks for possible integer overflows in unicodeobject.c. (GH-2623) (#2659)
https://github.com/python/cpython/commit/44eb51e6fcf45f3c2bf21c16e18c4da48a23d2d3
History
Date User Action Args
2017-07-11 04:44:29serhiy.storchakasetstatus: open -> closed
resolution: fixed
stage: resolved
2017-07-11 04:43:38serhiy.storchakasetmessages: + msg298119
2017-07-11 04:27:58serhiy.storchakasetmessages: + msg298117
2017-07-11 04:00:29serhiy.storchakasetpull_requests: + pull_request2724
2017-07-11 03:57:13serhiy.storchakasetpull_requests: + pull_request2723
2017-07-11 03:55:27serhiy.storchakasetmessages: + msg298113
2017-07-07 18:57:19serhiy.storchakasetstatus: closed -> open
versions: + Python 3.6, Python 3.7
messages: + msg297903

assignee: serhiy.storchaka
resolution: fixed -> (no value)
stage: resolved -> (no value)
2017-07-07 18:55:19serhiy.storchakasetpull_requests: + pull_request2689
2017-06-28 01:29:35vstinnersetstatus: open -> closed
resolution: fixed
messages: + msg297116

stage: resolved
2014-09-30 09:43:41serhiy.storchakasetmessages: + msg227873
2014-09-30 08:29:59serhiy.storchakasetfiles: + issue22207_unicode_3.patch

messages: + msg227871
2014-09-30 08:12:15serhiy.storchakasetmessages: + msg227870
2014-09-30 07:52:16gregory.p.smithsetmessages: + msg227869
2014-09-30 07:43:27serhiy.storchakasetnosy: + gregory.p.smith
messages: + msg227868
2014-08-25 01:22:09vstinnersetmessages: + msg225859
2014-08-24 10:19:10serhiy.storchakasetfiles: + unicode_2.patch

messages: + msg225808
2014-08-17 22:43:07vstinnersetfiles: + unicode.patch

messages: + msg225476
2014-08-17 22:41:57python-devsetnosy: + python-dev
messages: + msg225475
2014-08-15 23:13:29vstinnersetfiles: + overflow2.patch

messages: + msg225372
2014-08-15 22:03:19vstinnercreate