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