task_for_pid error 5

I'm trying to use task_for_pid in a project but I keep getting error code 5 signaling some kind of signing error. Even with this script I cant seem to get it to work.

#include <mach/mach_types.h>
#include <stdlib.h>
#include <mach/mach.h>
#include <mach/mach_error.h>
#include <mach/mach_traps.h>
#include <stdio.h>

int main(int argc, const char * argv[]) {
  task_t task;
  pid_t pid = argc >= 2 ? atoi(argv[1]) : 1;
  kern_return_t error = task_for_pid(mach_task_self(), pid, &task);
  printf("%d -> %x [%d - %s]\n", pid, task, error, mach_error_string(error));
  return error;
}

I've tried signing my executables using codesign and also tried building with Xcode with the "Debugging Tool" box checked under hardened runtime. My Info.plist file includes the SecTaskAccess key with the values "allowed" and "debug." Hoping someone can point me towards what I'm missing here. Thanks!

Answered by DTS Engineer in 815026022

As I mentioned in your other thread, task_for_pid is now restricted to the point that it’s only useful for developer tools. I’m not particularly interested in helping folks who are using it for other purposes. See this.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

task_for_pid is a security vulnerability looking for a place to be exploited, and so modern versions of macOS increasingly restrict its use. This has change so much that I’m a little hazy on the details however, it’s still possible to make it work in certain circumstances AFAIK.

Try this:

  • Make sure that the target process is running an executable with the com.apple.security.get-task-allow entitlement.

  • Make sure the source process is running as root.

Does that work?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Sorry to hijack, but that didn't work for me. I'm trying a command-line utility, doing:

static size_t
get_thread_count(pid_t pid)
{
        mach_port_t me = mach_task_self();
        mach_port_t task;
        kern_return_t res;
        thread_array_t threads;
        mach_msg_type_number_t n_threads;

        res = task_for_pid(me, pid, &task);
        if (res != KERN_SUCCESS) {
                fprintf(stderr, "Unable to get task for pid %d: %d\n", pid, res);
                return 0;
        }
        res = task_threads(task, &threads, &n_threads);
        if (res != KERN_SUCCESS) {
                fprintf(stderr, "Could not get threads: %d\n", res);
                return 0;
        }
        res = vm_deallocate(me, (vm_address_t)threads, n_threads * sizeof(*threads));
        // Ignore error
        return n_threads;
}```

and using an entitlements plist of

<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>com.apple.security.get-task-allow</key> <true/> </dict> </plist>```

and using codesign --sign - --entitlements ./ent.plist --deep ./t3 --force to get it in there, but it fails with error 5. (Even when run as root. 😄)

This could be how I'm codesigning it, of course; I was just doing a simple CLI tool test first.

As I mentioned in your other thread, task_for_pid is now restricted to the point that it’s only useful for developer tools. I’m not particularly interested in helping folks who are using it for other purposes. See this.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Don't need it, obviously! (Of possible interest, though, I'm only interested in finding out information about our own processes, so I assume there's a way to get a task handle for those, even if it involves setting up some XPC between them.)

task_for_pid error 5
 
 
Q