system.privilege.taskport succeds but task_for_pid returns !=KERN_SUCESS

Ivan Ostres <[email protected]>
Newsgroups gmane.comp.macosx.devel
Message-ID <[email protected]>
Hi all!

I wrote a small test application on Leopard 10.5.8 that does  
task_for_pid after authorization which always fail no matter what I  
do. I did a codesign and authorization itself goes fine:

[ivan]~/hoby/debuger > gcc -m64 syscall2.c -o sysc2 -framework  
Security 
                                                                       
[21:35]
[ivan]~/hoby/debuger > codesign -s gdb ./ 
sysc2 
                                                                                               [21 
:36]
[ivan]~/hoby/debuger  
 > 
                                                                                                                       [21 
:36]
[ivan]~/hoby/debuger  
 > 
                                                                                                                       [21 
:36]
[ivan]~/hoby/debuger > ./ 
sysc2 
                                                                                                               [21 
:36]
Jan 22 21:36:25 devil com.apple.SecurityServer[26]: Succeeded  
authorizing right system.privilege.taskport by client /Users/ivan/hoby/ 
debuger/sysc2 for authorization created by /Users/ivan/hoby/debuger/ 
sysc2.
task_for_pid failed.
[ivan]~/hoby/ 
debuger 
 > 
                                                                                                                       [21 
:36]
[ivan]~/hoby/debuger > ./ 
sysc2 
                                                                                                               [21 
:36]
task_for_pid failed.
[ivan]~/hoby/ 
debuger 
 > 
                                                                                                                       [21 
:36]
[ivan]~/hoby/debuger > sudo ./ 
sysc2 
                                                                                                          [21 
:36]
wait pid: 1111
RIP: 7fff5fc01010
[ivan]~/hoby/debuger>

I really started loosing hair over this so please help (running sudo ./ 
auth works fine and task_for_pid returns KERN_SUCCESS)

This is an example source code:

-----Code-----

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ptrace.h>
#include <assert.h>
#include <mach/mach.h>
#include <errno.h>
#include <stdlib.h>
#include <Security/Authorization.h>

int acquireTaskportRight() {
   AuthorizationRef authorization;
   OSStatus status = AuthorizationCreate (NULL,  
kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults,  
&authorization);
   if (status != 0) {
     fprintf(stderr, "Error creating authorization reference\n");
     return -1;
   }
   AuthorizationItem right = { "system.privilege.taskport", 0, 0 , 0 };
   AuthorizationItem items[] = { right };
   AuthorizationRights rights = { sizeof(items) / sizeof(items[0]),  
items };
   AuthorizationFlags flags = kAuthorizationFlagInteractionAllowed |  
kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize;

   status = AuthorizationCopyRights (authorization, &rights,  
kAuthorizationEmptyEnvironment, flags, NULL);
   if (status != 0) {
     fprintf(stderr, "Error authorizing current process with right to  
call task_for_pid\n");
     return -1;
   }
   return 0;
}


void check(int cond, char* msg) {
   if (!cond) {
     printf("%s\n", msg);
     exit(-1);
   }
}

int main() {
   pid_t child = fork();

   if (child == 0) {
     /* PT_TRACE_ME will stop the process after the execl is executed  
and allows the parent
        to take control. */
     check(!ptrace(PT_TRACE_ME, 0, 0, 0), "PT_TRACE_ME failed.");
     execl("./hello", "hello", NULL);
   } else {
     /* Get the task for this pid. Seems to require superuser  
privileges or some gid hack.
        Go Apple! */
     mach_port_t task;

     check(acquireTaskportRight()==0,"acquireTaskportRight failed");

     check(task_for_pid(mach_task_self(), child, &task) ==  
KERN_SUCCESS, "task_for_pid failed.");

     /* Get the list of threads in that process (we expect one thread  
exactly.) */
     thread_act_port_array_t threadList;
     mach_msg_type_number_t threadCount;
     check(task_threads(task, &threadList, &threadCount) ==  
KERN_SUCCESS, "task_threads failed.");
     check(threadCount == 1, "task has more than one thread.");


       /* Wait for updates from the child process we are tracing */
       int status;
       pid_t w = wait(&status);
       printf("wait pid: %d\n",w);


       /* Read the register state of the child via Mach (since we are  
single-stepping the child is guaranteed to be suspended at the moment.  
*/
       x86_thread_state64_t state;
       mach_msg_type_number_t stateCount = x86_THREAD_STATE64_COUNT;
       check(thread_get_state(threadList[0],
			     x86_THREAD_STATE64,
			     (thread_state_t)&state,
			     &stateCount) == KERN_SUCCESS, "thread_get_state failed.");

	printf("RIP: %lx\n",state.__rip);




       check(ptrace(PT_CONTINUE, child, (char*)1, 0) == 0,  
"PT_CONTINUE failed.");
     }

}

-----Code-----

Best Regards,
Ivan
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.