11/*
22 * Phusion Passenger - https://www.phusionpassenger.com/
3- * Copyright (c) 2010-2013 Phusion
3+ * Copyright (c) 2010-2014 Phusion
44 *
55 * "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
66 *
@@ -193,6 +193,9 @@ class ServerInstanceDir: public noncopyable {
193193
194194 void initialize (const string &path, bool owner) {
195195 TRACE_POINT ();
196+ struct stat buf;
197+ int ret;
198+
196199 this ->path = path;
197200 this ->owner = owner;
198201
@@ -212,18 +215,25 @@ class ServerInstanceDir: public noncopyable {
212215 * rights though, because we want admin tools to be able to list the available
213216 * generations no matter what user they're running as.
214217 */
218+
219+ do {
220+ ret = lstat (path.c_str (), &buf);
221+ } while (ret == -1 && errno == EAGAIN);
215222 if (owner) {
216- switch (getFileTypeNoFollowSymlinks (path)) {
217- case FT_NONEXISTANT:
223+ if (ret == 0 ) {
224+ if (S_ISDIR (buf.st_mode )) {
225+ verifyDirectoryPermissions (path, buf);
226+ } else {
227+ throw RuntimeException (" '" + path + " ' already exists, and is not a directory" );
228+ }
229+ } else if (errno == ENOENT) {
218230 createDirectory (path);
219- break ;
220- case FT_DIRECTORY:
221- verifyDirectoryPermissions (path);
222- break ;
223- default :
224- throw RuntimeException (" '" + path + " ' already exists, and is not a directory" );
231+ } else {
232+ int e = errno;
233+ throw FileSystemException (" Cannot lstat '" + path + " '" ,
234+ e, path);
225235 }
226- } else if (getFileType (path) != FT_DIRECTORY ) {
236+ } else if (! S_ISDIR (buf. st_mode ) ) {
227237 throw RuntimeException (" Server instance directory '" + path +
228238 " ' does not exist" );
229239 }
@@ -259,14 +269,10 @@ class ServerInstanceDir: public noncopyable {
259269 * so that an attacker cannot pre-create a directory with too liberal
260270 * permissions.
261271 */
262- void verifyDirectoryPermissions (const string &path) {
272+ void verifyDirectoryPermissions (const string &path, struct stat &buf ) {
263273 TRACE_POINT ();
264- struct stat buf;
265274
266- if (stat (path.c_str (), &buf) == -1 ) {
267- int e = errno;
268- throw FileSystemException (" Cannot stat() " + path, e, path);
269- } else if (buf.st_mode != (S_IFDIR | parseModeString (" u=rwx,g=rx,o=rx" ))) {
275+ if (buf.st_mode != (S_IFDIR | parseModeString (" u=rwx,g=rx,o=rx" ))) {
270276 throw RuntimeException (" Tried to reuse existing server instance directory " +
271277 path + " , but it has wrong permissions" );
272278 } else if (buf.st_uid != geteuid () || buf.st_gid != getegid ()) {
0 commit comments