[patch] fix get_option() crash, make more OPT_X_SASL_* info available.

Tom McLaughlin tmclaugh at sdf.lonestar.org
Mon Aug 14 17:17:14 CEST 2006


Hi, the attached patch is to fix a crash I found with py-ldap when using
get_option() and to allow getting more OPT_X_SASL_* information with
get_option().

1) The second to last hunk fixes a crash when using get_option() and the
constant returns a NULL.  I can repeat this crash on FreeBSD with python
2.4.3 / py-ldap 2.2.0 / openldap 2.3.24 and on CentOS with python 2.3.4 /
py-ldap 2.0.1 / openldap 2.2.13.

To recreate: (without TLS_CERT defined in ldap.conf || ~/.ldaprc)
>>> ldap.get_option(ldap.OPT_X_TLS_CERTFILE)

Result:
Segfault

Backtrace:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x811f000 (LWP 100124)]
0x0807779a in PyString_FromString (str=0x0)
    at /usr/ports/lang/python/work/Python-2.4.3/Objects/stringobject.c:106
106             size = strlen(str);
(gdb) bt full
#0  0x0807779a in PyString_FromString (str=0x0)
    at /usr/ports/lang/python/work/Python-2.4.3/Objects/stringobject.c:106
        size = 0
        op = (PyStringObject *) 0x2838f448
#1  0x2838d68b in LDAP_get_option (self=0x0, option=0) at
Modules/options.c:237
        res = 0
        intval = 673302330
        tv = {tv_sec = 0, tv_usec = 135372032}
        apiinfo = {ldapai_info_version = 0, ldapai_api_version = 0,
  ldapai_protocol_version = 0, ldapai_extensions = 0x2838f448,
  ldapai_vendor_name = 0x81b0acc "\002", ldapai_vendor_version = 136047500}
        lcs = (LDAPControl **) 0x2821cdca
        lc = (LDAPControl *) 0x0
        strval = 0x0
        extensions = (PyObject *) 0xbfbfe3c8
        v = (PyObject *) 0x811f048
        tup = (PyObject *) 0x0
        i = 0
        num_extensions = 0
        num_controls = 0
        ld = (LDAP *) 0x0
#2  0x2838c298 in l_ldap_get_option (self=0x0, args=0x81b45ec)
    at Modules/functions.c:117
        option = 24580
#3  0x0805a7dc in PyObject_Call (func=0xffffffff, arg=0x81b45ec,
kw=0x825302c)
    at /usr/ports/lang/python/work/Python-2.4.3/Objects/abstract.c:1795
        result = (PyObject *) 0x81b45ec
        call = 0
#4  0x0809d8ee in PyEval_EvalFrame (f=0x8168e0c)
    at /usr/ports/lang/python/work/Python-2.4.3/Python/ceval.c:3843
        s = (Py_UNICODE *) 0x81beb8c
        len = 135989964
        stack_pointer = (PyObject **) 0x8168f78
        next_instr = (unsigned char *) 0x82290a2 "}\004"
        opcode = -1
        oparg = 135989964
        why = WHY_NOT
        err = 0
        x = (PyObject *) 0x825302c
        v = (PyObject *) 0x81b45ec
        w = (PyObject *) 0x81b4f80
        u = (PyObject *) 0x81beb8c
        t = (PyObject *) 0x81b0acc
        stream = (PyObject *) 0x0
        fastlocals = (PyObject **) 0x8168f58
        freevars = (PyObject **) 0x8168f6c
        retval = (PyObject *) 0x0
        tstate = (PyThreadState *) 0x8117800
        co = (PyCodeObject *) 0x81b9860
        instr_ub = -1
        instr_lb = 0
        instr_prev = -1
        first_instr = (unsigned char *) 0x8229014 "t"
        names = (PyObject *) 0x812dabc
        consts = (PyObject *) 0x816589c
