Low severityNVD Advisory· Published Feb 19, 2015· Updated May 6, 2026
CVE-2014-1831
CVE-2014-1831
Description
Phusion Passenger before 4.0.37 allows local users to write to certain files and directories via a symlink attack on (1) control_process.pid or a (2) generation-* file.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
passengerRubyGems | < 4.0.38 | 4.0.38 |
Affected products
1Patches
134b1087870c2Fix low-urgency security vulnerability: writing files to arbitrary directory by hijacking temp directories.
4 files changed · +67 −2
ext/common/ServerInstanceDir.h+1 −1 modified@@ -213,7 +213,7 @@ class ServerInstanceDir: public noncopyable { * generations no matter what user they're running as. */ if (owner) { - switch (getFileType(path)) { + switch (getFileTypeNoFollowSymlinks(path)) { case FT_NONEXISTANT: createDirectory(path); break;
ext/common/Utils.cpp+29 −0 modified@@ -143,6 +143,35 @@ getFileType(const StaticString &filename, CachedFileStat *cstat, unsigned int th } } +FileType +getFileTypeNoFollowSymlinks(const StaticString &filename) { + struct stat buf; + int ret; + + ret = lstat(filename.c_str(), &buf); + if (ret == 0) { + if (S_ISREG(buf.st_mode)) { + return FT_REGULAR; + } else if (S_ISDIR(buf.st_mode)) { + return FT_DIRECTORY; + } else if (S_ISLNK(buf.st_mode)) { + return FT_SYMLINK; + } else { + return FT_OTHER; + } + } else { + if (errno == ENOENT) { + return FT_NONEXISTANT; + } else { + int e = errno; + string message("Cannot lstat '"); + message.append(filename); + message.append("'"); + throw FileSystemException(message, e, filename); + } + } +} + void createFile(const string &filename, const StaticString &contents, mode_t permissions, uid_t owner, gid_t group, bool overwrite)
ext/common/Utils.h+7 −1 modified@@ -65,6 +65,8 @@ typedef enum { FT_REGULAR, /** A directory. */ FT_DIRECTORY, + /** A symlink. Only returned by getFileTypeNoFollowSymlinks(), not by getFileType(). */ + FT_SYMLINK, /** Something else, e.g. a pipe or a socket. */ FT_OTHER } FileType; @@ -110,7 +112,7 @@ bool fileExists(const StaticString &filename, CachedFileStat *cstat = 0, /** * Check whether 'filename' exists and what kind of file it is. * - * @param filename The filename to check. + * @param filename The filename to check. It MUST be NULL-terminated. * @param mstat A CachedFileStat object, if you want to use cached statting. * @param throttleRate A throttle rate for cstat. Only applicable if cstat is not NULL. * @return The file type. @@ -121,6 +123,10 @@ bool fileExists(const StaticString &filename, CachedFileStat *cstat = 0, */ FileType getFileType(const StaticString &filename, CachedFileStat *cstat = 0, unsigned int throttleRate = 0); +/** + * Like getFileType(), but does not follow symlinks. + */ +FileType getFileTypeNoFollowSymlinks(const StaticString &filename); /** * Create the given file with the given contents, permissions and ownership.
NEWS+30 −0 modified@@ -17,6 +17,36 @@ Release 4.0.37 using this command guarantees that clients see no errors. * Fixed a crash occurs when an application fails to spawn, but the HTTP client disconnects before the error page is generated. Fixes issue #1028. + * Fixed a symlink-related security vulnerability. + + Urgency: low + Scope: local exploit + Summary: writing files to arbitrary directory by hijacking temp directories + Affected versions: 4.0.5 and later + Fixed versions: 4.0.37 + + Description: + Phusion Passenger creates a "server instance directory" in /tmp during startup, + which is a temporary directory that Phusion Passenger uses to store working files. + This directory is deleted after Phusion Passenger exits. For various technical + reasons, this directory must have a semi-predictable filename. If a local attacker + can predict this filename, and precreates a symlink with the same filename that + points to an arbitrary directory with mode 755, owner root and group root, then + the attacker will succeed in making Phusion Passenger write files and create + subdirectories inside that target directory. The following files/subdirectories + are created: + + * control_process.pid + * generation-X, where X is a number. + + If you happen to have a file inside the target directory called `control_process.pid`, + then that file's contents are overwritten. + + These files and directories are deleted during Phusion Passenger exit. The target + directory itself is not deleted, nor are any other contents inside the target + directory, although the symlink is. + + Thanks go to Jakub Wilk for discovering this issue. Release 4.0.36
Vulnerability mechanics
Synthesis attempt was rejected by the grounding validator. Re-run pending.
References
9- github.com/advisories/GHSA-c7j7-p5jq-26ffghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2014-1831ghsaADVISORY
- lists.fedoraproject.org/pipermail/package-announce/2015-February/149032.htmlnvdWEB
- openwall.com/lists/oss-security/2014/01/28/8nvdWEB
- openwall.com/lists/oss-security/2014/01/30/3nvdWEB
- bugs.debian.org/cgi-bin/bugreport.cginvdWEB
- bugzilla.redhat.com/show_bug.cginvdWEB
- github.com/phusion/passenger/commit/34b1087870c2nvdWEB
- github.com/rubysec/ruby-advisory-db/blob/master/gems/passenger/CVE-2014-1831.ymlghsaWEB
News mentions
0No linked articles in our index yet.