I'm writing a socket filter kext and I would want to ignore any connections made as root. Before OS X Lion, the following code worked flawlessly:
static boolean_t is_root() {
proc_t p = proc_self();
boolean_t isRoot = proc_suser(p);
proc_rele(p);
return isRoot;
}
But now with Lion and Mountain Lion, the is_root()
function always returns true. In Snow Leopard, it worked as I imagined it would.
Here's an example of how I tested the function inside a socket filter event handler:
int debugPid = proc_selfpid();
if (is_root()) {
printf("%u (root)\n", debugPid);
} else {
printf("%u (user)\n", debugPid);
}
But the output always says "root", for example:
2012-11-15 3:48:00.000 PM kernel[0]: 29879 (root)
Where the app making the connection is Twitter (confirmed through the PID). Twitter runs with regular user privileges, not root.
Is there a better/correct way to determine if the process behind the socket connection has root privileges?
According the bsd/sys/proc.h
(link):
/* this routine returns error if the process is not one with super user privileges */
int proc_suser(proc_t p);
So a return of 0
means the process has root privileges or non-zero otherwise.
You want:
static boolean_t is_root() {
proc_t p = proc_self();
int error = proc_suser(p);
proc_rele(p);
return error == 0;
}