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

failing overflow checks in replace_* #73331

Closed
matejcik mannequin opened this issue Jan 3, 2017 · 22 comments
Closed

failing overflow checks in replace_* #73331

matejcik mannequin opened this issue Jan 3, 2017 · 22 comments
Labels
3.7 (EOL) end of life interpreter-core (Objects, Python, Grammar, and Parser dirs) type-crash A hard crash of the interpreter, possibly with a core dump

Comments

@matejcik
Copy link
Mannequin

matejcik mannequin commented Jan 3, 2017

BPO 29145
Nosy @matejcik, @benjaminp, @vadmium, @serhiy-storchaka, @zhangyangyu
Files
  • replace-overflow-check.patch
  • replace-overflow-check-v2.patch
  • unicode-overflow.patch
  • replace-overflow-check-v3.patch
  • overflow-checks-3x.patch
  • overflow-checks-3x-2.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2017-01-10.03:08:46.022>
    created_at = <Date 2017-01-03.18:36:42.728>
    labels = ['interpreter-core', '3.7', 'type-crash']
    title = 'failing overflow checks in replace_*'
    updated_at = <Date 2017-01-14.07:25:16.080>
    user = 'https://github.com/matejcik'

    bugs.python.org fields:

    activity = <Date 2017-01-14.07:25:16.080>
    actor = 'python-dev'
    assignee = 'none'
    closed = True
    closed_date = <Date 2017-01-10.03:08:46.022>
    closer = 'xiang.zhang'
    components = ['Interpreter Core']
    creation = <Date 2017-01-03.18:36:42.728>
    creator = 'matejcik'
    dependencies = []
    files = ['46141', '46149', '46156', '46158', '46221', '46223']
    hgrepos = []
    issue_num = 29145
    keywords = ['patch']
    message_count = 22.0
    messages = ['284588', '284607', '284638', '284639', '284640', '284648', '284658', '284708', '284721', '284728', '284731', '284734', '284735', '284897', '285017', '285018', '285020', '285022', '285078', '285086', '285087', '285465']
    nosy_count = 6.0
    nosy_names = ['matejcik', 'benjamin.peterson', 'python-dev', 'martin.panter', 'serhiy.storchaka', 'xiang.zhang']
    pr_nums = []
    priority = 'normal'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'crash'
    url = 'https://bugs.python.org/issue29145'
    versions = ['Python 2.7', 'Python 3.5', 'Python 3.6', 'Python 3.7']

    @matejcik
    Copy link
    Mannequin Author

    matejcik mannequin commented Jan 3, 2017

    Related to http://bugs.python.org/issue1621 and http://bugs.python.org/issue27473
    GCC 6 optimizes away broken overflow checks. This leads to segfaults on test_replace_overflow, at least for strings and bytearrays.

    @matejcik matejcik mannequin added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-crash A hard crash of the interpreter, possibly with a core dump labels Jan 3, 2017
    @benjaminp
    Copy link
    Contributor

    Does that mean it no longer respects -fwrapv?

    @matejcik
    Copy link
    Mannequin Author

    matejcik mannequin commented Jan 4, 2017

    It does, but "-fwrapv" is not automatically added when you specify custom OPT flags. I should have clarified that in the original report.

    @zhangyangyu
    Copy link
    Member

    It does, but "-fwrapv" is not automatically added when you specify custom OPT flags.

    Indeed I think this is why the changes in bpo-27473 and bpo-1621 make sense.

    GCC 6 optimizes away broken overflow checks.

    I am sorry but I don't understand this. What do you mean by broken overflow checks? Is if (size > PY_SSIZE_T_MAX - vo.len) broken?

    @matejcik
    Copy link
    Mannequin Author

    matejcik mannequin commented Jan 4, 2017

    No, your changes from bpo-27473 are OK. However functions like replace_interleave and replace_single_character etc. still use the broken code:

    /* use the difference between current and new, hence the "-1" */
    /*   result_len = self_len + count * (to_len-1)  */
    product = count * (to_len-1);
    if (product / (to_len-1) != count) {
        PyErr_SetString(PyExc_OverflowError, "replace bytes is too long");
        return NULL;
    }

    @zhangyangyu
    Copy link
    Member

    Ohh sorry I misunderstand your intention. :-( Attach a patch. :-)

    @serhiy-storchaka
    Copy link
    Member

    It would be better to write the code in the same form as in 3.x. This could help backporting other patches if needed.

    @zhangyangyu
    Copy link
    Member

    It would be better to write the code in the same form as in 3.x. This could help backporting other patches if needed.

    Yes, it is. :-) I only had a fast glance at at 3.x codes and thought they didn't share much. :-( But apparently I was wrong. The new patch backports 3.x code.

    @matejcik
    Copy link
    Mannequin Author

    matejcik mannequin commented Jan 5, 2017

    some instances are present in unicodeobject.c too

    @serhiy-storchaka
    Copy link
    Member

    replace-overflow-check-v2.patch LGTM.

    @zhangyangyu
    Copy link
    Member

    some instances are present in unicodeobject.c too

    Thanks for your notification.

    v3 adds the some changes needed I could find in unicodeobject.c. Nothing in v2 is changed.

    @serhiy-storchaka
    Copy link
    Member

    It seems to me that unicodeobject.c should be changed in 3.x too.

    @zhangyangyu
    Copy link
    Member

    It seems to me that unicodeobject.c should be changed in 3.x too.

    I don't understand. Would you mind tell me which part? The only suspicious part to me is PY_SSIZE_T_MAX >> (rkind - 1). It seems should be PY_SSIZE_T_MAX / rkind.

    And I missed jan's patch so wrote mine. :-( But they are almost the same. :-)

    @serhiy-storchaka
    Copy link
    Member

    The code in PyUnicode_Join() checks on overflow after making an addition.

            sz += PyUnicode_GET_LENGTH(item);
            item_maxchar = PyUnicode_MAX_CHAR_VALUE(item);
            maxchar = Py_MAX(maxchar, item_maxchar);
            if (i != 0)
                sz += seplen;
            if (sz < old_sz || sz > PY_SSIZE_T_MAX) {
                PyErr_SetString(PyExc_OverflowError,
                                "join() result is too long for a Python string");
                goto onError;
            }

    Maybe there are other cases.

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Jan 9, 2017

    New changeset 29e505526bdd by Xiang Zhang in branch '2.7':
    Issue bpo-29145: Fix overflow checks in string, bytearray and unicode.
    https://hg.python.org/cpython/rev/29e505526bdd

    @zhangyangyu
    Copy link
    Member

    I committed the patch to 2.7. The new patch is for 3.x.

    @zhangyangyu zhangyangyu added the 3.7 (EOL) end of life label Jan 9, 2017
    @vadmium
    Copy link
    Member

    vadmium commented Jan 9, 2017

    FTR I thought the consensus was not to backport these fixes unless there was a demonstrated problem: <https://bugs.python.org/issue1621#msg144499\>, though personally, I would be in favour of backporting in many cases.

    Regarding str.join() in unicode.c, see also my unicode.patch in that bug. I included a test case that works on 32-bit platforms, which you may use. (From memory, you probably need to disable -fwrapv and maybe use -ftrapv or the undefined behaviour sanitizer to make the test fail.)

    @zhangyangyu
    Copy link
    Member

    FTR I thought the consensus was not to backport these fixes unless there was a demonstrated problem: <https://bugs.python.org/issue1621#msg144499\>, though personally, I would be in favour of backporting in many cases.

    Sorry not know that. :-( Another benefit of the change is it actually backports the codes from 3.x so it's easy for later maintainence and it doesn't add additional work.

    I included a test case that works on 32-bit platforms, which you may use.

    Thanks. But I don't get such an environment to test so I prefer not to add it now. I adjust my patch according to yours. :-)

    @vadmium
    Copy link
    Member

    vadmium commented Jan 9, 2017

    Both fixes (join and replace) look good to me. However I don’t think it is necessary to change the exception message in 3.5 or 3.6.

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Jan 10, 2017

    New changeset 09b1cdac74de by Xiang Zhang in branch '3.5':
    Issue bpo-29145: Fix overflow checks in str.replace() and str.join().
    https://hg.python.org/cpython/rev/09b1cdac74de

    New changeset d966ccda9f17 by Xiang Zhang in branch '3.6':
    Issue bpo-29145: Merge 3.5.
    https://hg.python.org/cpython/rev/d966ccda9f17

    New changeset f61a0e8ec022 by Xiang Zhang in branch 'default':
    Issue bpo-29145: Merge 3.6.
    https://hg.python.org/cpython/rev/f61a0e8ec022

    @zhangyangyu
    Copy link
    Member

    Thanks you all. :-)

    @python-dev
    Copy link
    Mannequin

    python-dev mannequin commented Jan 14, 2017

    New changeset dd2c7d497878 by Martin Panter in branch '3.5':
    Issues bpo-1621, bpo-29145: Test for str.join() overflow
    https://hg.python.org/cpython/rev/dd2c7d497878

    New changeset 0c6ea411af17 by Martin Panter in branch 'default':
    Issue bpo-29145: Merge test from 3.6
    https://hg.python.org/cpython/rev/0c6ea411af17

    @ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    3.7 (EOL) end of life interpreter-core (Objects, Python, Grammar, and Parser dirs) type-crash A hard crash of the interpreter, possibly with a core dump
    Projects
    None yet
    Development

    No branches or pull requests

    4 participants