Segmentation fault when destroying PySecBuffer
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
#!/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.
Reported by: llvtt
Original Ticket: pywin32/bugs/700
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.
Original comment by: llvtt
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
Original comment by: ecanneworder
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?
Original comment by: mhammond
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.
Original comment by: behackett
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
Original comment by: behackett