Skip to content
Permalink
Browse files Browse the repository at this point in the history
If the server instance directory already exists, it is now removed fi…
…rst in order get correct directory permissions.

If the directory still exists after removal, Phusion Passenger aborts to avoid writing to a directory with unexpected permissions.
Fixes issue #910.
  • Loading branch information
FooBarWidget committed Jun 27, 2013
1 parent 5db9246 commit 5483b32
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 2 deletions.
4 changes: 4 additions & 0 deletions NEWS
Expand Up @@ -34,6 +34,10 @@ Release 4.0.6
created with the setuid bit, when it should have sticky bit (to prevent
existing files from being deleted or renamed by a user that doesn't own the
file). This has now been fixed.
* If the server instance directory already exists, it will now be removed
first in order get correct directory permissions. If the directory still
exists after removal, Phusion Passenger aborts to avoid writing to a
directory with unexpected permissions. Fixes issue #910.
* The installer now checks whether the system has enough virtual memory, and
prints a helpful warning if it doesn't.
* Linux/AArch64 compatibility fixes. Patch contributed by Dirk Mueller.
Expand Down
29 changes: 28 additions & 1 deletion ext/common/ServerInstanceDir.h
Expand Up @@ -30,6 +30,7 @@
#include <oxt/backtrace.hpp>

#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <pwd.h>
Expand Down Expand Up @@ -214,7 +215,33 @@ class ServerInstanceDir: public noncopyable {
* rights though, because we want admin tools to be able to list the available
* generations no matter what user they're running as.
*/
makeDirTree(path, "u=rwx,g=rx,o=rx");
if (owner) {
switch (getFileType(path)) {
case FT_NONEXISTANT:
createDirectory(path);
break;
case FT_DIRECTORY:
removeDirTree(path);
createDirectory(path);
break;
default:
throw RuntimeException("'" + path + "' already exists, and is not a directory");
}
} else if (getFileType(path) != FT_DIRECTORY) {
throw RuntimeException("Server instance directory '" + path +
"' does not exist");
}
}

void createDirectory(const string &path) const {
// We do not use makeDirTree() here. If an attacker creates a directory
// just before we do, then we want to abort because we want the directory
// to have specific permissions.
if (mkdir(path.c_str(), parseModeString("u=rwx,g=rx,o=rx")) == -1) {
int e = errno;
throw FileSystemException("Cannot create server instance directory '" +
path + "'", e, path);
}
}

bool isDirectory(const string &dir, struct dirent *entry) const {
Expand Down
4 changes: 3 additions & 1 deletion test/cxx/ServerInstanceDirTest.cpp
Expand Up @@ -58,9 +58,11 @@ namespace tut {
}

TEST_METHOD(5) {
// The destructor doesnn't remove the server instance directory if it
// The destructor doesn't remove the server instance directory if it
// wasn't created with the ownership flag or if it's been detached.
string path, path2;
makeDirTree(parentDir + "/passenger-test.1234");
makeDirTree(parentDir + "/passenger-test.5678");
{
ServerInstanceDir dir(parentDir + "/passenger-test.1234", false);
ServerInstanceDir dir2(parentDir + "/passenger-test.5678", false);
Expand Down

0 comments on commit 5483b32

Please sign in to comment.