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