xref: /minix3/minix/fs/procfs/NOTES (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel SambucDevelopment notes regarding ProcFS. Original document by David van Moolenbroek.
2*433d6423SLionel Sambuc
3*433d6423SLionel Sambuc
4*433d6423SLionel SambucSECURITY MODEL
5*433d6423SLionel Sambuc
6*433d6423SLionel SambucRight now, procfs is not able to deal with security-sensitive information,
7*433d6423SLionel Sambucbecause there would be too many opportunities for rogue processes to obtain
8*433d6423SLionel Sambucvalues they shouldn't be able to get to. This is mainly due to the fact that
9*433d6423SLionel Sambucwhile procfs is running, the environment around it may change arbitrarily: for
10*433d6423SLionel Sambucexample, a /proc/<pid>/mem file could offer access to a process's core memory,
11*433d6423SLionel Sambucbut if a rogue process opened that file right before the victim process invokes
12*433d6423SLionel Sambucan exec() on a setuid binary, the rogue process could read from the victim
13*433d6423SLionel Sambucprocess's memory while a victim user provides this process with their password.
14*433d6423SLionel SambucThis is only one example out of many; such time-to-check/time-to-use race
15*433d6423SLionel Sambucconditions are inherent to the inherently race-prone situation that procfs
16*433d6423SLionel Sambucfinds itself in, trying to provide information about an asynchronously running
17*433d6423SLionel Sambucsystem.
18*433d6423SLionel Sambuc
19*433d6423SLionel SambucA little more specifically, this problem mainly comes up when system calls are
20*433d6423SLionel Sambucmade to obtain information (long) after a certain PID directory has been
21*433d6423SLionel Sambucupdated, which typically happens right after pulling in a new copy of the
22*433d6423SLionel Sambucprocess tables of the kernel, PM, and VFS. Returning stale information from
23*433d6423SLionel Sambucthose tables is usually not a problem: at worst, the caller gets outdated
24*433d6423SLionel Sambucinformation about the system as it once was, after passing a security check for
25*433d6423SLionel Sambucthat point in time. Hence, it can not obtain information it never had access
26*433d6423SLionel Sambucto. Using information from those tables to perform calls later, however, is
27*433d6423SLionel Sambuca different case. In the "mem" example above, procfs would have the old user ID
28*433d6423SLionel Sambucin its copy of the process tables, and yet perform on-demand sys_datacopy calls
29*433d6423SLionel Sambuc(or something similar) to retrieve memory from the process, bypassing a check
30*433d6423SLionel Sambucon the then-current user ID. A similar situation already exists right now for
31*433d6423SLionel Sambucthe /proc/<pid>/map file for example, which pulls in information on demand -
32*433d6423SLionel Sambucbut it provides only public information anyway, just like the other files that
33*433d6423SLionel Sambucprocfs currently exposes.
34*433d6423SLionel Sambuc
35*433d6423SLionel SambucA proper solution to this problem has simply not been implemented yet. It is
36*433d6423SLionel Sambucpossible to change the system in such a way that procfs check whether the
37*433d6423SLionel Sambuctarget process is still in the same security state before returning information
38*433d6423SLionel Sambucto the caller process. This can be done either while or after obtaining the
39*433d6423SLionel Sambucinformation, depending on what is most convenient for the design of the system.
40*433d6423SLionel SambucAny such solution obviously has an impact on system design and procfs'
41*433d6423SLionel Sambucperformance, and was found not worth implementing for the first version of
42*433d6423SLionel Sambucprocfs, since all offered information was public anyway. However, such a change
43*433d6423SLionel Sambuc*must* be made before procfs can expose anything that provides a potential for
44*433d6423SLionel Sambucsecurity breaches.
45*433d6423SLionel Sambuc
46*433d6423SLionel SambucFinally, it must be kept in mind that even updating the process tables from
47*433d6423SLionel Sambucvarious other sources is not an atomic operation. There might be mismatches
48*433d6423SLionel Sambucbetween the tables. Procfs must be able to handle such occurrences with care,
49*433d6423SLionel Sambucfrom both a security perspective and a general functionality perspective.
50*433d6423SLionel Sambuc
51*433d6423SLionel Sambuc
52*433d6423SLionel SambucFUTURE EXPANSIONS
53*433d6423SLionel Sambuc
54*433d6423SLionel SambucIt would be trivial to add a /proc/self symlink pointing to the caller's PID
55*433d6423SLionel Sambucdirectory, if the VFS-FS protocol's REQ_RDLINK request were augmented to
56*433d6423SLionel Sambucinclude the caller's PID or endpoint. However, this would be a procfs-specific
57*433d6423SLionel Sambucprotocol change, and there does not seem to be a need for this just yet.
58*433d6423SLionel Sambuc
59*433d6423SLionel SambucEven more custom protocol changes or procfs-specific backcalls would have to be
60*433d6423SLionel Sambucadded to expose processes' current working directory, root directory,
61*433d6423SLionel Sambucexecutable path, or open files. A number of VFS parts would have to be changed
62*433d6423SLionel Sambucsignificantly to fully support all of these, possibly including an entire DNLC.
63*433d6423SLionel Sambuc
64*433d6423SLionel SambucAll the necessary infrastructure is there to add static (sub)directories - for
65*433d6423SLionel Sambucexample, a /proc/net/ directory. It would be more tricky to add subdirectories
66*433d6423SLionel Sambucfor dynamic (process) directories, for example /proc/<pid>/fd/. This would
67*433d6423SLionel Sambucrequire some changes to the VTreeFS side of the tree management. Some of the
68*433d6423SLionel Sambuccurrent assumptions are documented in type.h.
69