X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/b5299791f4f00fc34907fc66ad03043ecca22b31..67479dbd136d020bd2dc4668603fb0e49d8d9419:/src/unix/snglinst.cpp diff --git a/src/unix/snglinst.cpp b/src/unix/snglinst.cpp index 80bf0d1629..66d616c32a 100644 --- a/src/unix/snglinst.cpp +++ b/src/unix/snglinst.cpp @@ -7,7 +7,7 @@ // Created: 09.06.01 // RCS-ID: $Id$ // Copyright: (c) 2001 Vadim Zeitlin -// License: wxWindows license +// License: wxWindows licence /////////////////////////////////////////////////////////////////////////////// // ============================================================================ @@ -18,7 +18,7 @@ // headers // ---------------------------------------------------------------------------- -#ifdef __GNUG__ +#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) #pragma implementation "snglinst.h" #endif @@ -35,16 +35,16 @@ #include "wx/string.h" #include "wx/log.h" #include "wx/intl.h" - #include "wx/file.h" #endif //WX_PRECOMP +#include "wx/file.h" #include "wx/utils.h" // wxGetHomeDir() #include "wx/snglinst.h" #include #include -#include +#include // for S_I[RW]USR #include // for kill() #include @@ -151,15 +151,14 @@ private: LockResult wxSingleInstanceCheckerImpl::CreateLockFile() { // try to open the file - m_fdLock = open(m_nameLock, + m_fdLock = open(m_nameLock.fn_str(), O_WRONLY | O_CREAT | O_EXCL, - S_IREAD | S_IWRITE); + S_IRUSR | S_IWUSR); if ( m_fdLock != -1 ) { // try to lock it - int rc = wxLockFile(m_fdLock, LOCK); - if ( rc == 0 ) + if ( wxLockFile(m_fdLock, LOCK) == 0 ) { // fine, we have the exclusive lock to the file, write our PID // into it @@ -167,7 +166,7 @@ LockResult wxSingleInstanceCheckerImpl::CreateLockFile() // use char here, not wxChar! char buf[256]; // enough for any PID size - int len = sprintf(buf, "%d", m_pidLocker) + 1; + int len = sprintf(buf, "%d", (int)m_pidLocker) + 1; if ( write(m_fdLock, buf, len) != len ) { @@ -181,6 +180,17 @@ LockResult wxSingleInstanceCheckerImpl::CreateLockFile() fsync(m_fdLock); + // change file's permission so that only this user can access it: + if ( chmod(m_nameLock.fn_str(), S_IRUSR | S_IWUSR) != 0 ) + { + wxLogSysError(_("Failed to set permissions on lock file '%s'"), + m_nameLock.c_str()); + + Unlock(); + + return LOCK_ERROR; + } + return LOCK_CREATED; } else // failure: see what exactly happened @@ -188,12 +198,12 @@ LockResult wxSingleInstanceCheckerImpl::CreateLockFile() close(m_fdLock); m_fdLock = -1; - if ( rc != EACCES && rc != EAGAIN ) + if ( errno != EACCES && errno != EAGAIN ) { wxLogSysError(_("Failed to lock the lock file '%s'"), m_nameLock.c_str()); - unlink(m_nameLock); + unlink(m_nameLock.fn_str()); return LOCK_ERROR; } @@ -227,6 +237,26 @@ bool wxSingleInstanceCheckerImpl::Create(const wxString& name) return FALSE; } + // Check if the file is owned by current user and has 0600 permissions. + // If it doesn't, it's a fake file, possibly meant as a DoS attack, and + // so we refuse to touch it: + wxStructStat stats; + if ( wxStat(name, &stats) != 0 ) + { + wxLogSysError(_("Failed to inspect the lock file '%s'"), name.c_str()); + return false; + } + if ( stats.st_uid != getuid() ) + { + wxLogError(_("Lock file '%s' has incorrect owner."), name.c_str()); + return false; + } + if ( stats.st_mode != (S_IFREG | S_IRUSR | S_IWUSR) ) + { + wxLogError(_("Lock file '%s' has incorrect permissions."), name.c_str()); + return false; + } + // try to open the file for reading and get the PID of the process // which has it wxFile file(name, wxFile::read); @@ -254,11 +284,11 @@ bool wxSingleInstanceCheckerImpl::Create(const wxString& name) } else { - if ( sscanf(buf, "%d", &m_pidLocker) == 1 ) + if ( sscanf(buf, "%d", (int *)&m_pidLocker) == 1 ) { if ( kill(m_pidLocker, 0) != 0 ) { - if ( unlink(name) != 0 ) + if ( unlink(name.fn_str()) != 0 ) { wxLogError(_("Failed to remove stale lock file '%s'."), name.c_str()); @@ -292,7 +322,7 @@ void wxSingleInstanceCheckerImpl::Unlock() { if ( m_fdLock != -1 ) { - if ( unlink(m_nameLock) != 0 ) + if ( unlink(m_nameLock.fn_str()) != 0 ) { wxLogSysError(_("Failed to remove lock file '%s'"), m_nameLock.c_str()); @@ -332,7 +362,12 @@ bool wxSingleInstanceChecker::Create(const wxString& name, wxString fullname = path; if ( fullname.empty() ) { - fullname << wxGetHomeDir() << _T('/'); + fullname = wxGetHomeDir(); + } + + if ( fullname.Last() != _T('/') ) + { + fullname += _T('/'); } fullname << name;