#5  0x0809ff28 in PyEval_EvalCodeEx (co=0x81b9860, globals=0x0, locals=0x0,
    args=0x81b9860, argcount=2, kws=0x8186968, kwcount=0, defs=0x0,
    defcount=0, closure=0x0)
    at /usr/ports/lang/python/work/Python-2.4.3/Python/ceval.c:2739
        tmp = (PyObject *) 0xffffffff
        f = (PyFrameObject *) 0x8168e0c
        retval = (PyObject *) 0x0
        fastlocals = (PyObject **) 0x8168f58
        freevars = (PyObject **) 0x8168f6c
        tstate = (PyThreadState *) 0x8117800
        x = (PyObject *) 0x0
        u = (PyObject *) 0x81b0acc
#6  0x0809e535 in PyEval_EvalFrame (f=0x818680c)
    at /usr/ports/lang/python/work/Python-2.4.3/Python/ceval.c:3658
        a = 0
        b = 0
        res = 0
        stack_pointer = (PyObject **) 0x8186968
        next_instr = (unsigned char *) 0x81cbc23 "S"
        opcode = -1
        oparg = 136135372
        why = WHY_NOT
        err = 0
        x = (PyObject *) 0x821b2d4
        v = (PyObject *) 0x81cc9bc
        w = (PyObject *) 0x81b5c00
        u = (PyObject *) 0x2
        t = (PyObject *) 0x81d42cc
        stream = (PyObject *) 0x0
        fastlocals = (PyObject **) 0x8186958
        freevars = (PyObject **) 0x818695c
        retval = (PyObject *) 0x0
        tstate = (PyThreadState *) 0x8117800
        co = (PyCodeObject *) 0x81c4260
        instr_ub = -1
        instr_lb = 0
        instr_prev = -1
        first_instr = (unsigned char *) 0x81cbc14 "t"
        names = (PyObject *) 0x81c38ec
        consts = (PyObject *) 0x81cafcc
#7  0x0809f6fd in PyEval_EvalFrame (f=0x816ec0c)
    at /usr/ports/lang/python/work/Python-2.4.3/Python/ceval.c:3648
        retval = (PyObject *) 0xffffffec
        fastlocals = (PyObject **) 0x8186958
        i = 1
        f = (PyFrameObject *) 0x818680c
        tstate = (PyThreadState *) 0x8117800
        stack = (PyObject **) 0x0
        stack_pointer = (PyObject **) 0x816ed60
        next_instr = (unsigned char *) 0x81c7763 "Fd"
        opcode = -1
        oparg = 136651076
        why = WHY_NOT
        err = 0
        x = (PyObject *) 0x821b2d4
        v = (PyObject *) 0x818680c
        w = (PyObject *) 0x81acfb0
        u = (PyObject *) 0x8186958
        t = (PyObject *) 0x8252144
        stream = (PyObject *) 0x0
        fastlocals = (PyObject **) 0x816ed58
        freevars = (PyObject **) 0x816ed58
        retval = (PyObject *) 0x0
        tstate = (PyThreadState *) 0x8117800
        co = (PyCodeObject *) 0x81ae5e0
        instr_ub = -1
        instr_lb = 0
        instr_prev = -1
        first_instr = (unsigned char *) 0x81c7754 "e"
        names = (PyObject *) 0x81bc7fc
        consts = (PyObject *) 0x814c6ac
#8  0x0809ff28 in PyEval_EvalCodeEx (co=0x81ae5e0, globals=0x0, locals=0x0,
    args=0x81ae5e0, argcount=0, kws=0x0, kwcount=0, defs=0x0, defcount=0,
    closure=0x0)
    at /usr/ports/lang/python/work/Python-2.4.3/Python/ceval.c:2739
        tmp = (PyObject *) 0xffffffff
        f = (PyFrameObject *) 0x816ec0c
        retval = (PyObject *) 0x0
        fastlocals = (PyObject **) 0x816ed58
        freevars = (PyObject **) 0x816ed58
        tstate = (PyThreadState *) 0x8117800
        x = (PyObject *) 0x0
        u = (PyObject *) 0x0
