Bug 211593 - procfs man page says "/proc/[pid]/exe" is just a symlink, which for me led to wrong expectations (since it appears to be special?)
Summary: procfs man page says "/proc/[pid]/exe" is just a symlink, which for me led to...
Status: NEW
Alias: None
Product: Documentation
Classification: Unclassified
Component: man-pages (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: documentation_man-pages@kernel-bugs.osdl.org
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-02-06 16:59 UTC by Ellie
Modified: 2021-02-06 16:59 UTC (History)
0 users

See Also:
Kernel Version:
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description Ellie 2021-02-06 16:59:13 UTC
The procfs man page currently says the following on "/proc/[pid]/exe":

              Under Linux 2.2 and later, this file is a symbolic link
              containing the actual pathname of the executed command.
              This symbolic link can be dereferenced normally;
              attempting to open it will open the executable.  You can
              even type /proc/[pid]/exe to run another copy of the same
              executable that is being run by process [pid].  If the
              pathname has been unlinked, the symbolic link will contain
              the string '(deleted)' appended to the original pathname.

I concluded the following things from this:

1. Even if I use open() rather than readlink() on /proc/[pid]/exe I will likely suffer a race if the target is moved in the same moment, since symlinks track by path and so it might be inherently impossible to atomically update the symlink target path along with a move in such a way that any open racing it will always get the correct target at any point in time.

2. When I use open() on /proc/[pid]/exe after the program binary itself was unlinked I'll get an error, since at least my understanding so far was that symlinks only store a path (relative or not), so something that still has an inode but is otherwise removed from path-reachable references cannot be linked to anymore.

At least the second one does NOT seem to be the case, leading me to think that /exe is not actually a real symlink and the first one also might not be a problem as a consequence. However, this leaves me a bit guessing, since the man page kind of dodges whether this is the case.

Assuming it just behaves LIKE a symlink but in a magic way that always points to the right target, I would propose the following changes to the man page:

1. Point out it just behaves LIKE a symlink, but it is magical such that the obvious downsides of race conditions when the binary is moved around or removed are avoided and it'll magically always work and point to the correct binary

2. Point out that because of these races being avoided, using readlink() is inherently unsafe compared to a direct open() when used on /proc/self/exe for opening the binary, since the target might move between readlink() and fopen() on the path while for open() that is impossible due to the link's magic nature. This might be super obvious, but sadly the readlink() + fopen() approach seems to be all over the internet and all over StackOverflow, with no notes on how much less safe it is for reading a program's own binary. So I feel like such an extra note might be warranted.

Of course this is all assuming my guesses are correct. If they aren't, this is probably an invalid ticket.

Note You need to log in before you can comment on or make changes to this bug.