Menu

#700 Segmentation fault when destroying PySecBuffer

v1.0 (example)
open
nobody
None
5
2016-02-27
2015-09-04
Luke Lovett
No

Environment
Windows 7
Visual Studio 2008
Python 2.7.8
kerberos_sspi 0.2
pywin32 219

When returning from the function "authGSSClientUnwrap" in the library "kerberos_sspi": https://pypi.python.org/pypi/kerberos-sspi/0.2, I encounter a segfault coming from ~PySecBuffer().

Reproduction

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/python
import kerberos_sspi

# SERVICE = xxx
# HOST = xxx

def repro():
    result, ctx = kerberos.authGSSClientInit(
        SERVICE + '@' + HOST, gssflags=kerberos.GSS_C_MUTUAL_FLAG)
    kerberos.authGSSClientStep(ctx, '')
    payload = kerberos.authGSSClientResponse(ctx)
    # Create response to intiiate SASL conversation
    response = make_sasl_start_response(payload)
    # Enter loop to catch protocol/library issues
    for _ in range(10):
        result = kerberos.authGSSClientStep(ctx, str(response['payload']))
        payload = kerberos.authGSSClientResponse(ctx) or ''
        response = make_sasl_continue_response(payload)
        if kerberos.AUTH_GSS_COMPLETE == result:
            break
    else:
        raise Exception("auth failed")
    # This causes a segmentation fault:
    kerberos.authGSSClientUnwrap(ctx, str(response['payload']))

You can find the original code that's causing this segmentation fault here: https://github.com/mongodb/mongo-python-driver/blob/master/pymongo/auth.py#L261-L326. Note that this code doesn't currently support using "kerberos_sspi" due to this and another problem. However, it's possible to reproduce this issue by doing a "import kerberos_sspi as kerberos" in lieu of the other kerberos imports in this file.

The source for the kerberos_sspi module is here: https://github.com/may-day/kerberos-sspi/blob/kerberos-sspi-0.2/kerberos_sspi.py

Thank you so much for looking into this. Please let me know if I can provide any more detail.

Discussion

  • Luke Lovett

    Luke Lovett - 2015-09-04

    Made a couple mistakes above:
    - import should be "import kerberos_sspi as kerberos"
    - "initiiate" should read "initiate"

    I can't find the button for "edit issue" if that feature exists on SourceForge.

     
  • james so

    james so - 2016-01-02

    Hi,
    it will be great if this can be fixed, we want to use python and mongo togather in windows desktop.

    Python and mongo db are powerful tool togather and we would love to use them togather.
    James

     
  • Mark Hammond

    Mark Hammond - 2016-01-03

    How can I repro this given just win7 professional? ie, what can I use for "SERVICE" and "HOST" in the repro above. Alternatively, can you get a stack trace from the crash?

     
  • Bernie Hackett

    Bernie Hackett - 2016-02-26

    Hi Mark,

    I think the problem is a mismatch between the way PySecBuffer works and the expectations of SSPI's DecryptMessage function. The docs for DecryptMessage (Kerberos) are here:

    https://msdn.microsoft.com/en-us/library/windows/desktop/aa375215(v=vs.85).aspx

    Note the docstring for pMessage says "The encrypted message is decrypted in place, overwriting the original contents of its buffer."

    The docs for SSPI / GSSAPI compatibility are here:

    https://msdn.microsoft.com/en-us/library/windows/desktop/aa380496(v=vs.85).aspx

    The example for calling DecryptMessage uses 2 SecBuffers. The pvBuffer pointer for the input SecBuffer is set to the input message, the pvBuffer pointer for the output SecBuffer is set to NULL (note this doesn't even seem possible with PySecBuffer). I beleive what DecryptMessage does is decrypt the input buffer in place, then set the pvBuffer pointer of the output SecBuffer to the position in the input buffer where the actual message starts.

    kerberos-sspi attempts to implement Microsoft's example here:

    https://github.com/may-day/kerberos-sspi/blob/kerberos-sspi-0.2/kerberos_sspi.py#L255-L261

    If I'm right, the reason for the segfault is that pywin32's SecBuffer frees its internal buffer when it is reclaimed, but since the buffer for both SecBuffers point to the same memory region after the DecryptMessage call we're attempting to free the same memory twice.

    I'm not sure how to solve this in pywin32. I suspect you would need a special SecBuffer type for this application.

     
  • Bernie Hackett

    Bernie Hackett - 2016-02-27

    I wrote a python extension to do Kerberos authentication with SSPI. When I initially implemented GSSUnwrap I was also freeing the output buffer, and my implementation also segfaulted. Removing the free of the output buffer fixed the problem. You can see the implementation here:

    https://github.com/mongodb-labs/winkerberos/blob/master/src/kerberos_sspi.c#L254