aboutsummaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* Add countermeasure against hard link attacks in /tmp.HEADmasterKaz Kylheku2022-07-301-0/+9
| | | | | | | | | | * safepath.c (safepath_check): Reject symbolic links that have a link count greater than 2. To defeat this check, the attacker must not only be able to hard link someone else's symlink into a /tmp-like directory, but unlink the original. (That could happen if the user or root have some available symlink sitting in an unsecured directory.)
* Ban file symlinks under /proc for all users.Kaz Kylheku2022-07-301-9/+2
| | | | | | | | | | | | | | | | | | | Travis Ormandy informs of an attack via /proc/<pid>/fd/<n> involving an unlinked file. When the fd link refers to a file "/path/to/foo", that file can be unlinked. The link then spontaneously changes to "/path/to/foo (deleted)". A user who doesn't have permissions to /proc/<pid>/fd can perpetrate this deletion via unlink, relying on their permission to unlink /path/to/foo, which is an unrelated path. * safepath.c (abs_path_check): Do not call geteuid(); perform the check unconditionally, regardless of the effective ID of the caller. This change means that safepath_check does not trust paths generated by Bash process substitution on Linux, even for non-root users. Bash should be built to use named FIFOs, even on Linux, and avoid the dangerous /dev/fd -> /proc/self/fd mechanism.
* Handle consecutive slashes better.Kaz Kylheku2022-07-301-12/+22
| | | | | | | | | | | * safepath.c (safepath_check): At the start of an absolute path and at every component separation, go to the last slash if there are multiple slashes; do not report multiple slashes as an invalid path. Also, if a symbolic link target ends with a slash, then do not add a slash between it and the rest of the path. We thereby conform to the POSIX requirement that if a link target consists of nothing but slashes, then those slashes replace the leading slashes of the rest of the path.
* Fix link grafting bug.Kaz Kylheku2022-07-291-1/+1
| | | | | | | | | | Reported by Travis Ormandy in comp.unix.programmer. * safepath.c (safepath_check): In the case when we are combining a relative symlink target with remaining material from the path, there is a forgotten 1 offset which causes the slash between them to be deleted.
* Use regular expression against /proc symlinks.Kaz Kylheku2022-07-293-11/+43
| | | | | | | | | | | | | | | | * safepath.c (bad_proc): New static variable; regular expression that matches paths under /proc that traverse dangerous symlinks. (bad_proc_rx): Compiled version of above regex. (abs_path_check): Replace ad-hoc path match with regexec call. (safepath_init, safepath_deinit): New functions needed because have to compile a regular expression one time, and then keep using it. We could do this lazily but then we need pthread_once to make things thread safe. * safepath.h (safepath_init, safepath_cleanup): Declared. * testsp.c (main): Call safepath_init and safepath_cleanup.
* Guard against /proc/<pid>/cwd attack.Kaz Kylheku2022-07-291-3/+109
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This exploit against safepath_check was reported by Travis Ormandy in the comp.unix.programmer Usenet newsgroup on July 29th (UTC), message ID jkgrb9FhdslU1 <at> mid.individual.net. On Linux, if you change to some directory and run the "su" program, the operating system will spin up a process whose /proc/<pid> directory is root-owned, and not writable (thus safe-looking) and contains a cwd symlink pointing to that directory. Regular users cannot follow this symlink, but root can, which makes it an attack vector. There eare more unsafe links under /proc; this will be addressed in another commit. * safepath.c (simplify_path): New static function, for removing "..", "." and empty components from a path without filesystem access. When we are checking absolute paths for unsafe patterns we must use simplified paths, otherwise these components can be used to evade the matches we are looking for. However, we cannot then do all of our safety checks on a simplified path because a simplified path can be completely safe, whereas the original isn't: e.g. foo/unsafe/../bar simplifies to foo/bar. (abs_path_check): New static function. Here we will place all knowledge about special paths that are possible attack vectors, starting with this ill-considered /proc/<pid>/cwd. (safepath_check): If the input path is absolute, check it with abs_path_check. Also, if a symlink target is an absolute path, check it also.
* Check ownership of symlinks.Kaz Kylheku2022-07-251-0/+12
| | | | | * safepath.c (safepath_check): Do not continue if a symlink is not owned by root or the caller's effective UID.
* Be sure to root directory from absolute symlink.Kaz Kylheku2022-07-251-1/+12
| | | | | | | | * safepath.c (safepath_check): If we are checking a relative directory, and an absolute symlink shows up, then we have to check the root directory; we have not checked it before. It could have bad permissions. We ensure we do this at most once.
* README: add Known Caveats section.Kaz Kylheku2022-07-251-0/+15
| | | | | * README: There is an issue with the trust in the current working direcory when relative paths are used.
* Typo in README.Kaz Kylheku2022-07-251-1/+1
|
* Correctly handle readlink overflow.Kaz Kylheku2022-07-242-2/+9
| | | | | | | | | | * safepath.h (SAFEPATH_TOOLONG): New enum constant. * safepath.c (safepatch_check): Don't ignore the truncation situation from readlink. Use the full buffer length, and if readlink returns 256, then diagnose overflow using the new SAFEPATH_TOOLONG error code and bail. (safepath_strerr): Map SAFEPATH_TOOLONG.
* Add SAFEPATH_NOTIDIR error code.Kaz Kylheku2022-07-242-0/+7
| | | | | | | | * safepath.h (SAFEPATH_NOTDIR): New enum. * safepath.c (safepath_err, set_errno): Handle conversion between SAFEPATH_NOTDIR and ENOTDIR. (safepath_strerr): Map SAFEPATH_NOTDIR to message.
* Add GCC sanitizer debugging.Kaz Kylheku2022-07-241-1/+2
| | | | | * Makefile (DIAG_FLAGS): Sanitize for memory misuse and undefined behavior.
* Map safepath errors to strings.Kaz Kylheku2022-07-233-1/+23
| | | | | | | * safepath.[ch]: New function, safepath_strerr. * testsp.c (main): Use new function to print message, rather than integer code.
* Check using effective UID, not real.Kaz Kylheku2022-07-232-4/+4
| | | | | | | | | | | | | | | | | | | We don't want to behave like the access function, which is intended for use in setuid programs to determine what the original user can access. The purpose of safepath_check is to check whether the filesystem can harm the caller. For that, the effective identity that is being wielded should be used. A setuid executable might have a real user ID bob, but effective root. Root does not trust bob; root doesn't want to follow a symlink controlled by bob. * safepath.c (safe_group, tamper_proof): Replace getuid calls with geteuid. * README.md: Updated text.
* Fix some inaccurate comments.Kaz Kylheku2022-07-231-11/+10
| | | | | * safepath.c (tamper_proof, safepath_check): Reword outdated comments.
* safepath: new project.Kaz Kylheku2022-07-225-0/+561
|
* NILKaz Kylheku2022-07-220-0/+0