Parsing /proc/maps? [closed]

2019-09-29 06:38发布

问题:

I wrote the following code in C. What I have done so far is open the proc directory and read the processes inside - dictories that did not consist of numerical characters were simply disregarded as I only want to look at the numeric directories. What I want to do is to print the PID of all the processes in the proc directory that have read and write permissions. My question is how can I extract the permissions of a process from the proc/.../maps file?

Here is a snippet of my code where I am having trouble:

sprintf(buf, "/proc/%d/maps", tgid->d_name); 
file = fopen(buf, "r");

while (fgets(buf, sizeof(buf), file)) {
    sscanf(buf, "%x-%x %4c %x %x:%x", &from, &to, flags, &offset, &major, &minor);
}

fclose(file);
if (flags[0] == 'r' && flags[1] == 'w') {
    printf("%d\n", tgid->d_name);
}      

回答1:

What I want to do is to print the PID of all the processes that are read and writable

A process is an abstraction provided by some operating system. It makes no sense to speak of a "readable" process (or a "writable" one), or one with "read" permissions or "write" permissions, since it is about file system permissions. A process is not a file, and its /proc/1234/ directory is just a view into that process given by the kernel. A process is using file descriptors to access files (and you might scan its /proc/1234/fd/ directory).

The proc(5) file system is a pseudo file system specific to Linux. The /proc/$pid/maps is a textual view showing the virtual address space of a process. You can read that pseudo-file sequentially.

To change its virtual address space, a Linux process would use system calls like execve(2) (which initializes a fresh virtual address space for a new program), mmap(2) and munmap, mprotect(2), etc...

To scan a directory (such as /proc/1234/fd/ or even /proc/) programmatically, use opendir(3) with closedir after having looped on readdir(3) (you'll probably also use stat(2) on a file path that you have constructed) You could use nftw(3) in some cases.

Read also Operating Systems: Three Easy Pieces to get a broad view about OSes.

after edit

What I want to do is to print the PID of all the processes in the proc directory that have read and write permissions

That has no sense. A process don't have permissions, but it does have credentials(7) (which define what file accesses are permitted to the process). You may parse /proc/1234/status to find the credentials of process of pid 1234 (in particular, the lines starting with Uid: and Gid: from that pseudo-file).

Read some good Linux programming book, perhaps the old ALP. Read also syscalls(2), execve(2), inode(7), path_resolution(7) and also the failure cases of file related system calls such as open(2), read(2), etc... (so also errno(3)). Take time to read carefully proc(5).

My question is how can I extract the permissions of a process from the /proc/.../maps file?

You cannot extract such information from that file. The /proc/1234/maps pseudo-file describes the virtual address space of process 1234. The credentials are given (with other status information) in /proc/1234/status. And it makes no sense to speak of the permissions of a process.



回答2:

I don't know what exactly you're trying to do, but your program certainly doesn't do it.

Here's what your program does:

  • Open /proc/1234/maps where 1234 is the process's own PID.
  • Read the lines in this file one by one and parse them, recording the values in flags and other variables.
  • Print out information based on the final value of flags, which was collected from the last (matching) line.

So:

  • This will not “print the PID of all the processes” in any sense, since you're only looking at a single process.
  • What is printed out is based on the last line of the maps file. On x86_64 at least, this is the vsyscall area, which contains code and therefore is executable but not writable.

I won't offer a way to fix your program since I don't know what you want it to do. Saying “have read and write permissions” is incomplete: permissions over what?