3

I am in a kernel module and I want to have the whole process name from a given pid. exactly: I want the line which is hold in /proc/PID/cmdline.

The problem is that task_struct->comm[] is only 15 bytes long and doesn't handle if a program changes his argv[] manually or via setproctitle(3)...

Any ideas? :)

2 Answers 2

4

You could always look at how the kernel does it. You'll see the function:

proc_pid_cmdline(struct task_struct *task, char * buffer) 

It's fairly easy to follow but once you have the task_struct for the process you are interested in you use access_process_vm() to slurp the bits you want from mm->arg_start.

Sign up to request clarification or add additional context in comments.

3 Comments

I was using this function BUT with this I cannot access the whole argv, only argv[0] :(
thomasbl: You are accessing the whole argv, you're just stopping at the first '\0', which is the end of argv[0] - each element is separated by a '\0'.
thank you for the right answer of my problem! But I don't read your answer yesterday and so today I found it out by myself :)
1

What's wrong with opening the /proc/<pid>/cmdline file and just reading the contents?

3 Comments

the problem is that I am hijacked the open() syscall and if I try to open the /proc/pid/cmdline for reading I'll end up in an endless loop.
Wouldn't you have simply chained the syscall? In other words, save its last value before you (so eloquently) hijacked it. In that case you would be able to just call the old one.
Otherwise you would have to provide all the open functionality in your intercept, rather than just having to add your code to do new stuff and letting the old stuff be handled by the kernel proper.