Solved, bug in DSObjCWrappers in 64-bit executables make calls fail with -14079
Solved, bug in DSObjCWrappers in 64-bit executables make calls fail with -14079
- Subject: Solved, bug in DSObjCWrappers in 64-bit executables make calls fail with -14079
- From: Sidney San MartÃn <email@hidden>
- Date: Sun, 24 Mar 2013 00:51:33 -0400
I just spent some time debugging a mysterious problem: DSObjCWrappers' -[DSoUser setPassword:] method reliably threw an exception containing the status code -14079 ("Specified buffer format is invalid"). It also affected other methods.
I'm sharing my solution with the list mostly for archive purposes in case someone else runs into the same bug. It turns out that only 64-bit executables are affected, dscl and the like are 32-bit on 10.5 (the final operating system where you should be using DSObjCWrappers ;) ).
There's a bug in -[DSoNode authenticateWithBufferItems:authType:authOnly:]. It (correctly, AFAICT) allocates a buffer with four bytes reserved for the length of each entry but uses a size_t to represent the length to be written into the buffer. size_t is eight bytes on 64-bit machines so the buffer is corrupted.
The fix is to make ulCurrentLength in the above-named method and its brother a uint32_t. Here's a diff against <http://opensource.apple.com/source/DSTools/DSTools-112.1/DSObjCWrappers/DSoNode.m>:
--- a/DSoNode.m 2006-04-05 18:11:40.000000000 -0400
+++ b/DSoNode.m 2013-03-24 00:50:02.000000000 -0400
@@ -468,7 +468,7 @@
authOnly: (BOOL)inAuthOnly
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- size_t ulCurrentLength = 0;
+ uint32_t ulCurrentLength = 0;
DSoBuffer *dbAuth = nil;
DSoBuffer *dbStep = [[DSoBuffer alloc] initWithDir:mDirectory bufferSize:2048] ;
DSoDataNode *dnAuthType = [(DSoDataNode*)[DSoDataNode alloc] initWithDir:mDirectory cString:inAuthType] ;
@@ -523,7 +523,7 @@
responseBufferItems: (NSArray**)outBufferItems
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- size_t ulCurrentLength = 0;
+ uint32_t ulCurrentLength = 0;
DSoBuffer *dbAuth = nil;
DSoBuffer *dbStep = [[DSoBuffer alloc] initWithDir:mDirectory bufferSize:2048] ;
DSoDataNode *dnAuthType = [(DSoDataNode*)[DSoDataNode alloc] initWithDir:mDirectory cString:inAuthType] ;
I patched over it by overloading -[DSoNode authenticateWithBufferItems:authType:authOnly:] with a fixed version in a DSoNode category since that's the only one I use. If anyone thinks I missed the real problem (e.g. Directory Services isn't 64-bit-safe and will break horribly in other ways), lemme know.
Sidney
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden