1

I am working on kernel extension and want to find out how to find process name by pid in kernel extension

This code works great in user space

static char procdata[4096];
int mib[3] = { CTL_KERN, KERN_PROCARGS, pid };
procdata[0] = '\0'; // clear
size_t size = sizeof(procdata);
if (sysctl(mib, 3, procdata, &size, NULL, 0)) {
  return ERROR(ERROR_INTERNAL);
}
procdata[sizeof(procdata)-2] = ':';
procdata[sizeof(procdata)-1] = '\0';
ret = procdata;
return SUCCESS;

but for the kernel space, there are errors such as "Use of undeclared identifier 'CTL_KERN'" (even if I add #include )

What is the correct way to do it in kernel extension?

Georgy Buranov
  • 1,296
  • 1
  • 16
  • 26

1 Answers1

3

The Kernel.framework header <sys/proc.h> is what you're looking for.

In particular, you can use proc_name() to get a process's name given its PID:

/* this routine copies the process's name of the executable to the passed in buffer. It 
 * is always null terminated. The size of the buffer is to be passed in as well. This 
 * routine is to be used typically for debugging 
 */
void proc_name(int pid, char * buf, int size);

Note however, that the name will be truncated to MAXCOMLEN - 16 bytes.

You might also be able to use the sysctl via sysctlbyname() from the kernel. In my experience, that function doesn't work well though, as the sysctl buffer memory handling isn't expecting buffers in kernel address space, so most types of sysctl will cause a kernel panic if called from a non-kernel thread. It also doesn't seem to work for all sysctls.

pmdj
  • 22,018
  • 3
  • 52
  • 103
  • Sidenote: `proc_name()` is defined in ``. This is a very obscure API. Thank you for the info! – Andy Jun 21 '15 at 16:41
  • @Andy That is true for user space, in the kernel there's a similar function in `` - which was what the question was about. – pmdj Jan 29 '18 at 16:18
  • How to get the full path of the process name? e.g `/usr/foo/my_binary` ? – horseyguy Jul 19 '19 at 00:58
  • @horseyguy This isn‘t directly and reliably possible, you’d need to get the executable’s vnode when the process starts. See https://stackoverflow.com/a/33740742/48660 – pmdj Jul 19 '19 at 05:57
  • @pmdj hmmm....interesting. i'm trying to implement an application-level firewall based on application paths, can you think of the best way to go about this knowing that we can't get the full process path? – horseyguy Jul 19 '19 at 11:03
  • 1
    @horseyguy I didn't say it's not possible at all, I said you can't get to it directly. In user space, you can get it using `proc_pidpath()` from libproc. **However** this requires the co-operation of the process as it reads it from the `argv[0]` in the process in question. So processes can lie about that path. Second, files can be moved or replaced, so the information only really makes sense at the point of process launch. Finally, in the answer I linked, I explained how to get the path inside the kext during process launch using KAUTH. Note that KAUTH is deprecated in 10.15, but so are NKE. – pmdj Jul 20 '19 at 10:29
  • @pmdj you're a fount of know-how, the only person with knowledge on this active on SO. May i ask you another? I'm using the kernel control API to talk to a daemon process - but there's no information on whether the kernel control callback that receives messages from userspace (ctl_setopt) "interrupts" whatever function is currently executing or whether it's queued to run after the current function. Basically, i would *love* my kernel function (i.e an NKE socket connect callback) to *block* and wait for the response from the daemon (to get important data), before continuing, is this possible? – horseyguy Jul 21 '19 at 19:07
  • @horseyguy As it's entirely unrelated to this question, please open a new question for that to make it easy for other users to search for it. I get an alert for any question tagged with [kernel-extension] so I will definitely see it! (My email address is also in my profile, so I'm not hard to get hold of.) The short answer though is that any socket callbacks in the kext run in the context of the calling process's thread, and control returns to user space only after the callback returns. – pmdj Jul 22 '19 at 08:01
  • @pmdj thanks man, here it is! https://stackoverflow.com/questions/57145678/how-to-have-synchronous-communication-between-kext-and-user-space-on-macos – horseyguy Jul 22 '19 at 12:04
  • @pmdj one other question -- if the NKE runs in the context of the user process, does that mean the NKE gets access to global variables defined in that process? – horseyguy Jul 22 '19 at 14:28
  • 1
    @pmdj are you sure `proc_pidpath()` is based on `argv[0]` ? i changed it for a process (which changes the name under the `ps` command) and then ran `proc_pidpath()` from another process, and it returned the full process name as it was originally, not the modified one. – horseyguy Jul 24 '19 at 14:47