[SERVER-9960] access violation on getCertificateName Created: 18/Jun/13  Updated: 11/Jul/16  Resolved: 19/Jun/13

Status: Closed
Project: Core Server
Component/s: Security
Affects Version/s: 2.5.0
Fix Version/s: 2.5.1

Type: Bug Priority: Major - P3
Reporter: Eric Milkie Assignee: Andreas Nilsson
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Windows


Issue Links:
Related
related to SERVER-7961 Use x.509 certificates for authentica... Closed
Operating System: ALL
Participants:

 Description   

It would appear that calling free() on the pointer returned by X509_NAME_online was not the correct thing to do. In debug mode, the Windows heap checker flags it as an invalid pointer to call free() on (there is a popup stating so). I then clicked on the button to dismiss the dialog and trigger a stack trace:

D:\slave\Windows_64bit_2008R2+_SSL_Nightly\mongo>mongod.exe --port 27999 --setParameter enableTestCommands=1 --httpinterface --sslOnNormalPorts --sslPEMKeyFile jstests/libs/server.pem --sslCAFile jste
sts/libs/ca.pem --sslWeakCertificateValidation
Tue Jun 18 15:21:09.517 *** unhandled exception 0x80000003 at 0x0000000140FF72AD, terminating
Tue Jun 18 15:21:09.518 *** stack trace for unhandled exception:
Tue Jun 18 15:21:10.391 mongod.exe    f:\dd\vctools\crt_bld\self_64_amd64\crt\src\dbgheap.c(1322)          _free_dbg_nolock+0x19d
Tue Jun 18 15:21:10.392 mongod.exe    f:\dd\vctools\crt_bld\self_64_amd64\crt\src\dbgheap.c(1265)          _free_dbg+0x26
Tue Jun 18 15:21:10.393 mongod.exe    f:\dd\vctools\crt_bld\self_64_amd64\crt\src\dbgfree.c(50)            free+0x18
Tue Jun 18 15:21:10.394 mongod.exe    ...\src\mongo\util\net\ssl_manager.cpp(263)                          mongo::getCertificateSubjectName+0x9a
Tue Jun 18 15:21:10.394 mongod.exe    ...\src\mongo\util\net\ssl_manager.cpp(431)                          mongo::`anonymous namespace'::SSLManager::_setupPEM+0x86b
Tue Jun 18 15:21:10.395 mongod.exe    ...\src\mongo\util\net\ssl_manager.cpp(310)                          mongo::`anonymous namespace'::SSLManager::SSLManager+0x343
Tue Jun 18 15:21:10.396 mongod.exe    ...\src\mongo\util\net\ssl_manager.cpp(243)                          mongo::_mongoInitializerFunction_SSLManager+0xe4
Tue Jun 18 15:21:10.397 mongod.exe    ...\src\third_party\boost\boost\function\function_template.hpp(95)   boost::detail::function::function_invoker1<mongo::Status (__cdecl*)(mongo::InitializerContext
 * __ptr64),mongo::Status,mongo::InitializerContext * __ptr64>::invoke+0x54
Tue Jun 18 15:21:10.398 mongod.exe    ...\src\third_party\boost\boost\function\function_template.hpp(760)  boost::function1<mongo::Status,mongo::InitializerContext * __ptr64>::operator()+0xb8
Tue Jun 18 15:21:10.399 mongod.exe    ...\src\mongo\base\initializer.cpp(45)                               mongo::Initializer::execute+0x2da
Tue Jun 18 15:21:10.400 mongod.exe    ...\src\mongo\base\initializer.cpp(58)                               mongo::runGlobalInitializers+0x4c
Tue Jun 18 15:21:10.401 mongod.exe    ...\src\mongo\base\initializer.cpp(77)                               mongo::runGlobalInitializers+0x25a
Tue Jun 18 15:21:10.402 mongod.exe    ...\src\mongo\base\initializer.cpp(81)                               mongo::runGlobalInitializersOrDie+0x47
Tue Jun 18 15:21:10.403 mongod.exe    ...\src\mongo\db\db.cpp(1304)                                        mongoDbMain+0x1bb
Tue Jun 18 15:21:10.404 mongod.exe    ...\src\mongo\db\db.cpp(742)                                         wmain+0x78
Tue Jun 18 15:21:10.405 mongod.exe    f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c(278)              __tmainCRTStartup+0xe2
Tue Jun 18 15:21:10.405 mongod.exe    f:\dd\vctools\crt_bld\self_64_amd64\crt\src\crt0.c(189)              wmainCRTStartup+0xe
Tue Jun 18 15:21:10.406 kernel32.dll                                                                       BaseThreadInitThunk+0xd
Tue Jun 18 15:21:10.407 writing minidump diagnostic file mongo.dmp
Tue Jun 18 15:21:10.559 *** immediate exit due to unhandled exception