#9  0x080a00c2 in PyEval_EvalCode (co=0x81ae5e0, globals=0x813e824,
    locals=0x813e824)
    at /usr/ports/lang/python/work/Python-2.4.3/Python/ceval.c:487
No locals.
#10 0x080b79de in run_node (n=0x81265a8, filename=0x0, globals=0x813e824,
    locals=0x813e824, flags=0xbfbfeb18)
    at /usr/ports/lang/python/work/Python-2.4.3/Python/pythonrun.c:1265
        co = (PyCodeObject *) 0x81ae5e0
        v = (PyObject *) 0x81265a8
#11 0x080b8be9 in PyRun_InteractiveOneFlags (fp=0x282faac0,
    filename=0x80d9b7c "<stdin>", flags=0xbfbfeb18)
    at /usr/ports/lang/python/work/Python-2.4.3/Python/pythonrun.c:762
        m = (PyObject *) 0x0
        d = (PyObject *) 0x0
        v = (PyObject *) 0x81b4a20
        w = (PyObject *) 0x81b4d60
        n = (node *) 0x81265a8
        err = {error = 16, filename = 0x80d9b7c "<stdin>", lineno = 0,
  offset = 0, text = 0x0, token = -1, expected = -1}
        ps1 = 0x81b4a34 ">>> "
        ps2 = 0x81265a8 "8f\022\bP\217\021\b"
#12 0x080b8d27 in PyRun_InteractiveLoopFlags (fp=0x282faac0,
    filename=0x80d9b7c "<stdin>", flags=0xbfbfeb18)
    at /usr/ports/lang/python/work/Python-2.4.3/Python/pythonrun.c:695
        v = (PyObject *) 0x81b4d60
        ret = 0
        local_flags = {cf_flags = 135422044}
#13 0x080b9235 in PyRun_AnyFileExFlags (fp=0x282faac0,
    filename=0x80d9b7c "<stdin>", closeit=0, flags=0xbfbfeb18)
    at /usr/ports/lang/python/work/Python-2.4.3/Python/pythonrun.c:658
        err = 135109500
#14 0x08055a41 in Py_Main (argc=0, argv=0xbfbfec48)
    at /usr/ports/lang/python/work/Python-2.4.3/Modules/main.c:493
        v = (PyObject *) 0x0
        c = 0
        sts = 0
        command = 0x0
        filename = 0x0
        module = 0x0
        fp = (FILE *) 0x282faac0
        p = 0x0
        inspect = 0
        unbuffered = 0
        skipfirstline = 0
        stdin_is_interactive = 1
        help = 0
        version = 0
        saw_inspect_flag = 0
        saw_unbuffered_flag = 0
        cf = {cf_flags = 0}
#15 0x0805504d in main (argc=1, argv=0xbfbfec48)
    at /usr/ports/lang/python/work/Python-2.4.3/Modules/python.c:23



2) I wanted to be able to get a user's SASL_MECH, SASL_AUTHCID, and
SASL_AUTHZID but that information wasn't available through py-ldap...  So
I made it available. :)  Other than adding more SASL constants to
Modules/options.c, I made LDAP_OPT_X_SASL_SECPROPS return Py_None with
LDAP_get_option() because according to ldap.h it is read only.  Trying to
get ldap.OPT_X_SASL_SECPROPS was returning ldap.SERVER_DOWN for me before
even though I had SASL_SECPROPS defined.

Please let me know if there are any questions or comments.  I don't
actually know C...  I just kinda figured out the changes.  Thanks.

tom

-- 
| tmclaugh at sdf.lonestar.org             tmclaugh at FreeBSD.org |
| FreeBSD                                   http://www.FreeBSD.org |
| BSD#                    http://www.mono-project.com/Mono:FreeBSD |





More information about the python-ldap mailing list