Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot access keychain item after SMJobBless update

Tags:

We have a problem with updating a helper tool with SMJobBless that has been puzzling us for days now.

We are developing an application for which at some point we need to perform administrative tasks (loading/unloading a kext). We are also using the keychain to store account information for our application.

For the administrative tasks, we use a helper tool that is installed using SMJobBless with which we communicate using DO over Mach ports (with NSConnection).

In the helper tool:

// use our bundle id as our service name NSString* name = [[NSBundle mainBundle] bundleIdentifier];  launch_data_t checkinRequest = launch_data_new_string(LAUNCH_KEY_CHECKIN); launch_data_t checkinResponse = launch_msg(checkinRequest); launch_data_t machServicesDict = launch_data_dict_lookup(checkinResponse, LAUNCH_JOBKEY_MACHSERVICES); launch_data_t machPort = launch_data_dict_lookup(machServicesDict, [name UTF8String]);  mach_port_t mp = launch_data_get_machport(machPort);  launch_data_free(checkinResponse); launch_data_free(checkinRequest);  NSMachPort *receivePort = [[NSMachPort alloc] initWithMachPort:mp]; NSConnection *server = [NSConnection connectionWithReceivePort:receivePort sendPort:nil];         

In the app:

NSConnection *conn = [NSConnection connectionWithRegisteredName:HELPER_BUNDLE_IDENTIFIER host:nil];  id proxyServerObject = [conn rootProxy];  if(conn && proxyServerObject) {     return [proxyServerObject someMethod]; } return NO; 

We sign both the application and the helper tool using a codesign certificate from Thawte. So far, everything works like a charm. The helper tool is installed and we can communicate with it using DO; our kext is loaded and unloaded successfully.

The problem starts when we try to update our helper tool. We use the info dictionary of the installed tool and the bundled tool in our app bundle to check whether an update of the tool is required and call SMJobBless again to perform the update.

After the SMJobBless call, the following lines appear in the Console:

6/19/12 10:31:24.000 AM kernel: CODE SIGNING: cs_invalid_page(0x104e17000): p=74362[OURAPP] clearing CS_VALID 6/19/12 10:31:24.000 AM kernel: CODE SIGNING: cs_invalid_page(0x10d0de000): p=74364[OURAPPHELPER] clearing CS_VALID 

After this, the application is unable to read the application password from our keychain item, the function SecKeychainItemCopyContent returns errSecAuthFailed (-25293). However, no error is reported if we manually verify the code signature of our installed helper tool or application bundle using codesign -vvvv PATH_TO_TOOL_OR_BUNDLE. The tool and application are signed outside of the Xcode environment and the contents are not altered after the signing process.

We have found one other post that describes a similar situation, but that question is still unanswered. A related issue might be SMJobBless returning error 4098.

We are testing on OSX 10.7.4.

Anyone faced similar issues or is there something obvious that we are doing wrong?

like image 586
AvD Avatar asked Jun 19 '12 09:06

AvD


1 Answers

This is due to a bug related to how SMJobBless replaces the helper tool on disk. In particular, it modifies the binary in place rather than taking the common approach of writing to a temporary file and then renaming it over top of the destination. The effect of this is that if the binary is in memory, the modifications to the file change the memory pages backing the file, invalidating their code signature. I've written up a bug report about this as rdar://problem/13514523. I'd encourage you to file your own if you've not done so already.

A possible workaround may be to have your application ask the helper tool to remove itself from disk before you use SMJobBless to upgrade it. This should result in SMJobBless copying to a new file on disk, bypassing the issue.

like image 59
bdash Avatar answered Oct 25 '22 18:10

bdash