author | erik <erik> | 2007-01-26 20:30:32 (UTC) |
---|---|---|
committer | erik <erik> | 2007-01-26 20:30:32 (UTC) |
commit | f77da1ae08512b02a3c50a124f823ed77e53dd64 (patch) (unidiff) | |
tree | ac7e414aff95348e0bf2fba3f45b2a06a4eb4623 | |
parent | 4688f98202f590ec6af6c2e66a49dd2f80536083 (diff) | |
download | opie-f77da1ae08512b02a3c50a124f823ed77e53dd64.zip opie-f77da1ae08512b02a3c50a124f823ed77e53dd64.tar.gz opie-f77da1ae08512b02a3c50a124f823ed77e53dd64.tar.bz2 |
Both packageslave.cpp and textedit.cpp have instances of possibly exploitable
race conditions associated to files. The big deal is that it is quite typical
to use strings of pathnames to track files. But because that does not leverage
the filesystem would be attackers may be able to exploit time lags in uses
of filesystem functions (like stat and chmod or open) to get files with
suspect data into the files that the applications are working with.
This commit closes that potential hole even though there are no known exploits.
Better safe then sorry. There is no change in the behavior of the apps.
-rw-r--r-- | core/apps/textedit/textedit.cpp | 9 | ||||
-rw-r--r-- | core/launcher/packageslave.cpp | 30 |
2 files changed, 22 insertions, 17 deletions
diff --git a/core/apps/textedit/textedit.cpp b/core/apps/textedit/textedit.cpp index 4bbc62b..1c81a55 100644 --- a/core/apps/textedit/textedit.cpp +++ b/core/apps/textedit/textedit.cpp | |||
@@ -786,7 +786,6 @@ bool TextEdit::save() { | |||
786 | saveAs(); | 786 | saveAs(); |
787 | return false; | 787 | return false; |
788 | } | 788 | } |
789 | name = currentFileName; | ||
790 | if(doc) { | 789 | if(doc) { |
791 | file = doc->file(); | 790 | file = doc->file(); |
792 | odebug << "saver file "+file << oendl; | 791 | odebug << "saver file "+file << oendl; |
@@ -807,7 +806,8 @@ bool TextEdit::save() { | |||
807 | 806 | ||
808 | struct stat buf; | 807 | struct stat buf; |
809 | mode_t mode; | 808 | mode_t mode; |
810 | stat(file.latin1(), &buf); | 809 | QFile f(file); |
810 | fstat(f.handle(), &buf); | ||
811 | mode = buf.st_mode; | 811 | mode = buf.st_mode; |
812 | 812 | ||
813 | if(!fileIs) { | 813 | if(!fileIs) { |
@@ -819,7 +819,6 @@ bool TextEdit::save() { | |||
819 | } | 819 | } |
820 | } else { | 820 | } else { |
821 | odebug << "regular save file" << oendl; | 821 | odebug << "regular save file" << oendl; |
822 | QFile f(file); | ||
823 | if( f.open(IO_WriteOnly)) { | 822 | if( f.open(IO_WriteOnly)) { |
824 | QCString crt = rt.utf8(); | 823 | QCString crt = rt.utf8(); |
825 | f.writeBlock(crt,crt.length()); | 824 | f.writeBlock(crt,crt.length()); |
@@ -827,7 +826,6 @@ bool TextEdit::save() { | |||
827 | QMessageBox::message(tr("Text Edit"),tr("Write Failed")); | 826 | QMessageBox::message(tr("Text Edit"),tr("Write Failed")); |
828 | return false; | 827 | return false; |
829 | } | 828 | } |
830 | |||
831 | } | 829 | } |
832 | editor->setEdited( false); | 830 | editor->setEdited( false); |
833 | edited1=false; | 831 | edited1=false; |
@@ -835,8 +833,7 @@ bool TextEdit::save() { | |||
835 | if(caption().left(1)=="*") | 833 | if(caption().left(1)=="*") |
836 | setCaption(caption().right(caption().length()-1)); | 834 | setCaption(caption().right(caption().length()-1)); |
837 | 835 | ||
838 | 836 | fchmod( f.handle(), mode); | |
839 | chmod( file.latin1(), mode); | ||
840 | } | 837 | } |
841 | return true; | 838 | return true; |
842 | } | 839 | } |
diff --git a/core/launcher/packageslave.cpp b/core/launcher/packageslave.cpp index abbc610..965020e 100644 --- a/core/launcher/packageslave.cpp +++ b/core/launcher/packageslave.cpp | |||
@@ -220,26 +220,34 @@ void PackageHandler::cleanupPackageFiles( const QString &listfile ) | |||
220 | while ( !ts.eof() ) { // until end of file... | 220 | while ( !ts.eof() ) { // until end of file... |
221 | s = ts.readLine(); // line of text excluding '\n' | 221 | s = ts.readLine(); // line of text excluding '\n' |
222 | // for s, do link/mkdir. | 222 | // for s, do link/mkdir. |
223 | if ( s.right(1) == "/" ) { | 223 | // @todo Right now we just move on if the name of the file we |
224 | //should rmdir if empty, after all files have been removed | 224 | // find is actually a directory. What we ought to do is check |
225 | } else { | 225 | // to see if the directory is empty and if so remove it. |
226 | if ( s.right(1) != "/" ) { | ||
226 | #ifndef Q_OS_WIN32 | 227 | #ifndef Q_OS_WIN32 |
227 | odebug << "remove symlink for " << s.ascii() << "" << oendl; | 228 | odebug << "remove symlink for " << s << oendl; |
229 | QFile symFile(s); | ||
230 | QFileInfo symFileInfo(symFile); | ||
228 | //check if it is a symlink first (don't remove /etc/passwd...) | 231 | //check if it is a symlink first (don't remove /etc/passwd...) |
229 | char buf[10]; //we don't care about the contents | 232 | if ( !symFileInfo.readLink().isNull()) |
230 | if ( ::readlink( s.ascii(),buf, 10 >= 0 ) ) | 233 | if (!symFile.remove()) |
231 | ::unlink( s.ascii() ); | 234 | owarn << "Unable to remove symlink " << symFile.name() |
235 | << " " << __FILE__ << ":" << __LINE__ << oendl; | ||
232 | #else | 236 | #else |
233 | // ### revise | 237 | // @todo If we actually want to be portable to other operating |
234 | owarn << "Unable to remove symlink " << __FILE__ << ":" << __LINE__ << "" << oendl; | 238 | // systems we ought to at least have a portable way of removing |
239 | // their notion of symlinks. | ||
240 | owarn << "Unable to remove symlink " << s " " << __FILE__ | ||
241 | << ":" << __LINE__ << oendl; | ||
235 | #endif | 242 | #endif |
236 | } | 243 | } |
237 | } | 244 | } |
238 | f.close(); | 245 | f.close(); |
239 | 246 | ||
240 | //remove the list file | 247 | //remove the list file |
241 | ::unlink( listfile.ascii() ); | 248 | if (!f.remove()) |
242 | 249 | owarn << "Unable to remove list file " << f.name() << " " | |
250 | << __FILE__ << ":" << __LINE__ << oendl; | ||
243 | } | 251 | } |
244 | } | 252 | } |
245 | 253 | ||