1 Development notes regarding ProcFS. Original document by David van Moolenbroek.
6 Right now, procfs is not able to deal with security-sensitive information,
7 because there would be too many opportunities for rogue processes to obtain
8 values they shouldn't be able to get to. This is mainly due to the fact that
9 while procfs is running, the environment around it may change arbitrarily: for
10 example, a /proc/<pid>/mem file could offer access to a process's core memory,
11 but if a rogue process opened that file right before the victim process invokes
12 an exec() on a setuid binary, the rogue process could read from the victim
13 process's memory while a victim user provides this process with their password.
14 This is only one example out of many; such time-to-check/time-to-use race
15 conditions are inherent to the inherently race-prone situation that procfs
16 finds itself in, trying to provide information about an asynchronously running
19 A little more specifically, this problem mainly comes up when system calls are
20 made to obtain information (long) after a certain PID directory has been
21 updated, which typically happens right after pulling in a new copy of the
22 process tables of the kernel, PM, and VFS. Returning stale information from
23 those tables is usually not a problem: at worst, the caller gets outdated
24 information about the system as it once was, after passing a security check for
25 that point in time. Hence, it can not obtain information it never had access
26 to. Using information from those tables to perform calls later, however, is
27 a different case. In the "mem" example above, procfs would have the old user ID
28 in its copy of the process tables, and yet perform on-demand sys_datacopy calls
29 (or something similar) to retrieve memory from the process, bypassing a check
30 on the then-current user ID. A similar situation already exists right now for
31 the /proc/<pid>/map file for example, which pulls in information on demand -
32 but it provides only public information anyway, just like the other files that
33 procfs currently exposes.
35 A proper solution to this problem has simply not been implemented yet. It is
36 possible to change the system in such a way that procfs check whether the
37 target process is still in the same security state before returning information
38 to the caller process. This can be done either while or after obtaining the
39 information, depending on what is most convenient for the design of the system.
40 Any such solution obviously has an impact on system design and procfs'
41 performance, and was found not worth implementing for the first version of
42 procfs, since all offered information was public anyway. However, such a change
43 *must* be made before procfs can expose anything that provides a potential for
46 Finally, it must be kept in mind that even updating the process tables from
47 various other sources is not an atomic operation. There might be mismatches
48 between the tables. Procfs must be able to handle such occurrences with care,
49 from both a security perspective and a general functionality perspective.
54 It would be trivial to add a /proc/self symlink pointing to the caller's PID
55 directory, if the VFS-FS protocol's REQ_RDLINK request were augmented to
56 include the caller's PID or endpoint. However, this would be a procfs-specific
57 protocol change, and there does not seem to be a need for this just yet.
59 Even more custom protocol changes or procfs-specific backcalls would have to be
60 added to expose processes' current working directory, root directory,
61 executable path, or open files. A number of VFS parts would have to be changed
62 significantly to fully support all of these, possibly including an entire DNLC.
64 All the necessary infrastructure is there to add static (sub)directories - for
65 example, a /proc/net/ directory. It would be more tricky to add subdirectories
66 for dynamic (process) directories, for example /proc/<pid>/fd/. This would
67 require some changes to the VTreeFS side of the tree management. Some of the
68 current assumptions are documented in type.h.