I expect Valgrind Memcheck might show a similar issue.



 Comments   
Comment by auto [ 19/Jun/13 ]

Author:

{u'username': u'agralius', u'name': u'Andreas Nilsson', u'email': u'andreas.nilsson@10gen.com'}

Message: SERVER-9960 Replace X509_NAME_oneline with X509_NAME_print_ex
Branch: master
https://github.com/mongodb/mongo/commit/260befcae73d6f9a17d958417e75a9b7bc4a89a1

Comment by Andreas Nilsson [ 19/Jun/13 ]

Given that X509_NAME_oneline is deprecated and we want to use RFC2253 format anyway I rewrote getCertificateSubjectName to use X509_NAME_print_ex instead. http://codereview.10gen.com/11024035/

Comment by Eric Milkie [ 19/Jun/13 ]

I looked at the code now too. It's not actually that useful; it just allocates a buffer of hardcoded size 200 if you don't pass it one yourself, and then it reallocs sometimes. We'd be better off just passing our own large buffer in.

The 'b' struct is allocated if you don't pass your own buffer, so the function's author has tried to make sure to deallocate the BUF_MEM at all function exit points (not an elegant job when you're in C). Basically the OPENSSL_free() is the opposite of the BUF_MEM_new(). The returned buffer was allocated via BUF_MEM_grow() and needs to be freed by the caller.

Comment by Andreas Nilsson [ 19/Jun/13 ]

Seems other people have had the same issue:
http://stackoverflow.com/questions/15175917/free-string-returned-by-x509-name-oneline

According to docs X509_NAME_oneline allocates a pointer which should be freed and this is also how OpenSSL uses the function itself when looking.

However the implementation of X509_NAME_oneline ends with the lines below. To me it looks like the entire b-struct is freed on some occasions in which case the pointer p looks invalid to me.

if (b != NULL) {
 p=b->data;
 OPENSSL_free(b);
}
else ...
return(p);

b is a buf_mem_st struct defined as

struct buf_mem_st {   
 size_t length;  /* current number of bytes */
 char *data;
 size_t max; /* size of buffer */
};

Comment by Tad Marshall [ 18/Jun/13 ]

I see. Maybe we should try to get that code running earlier so you get stack traces on SSL initialization problems. I think we can set up dependencies such that the platform_init code runs before other initializers. I see that we were already in runGlobalInitializers() and we did get a stack trace from the breakpoint exception, but that gets set up in setupSignalHandlers(), which is called very early in mongoDbMain().

Comment by Eric Milkie [ 18/Jun/13 ]

I ran the debug version by hand (we have no debug buildslave running the Windows SSL build and the SSL test suite).
The release version was simply exiting with a status code, but not printing a stack trace. This was, I believe, due to the fact that the crash happens as code that is run before we install the handler that prints stack traces, unfortunately. I would have run the build using WinDbg but it wasn't installed on the builder, so recompiling in debug mode seemed like the next best thing.

Comment by Tad Marshall [ 18/Jun/13 ]

milkie Are we missing code to turn the popup into a logged exception? I.E. is the code in util/platform_init.cpp not catching this case?

The unhandled exception is a breakpoint exception. Is this Buildbot slave running a debug version?

Is the problem that this build slave doesn't have Dont_Show_UI set in the registry? Is that why there was a popup you had to click on?

Generated at Thu Feb 08 03:21:55 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.