[SERVER-7004] db.hostInfo() crashes mongod with: Uncaught std::exception: basic_string::_S_create Created: 10/Sep/12 Updated: 11/Jul/16 Resolved: 18/Sep/12 |
|
| Status: | Closed |
| Project: | Core Server |
| Component/s: | Diagnostics |
| Affects Version/s: | 2.1.2, 2.2.0 |
| Fix Version/s: | 2.2.1, 2.3.0 |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Thomas Rueckstiess | Assignee: | Ben Becker |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Environment: |
Was able to reproduce on Mac OS X 10.7.4 (Lion) and Mac OS X 10.8.1 (Mountain Lion) |
||
| Attachments: |
|
| Operating System: | OS X |
| Participants: |
| Description |
|
Running db.hostInfo() crashes mongod (2.1.2 and 2.2.0) with
Log file says:
Crashed on 3 different machines (2 MBPro, 1 MBAir), tested default port (27017) and custom port (30000), tested binary and compiled on host, replica set and single instance. Was not able to reproduce on two other OS X machines. Logfile (verbose level 5) is attached. |
| Comments |
| Comment by auto [ 18/Sep/12 ] | ||||||||||||||||||||||||||
|
Author: {u'date': u'2012-09-17T11:03:19-07:00', u'email': u'ben.becker@10gen.com', u'name': u'Ben Becker'}Message: | ||||||||||||||||||||||||||
| Comment by auto [ 17/Sep/12 ] | ||||||||||||||||||||||||||
|
Author: {u'date': u'2012-09-17T11:03:19-07:00', u'email': u'ben.becker@10gen.com', u'name': u'Ben Becker'}Message: | ||||||||||||||||||||||||||
| Comment by Ben Becker [ 12/Sep/12 ] | ||||||||||||||||||||||||||
|
Yep, that's the correct approach. Initial version naively assumed truncation was ok. Patch coming as soon as time permits. | ||||||||||||||||||||||||||
| Comment by Thomas Rueckstiess [ 12/Sep/12 ] | ||||||||||||||||||||||||||
|
According to the function manual, a preceding call to
with NULL as oldp will return the required buffer length in the len parameter. The buffer can then be allocated with the right size. Function manual excerpt:
| ||||||||||||||||||||||||||
| Comment by Thomas Rueckstiess [ 11/Sep/12 ] | ||||||||||||||||||||||||||
|
Stack Trace:
| ||||||||||||||||||||||||||
| Comment by Thomas Rueckstiess [ 11/Sep/12 ] | ||||||||||||||||||||||||||
|
Ben, it appears that sysctlbyname() is in fact returning 0 for oldlenp when the buffer is too small. I also caught this exception:
which points to the length passed to the string constructor being < 0. | ||||||||||||||||||||||||||
| Comment by Ben Becker [ 11/Sep/12 ] | ||||||||||||||||||||||||||
|
Hmm, if this is indeed caused by the sysctl value's length, it seems sysctlbyname() doesn't quite function as per the man page, or I'm misunderstanding something. Given the following description:
It seems the len parameter should be set to 256 on encountering ENOMEM, thus no buffer overflow or attempting to read past the end of the buffer. The code currently has a check for an error (less than 0) but continues on error. This should be fixed to return a default string. It's also worth noting that ENOMEM is a positive value. That's all a bit tangential though – the results should just be a truncated string if len is populated with the 'amount of data copied' according to the man page. The exception could also be caused by sysctlbyname() returning a length of zero (due to the size-1 in the string ctor). A check for this should probably be added regardless. @Thomas, would it be possible to start mongod with gdb and post the backtrace to confirm this is the cause of the exception? You may want to run 'catch throw' first to ensure we get the stack trace at the time the exception is thrown, but you may need to continue past a few 'normal' exceptions. Thanks, | ||||||||||||||||||||||||||
| Comment by Thomas Rueckstiess [ 11/Sep/12 ] | ||||||||||||||||||||||||||
|
In src/mongo/util/processinfo_darwin.cpp line 117 a string buffer of length 256 is allocated. The call to
in line 119 returns a string that can potentially be longer than 256 char. On my machine (MacBook Pro Retina Mid 2012, OS X 10.8.1) a call to "sysctl machdep.cpu.features" from the command line returns
which is 257 characters long and thus creates a buffer overflow. On an older MacBook Pro (MacBook Pro Late 2011, OS X 10.8.1), the returned string was only 249 char long, thus the error didn't occur. |