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

Pickler.dump from a badly initialized Pickler segfaults #47914

Closed
devdanzin mannequin opened this issue Aug 24, 2008 · 11 comments
Closed

Pickler.dump from a badly initialized Pickler segfaults #47914

devdanzin mannequin opened this issue Aug 24, 2008 · 11 comments
Assignees
Labels
release-blocker type-crash A hard crash of the interpreter, possibly with a core dump

Comments

@devdanzin
Copy link
Mannequin

devdanzin mannequin commented Aug 24, 2008

BPO 3664
Nosy @warsaw, @jcea, @amauryfa, @tiran, @devdanzin, @avassalotti
Files
  • _pickle.c
  • issue3664_fix.diff
  • 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 = 'https://github.com/avassalotti'
    closed_at = <Date 2008-10-17.20:16:14.183>
    created_at = <Date 2008-08-24.20:26:34.495>
    labels = ['type-crash', 'release-blocker']
    title = 'Pickler.dump from a badly initialized Pickler segfaults'
    updated_at = <Date 2008-10-17.20:16:14.182>
    user = 'https://github.com/devdanzin'

    bugs.python.org fields:

    activity = <Date 2008-10-17.20:16:14.182>
    actor = 'amaury.forgeotdarc'
    assignee = 'alexandre.vassalotti'
    closed = True
    closed_date = <Date 2008-10-17.20:16:14.183>
    closer = 'amaury.forgeotdarc'
    components = []
    creation = <Date 2008-08-24.20:26:34.495>
    creator = 'ajaksu2'
    dependencies = []
    files = ['11704', '11814']
    hgrepos = []
    issue_num = 3664
    keywords = ['patch']
    message_count = 11.0
    messages = ['71860', '71863', '71938', '71942', '74164', '74327', '74888', '74896', '74898', '74902', '74936']
    nosy_count = 6.0
    nosy_names = ['barry', 'jcea', 'amaury.forgeotdarc', 'christian.heimes', 'ajaksu2', 'alexandre.vassalotti']
    pr_nums = []
    priority = 'release blocker'
    resolution = 'fixed'
    stage = None
    status = 'closed'
    superseder = None
    type = 'crash'
    url = 'https://bugs.python.org/issue3664'
    versions = ['Python 3.0']

    @devdanzin
    Copy link
    Mannequin Author

    devdanzin mannequin commented Aug 24, 2008

    This script segfaults:

    import _pickle
    obj = _pickle.Pickler(open("/bin/ls")) #can be open(file) for scripts
    try: obj.__init__('pouet', 87)
    except Exception as err: pass

    obj.dump(0)
    ###

    [Switching to Thread -1210775360 (LWP 19096)]
    0xb79fbf91 in pickler_write (self=0xb7a2fe4c, s=0xbff441a1 "...", n=2)
    at /home/ajaksu/py3k/Modules/_pickle.c:442
    442 memcpy(self->write_buf + self->buf_size, s, n);
    (gdb) backtrace
    #0 0xb79fbf91 in pickler_write (self=0xb7a2fe4c, s=0xbff441a1 "...",
    n=2) at /home/ajaksu/py3k/Modules/_pickle.c:442
    #1 0xb7a00a8c in dump (self=0xb7a2fe4c, obj=0x81fbd78) at
    /home/ajaksu/py3k/Modules/_pickle.c:2288
    #2 0xb7a00bb8 in Pickler_dump (self=0xb7a2fe4c, args=0xb7b30034) at
    /home/ajaksu/py3k/Modules/_pickle.c:2328
    #3 0x081626b1 in PyCFunction_Call (func=0xb796c3ec, arg=0xb7b30034,
    kw=0x0) at Objects/methodobject.c:81
    #4 0x080b378f in call_function (pp_stack=0xbff442e4, oparg=1) at
    Python/ceval.c:3403
    #5 0x080ae8d2 in PyEval_EvalFrameEx (f=0x829bafc, throwflag=0) at
    Python/ceval.c:2205
    #6 0x080b1c24 in PyEval_EvalCodeEx (co=0xb7acf2c8, globals=0xb7a9a8f4,
    locals=0xb7a9a8f4, args=0x0, argcount=0, kws=0x0,
    kwcount=0, defs=0x0, defcount=0, kwdefs=0x0, closure=0x0) at
    Python/ceval.c:2840

    Found using Fusil.

    @devdanzin devdanzin mannequin added the type-crash A hard crash of the interpreter, possibly with a core dump label Aug 24, 2008
    @tiran
    Copy link
    Member

    tiran commented Aug 24, 2008

    pickler_write() has no check for self->write_buf == NULL

    Suggested patch:
    ===================================================================

    --- Modules/_pickle.c   (Revision 66010)
    +++ Modules/_pickle.c   (Arbeitskopie)
    @@ -421,6 +421,10 @@
     {
         PyObject *data, *result;
    
    +    if (self->write_buf == NULL) {
    +        PyErr_SetString(PyExc_SystemError, "Invalid write buffer");
    +        return -1;
    +    }
         if (s == NULL) {
             if (!(self->buf_size))
                 return 0;

    @avassalotti
    Copy link
    Member

    Oh, that's nasty. Recalling __init__ with bad arguments breaks the
    internal invariants as it clears the Pickler's content before parsing
    the arguments. I suspect that Unpickler is vulnerable too.

    Adding a NULL check in pickler_write will only fix this particular
    example. I could probably find another crash example that doesn't use
    pickler_write.

    @avassalotti
    Copy link
    Member

    Unpickler looks safe as Unpickler_load() checks if Unpickler was
    properly initialized. And only Pickler_dump is vulnerable right now (new
    methods, if any, exposed for bpo-3385 will have to take into account
    this vulnerability).

    @avassalotti
    Copy link
    Member

    I will try to find time next weekend to fix this (and other pickle
    blockers).

    @avassalotti
    Copy link
    Member

    Here's the fix. The added check in Pickler_dump should prevent any
    segfaults due to __init__() errors.

    I also added the check proposed by Christian as a safe-guard in case a
    core developer adds a new method that doesn't check if the object was
    properly initialized.

    @warsaw
    Copy link
    Member

    warsaw commented Oct 17, 2008

    Rather than attach a full _pickle.c file, please generate a unified diff
    with just your changes. The patch should include a test for the
    crashing condition. If you can upload that I'll try to accept it for
    rc3. Deferring for now.

    @avassalotti
    Copy link
    Member

    Oops. I must have been quite tired when I submitted that.

    Here's the patch for the fix and the test case.

    @amauryfa
    Copy link
    Member

    The patch is fine.

    @warsaw
    Copy link
    Member

    warsaw commented Oct 17, 2008

    Amaury, please apply the patch and close the issue. Thanks!

    @amauryfa
    Copy link
    Member

    Committed r66963.

    @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
    release-blocker type-crash A hard crash of the interpreter, possibly with a core dump
    Projects
    None yet
    Development

    No branches or pull requests

    5 participants