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 /core/apps/textedit/textedit.cpp | |
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.
Diffstat (limited to 'core/apps/textedit/textedit.cpp') (more/less context) (show whitespace changes)
-rw-r--r-- | core/apps/textedit/textedit.cpp | 9 |
1 files changed, 3 insertions, 6 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 | |||
@@ -693,243 +693,240 @@ void TextEdit::openFile( const QString &f ) { | |||
693 | switch ( QMessageBox::warning(this,tr("Text Editor"),tr("Text Editor has detected<BR>you selected a <B>.desktop</B>file.<BR>Open<B>.desktop</B> file or <B>linked</B> file?"),tr(".desktop File"),tr("Linked Document"),0,1,1) ) | 693 | switch ( QMessageBox::warning(this,tr("Text Editor"),tr("Text Editor has detected<BR>you selected a <B>.desktop</B>file.<BR>Open<B>.desktop</B> file or <B>linked</B> file?"),tr(".desktop File"),tr("Linked Document"),0,1,1) ) |
694 | { | 694 | { |
695 | case 0: //desktop | 695 | case 0: //desktop |
696 | filer = f; | 696 | filer = f; |
697 | break; | 697 | break; |
698 | case 1: //linked | 698 | case 1: //linked |
699 | DocLnk sf(f); | 699 | DocLnk sf(f); |
700 | filer = sf.file(); | 700 | filer = sf.file(); |
701 | break; | 701 | break; |
702 | }; | 702 | }; |
703 | } | 703 | } |
704 | else if(fi.baseName().left(1) == "") | 704 | else if(fi.baseName().left(1) == "") |
705 | { | 705 | { |
706 | odebug << "opening dotfile" << oendl; | 706 | odebug << "opening dotfile" << oendl; |
707 | currentFileName=f; | 707 | currentFileName=f; |
708 | openDotFile(currentFileName); | 708 | openDotFile(currentFileName); |
709 | return; | 709 | return; |
710 | } | 710 | } |
711 | /* | 711 | /* |
712 | * The problem is a file where Config(f).isValid() and it does not | 712 | * The problem is a file where Config(f).isValid() and it does not |
713 | * end with .desktop will be treated as desktop file | 713 | * end with .desktop will be treated as desktop file |
714 | */ | 714 | */ |
715 | else if (f.find(".desktop",0,true) != -1 ) | 715 | else if (f.find(".desktop",0,true) != -1 ) |
716 | { | 716 | { |
717 | DocLnk sf(f); | 717 | DocLnk sf(f); |
718 | filer = sf.file(); | 718 | filer = sf.file(); |
719 | if(filer.right(1) == "/") | 719 | if(filer.right(1) == "/") |
720 | filer = f; | 720 | filer = f; |
721 | 721 | ||
722 | } | 722 | } |
723 | else | 723 | else |
724 | filer = f; | 724 | filer = f; |
725 | 725 | ||
726 | DocLnk nf; | 726 | DocLnk nf; |
727 | nf.setType("text/plain"); | 727 | nf.setType("text/plain"); |
728 | nf.setFile(filer); | 728 | nf.setFile(filer); |
729 | currentFileName=filer; | 729 | currentFileName=filer; |
730 | 730 | ||
731 | nf.setName(fi.baseName()); | 731 | nf.setName(fi.baseName()); |
732 | openFile(nf); | 732 | openFile(nf); |
733 | 733 | ||
734 | odebug << "openFile string "+currentFileName << oendl; | 734 | odebug << "openFile string "+currentFileName << oendl; |
735 | 735 | ||
736 | showEditTools(); | 736 | showEditTools(); |
737 | // Show filename in caption | 737 | // Show filename in caption |
738 | QString name = filer; | 738 | QString name = filer; |
739 | int sep = name.findRev( '/' ); | 739 | int sep = name.findRev( '/' ); |
740 | if ( sep > 0 ) | 740 | if ( sep > 0 ) |
741 | name = name.mid( sep+1 ); | 741 | name = name.mid( sep+1 ); |
742 | updateCaption( name ); | 742 | updateCaption( name ); |
743 | } | 743 | } |
744 | 744 | ||
745 | void TextEdit::openFile( const DocLnk &f ) { | 745 | void TextEdit::openFile( const DocLnk &f ) { |
746 | // clear(); | 746 | // clear(); |
747 | // bFromDocView = true; | 747 | // bFromDocView = true; |
748 | FileManager fm; | 748 | FileManager fm; |
749 | QString txt; | 749 | QString txt; |
750 | currentFileName=f.file(); | 750 | currentFileName=f.file(); |
751 | odebug << "openFile doclnk " + currentFileName << oendl; | 751 | odebug << "openFile doclnk " + currentFileName << oendl; |
752 | if ( !fm.loadFile( f, txt ) ) { | 752 | if ( !fm.loadFile( f, txt ) ) { |
753 | // ####### could be a new file | 753 | // ####### could be a new file |
754 | odebug << "Cannot open file" << oendl; | 754 | odebug << "Cannot open file" << oendl; |
755 | } | 755 | } |
756 | // fileNew(); | 756 | // fileNew(); |
757 | if ( doc ) | 757 | if ( doc ) |
758 | delete doc; | 758 | delete doc; |
759 | doc = new DocLnk(f); | 759 | doc = new DocLnk(f); |
760 | editor->setText(txt); | 760 | editor->setText(txt); |
761 | editor->setEdited( false); | 761 | editor->setEdited( false); |
762 | edited1=false; | 762 | edited1=false; |
763 | edited=false; | 763 | edited=false; |
764 | 764 | ||
765 | doc->setName(currentFileName); | 765 | doc->setName(currentFileName); |
766 | updateCaption(); | 766 | updateCaption(); |
767 | setTimer(); | 767 | setTimer(); |
768 | } | 768 | } |
769 | 769 | ||
770 | void TextEdit::showEditTools() { | 770 | void TextEdit::showEditTools() { |
771 | menu->show(); | 771 | menu->show(); |
772 | editBar->show(); | 772 | editBar->show(); |
773 | if(!useSearchBar) | 773 | if(!useSearchBar) |
774 | searchBar->hide(); | 774 | searchBar->hide(); |
775 | else | 775 | else |
776 | searchBar->show(); | 776 | searchBar->show(); |
777 | setWState (WState_Reserved1 ); | 777 | setWState (WState_Reserved1 ); |
778 | } | 778 | } |
779 | 779 | ||
780 | /*! | 780 | /*! |
781 | unprompted save */ | 781 | unprompted save */ |
782 | bool TextEdit::save() { | 782 | bool TextEdit::save() { |
783 | QString name, file; | 783 | QString name, file; |
784 | odebug << "saveAsFile " + currentFileName << oendl; | 784 | odebug << "saveAsFile " + currentFileName << oendl; |
785 | if(currentFileName.isEmpty()) { | 785 | if(currentFileName.isEmpty()) { |
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; |
793 | name = doc->name(); | 792 | name = doc->name(); |
794 | odebug << "File named "+name << oendl; | 793 | odebug << "File named "+name << oendl; |
795 | } else { | 794 | } else { |
796 | file = currentFileName; | 795 | file = currentFileName; |
797 | name = QFileInfo(currentFileName).baseName(); | 796 | name = QFileInfo(currentFileName).baseName(); |
798 | } | 797 | } |
799 | 798 | ||
800 | QString rt = editor->text(); | 799 | QString rt = editor->text(); |
801 | if( !rt.isEmpty() ) { | 800 | if( !rt.isEmpty() ) { |
802 | if(name.isEmpty()) { | 801 | if(name.isEmpty()) { |
803 | saveAs(); | 802 | saveAs(); |
804 | } else { | 803 | } else { |
805 | currentFileName = name; | 804 | currentFileName = name; |
806 | odebug << "saveFile "+currentFileName << oendl; | 805 | odebug << "saveFile "+currentFileName << oendl; |
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) { |
814 | doc->setName( name); | 814 | doc->setName( name); |
815 | FileManager fm; | 815 | FileManager fm; |
816 | if ( !fm.saveFile( *doc, rt ) ) { | 816 | if ( !fm.saveFile( *doc, rt ) ) { |
817 | QMessageBox::message(tr("Text Edit"),tr("Save Failed")); | 817 | QMessageBox::message(tr("Text Edit"),tr("Save Failed")); |
818 | return false; | 818 | return false; |
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()); |
826 | } else { | 825 | } else { |
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; |
834 | edited=false; | 832 | edited=false; |
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 | } |
843 | return false; | 840 | return false; |
844 | } | 841 | } |
845 | 842 | ||
846 | /*! | 843 | /*! |
847 | prompted save */ | 844 | prompted save */ |
848 | bool TextEdit::saveAs() { | 845 | bool TextEdit::saveAs() { |
849 | 846 | ||
850 | if(caption() == tr("Text Editor")) | 847 | if(caption() == tr("Text Editor")) |
851 | return false; | 848 | return false; |
852 | odebug << "saveAsFile " + currentFileName << oendl; | 849 | odebug << "saveAsFile " + currentFileName << oendl; |
853 | 850 | ||
854 | QString rt = editor->text(); | 851 | QString rt = editor->text(); |
855 | odebug << currentFileName << oendl; | 852 | odebug << currentFileName << oendl; |
856 | 853 | ||
857 | if( currentFileName.isEmpty() | 854 | if( currentFileName.isEmpty() |
858 | || currentFileName == tr("Unnamed") | 855 | || currentFileName == tr("Unnamed") |
859 | || currentFileName == tr("Text Editor")) | 856 | || currentFileName == tr("Text Editor")) |
860 | { | 857 | { |
861 | odebug << "do silly TT filename thing" << oendl; | 858 | odebug << "do silly TT filename thing" << oendl; |
862 | QString pt = rt.simplifyWhiteSpace(); | 859 | QString pt = rt.simplifyWhiteSpace(); |
863 | int i = pt.find( ' ' ); | 860 | int i = pt.find( ' ' ); |
864 | QString docname = pt; | 861 | QString docname = pt; |
865 | if ( i > 0 ) docname = pt.left( i ); | 862 | if ( i > 0 ) docname = pt.left( i ); |
866 | 863 | ||
867 | while( docname.startsWith( "." ) ) | 864 | while( docname.startsWith( "." ) ) |
868 | docname = docname.mid( 1 ); | 865 | docname = docname.mid( 1 ); |
869 | docname.replace( QRegExp("/"), "_" ); | 866 | docname.replace( QRegExp("/"), "_" ); |
870 | // Cut the length. Filenames longer than 40 are not helpful | 867 | // Cut the length. Filenames longer than 40 are not helpful |
871 | // and something goes wrong when they get too long. | 868 | // and something goes wrong when they get too long. |
872 | if ( docname.length() > 40 ) docname = docname.left(40); | 869 | if ( docname.length() > 40 ) docname = docname.left(40); |
873 | 870 | ||
874 | if ( docname.isEmpty() ) docname = tr("Unnamed"); | 871 | if ( docname.isEmpty() ) docname = tr("Unnamed"); |
875 | 872 | ||
876 | if(doc) doc->setName(docname); | 873 | if(doc) doc->setName(docname); |
877 | 874 | ||
878 | currentFileName=docname; | 875 | currentFileName=docname; |
879 | } | 876 | } |
880 | 877 | ||
881 | 878 | ||
882 | QMap<QString, QStringList> map; | 879 | QMap<QString, QStringList> map; |
883 | map.insert(tr("All"), QStringList() ); | 880 | map.insert(tr("All"), QStringList() ); |
884 | QStringList text; | 881 | QStringList text; |
885 | text << "text/*"; | 882 | text << "text/*"; |
886 | map.insert(tr("Text"), text ); | 883 | map.insert(tr("Text"), text ); |
887 | text << "*"; | 884 | text << "*"; |
888 | map.insert(tr("All"), text ); | 885 | map.insert(tr("All"), text ); |
889 | 886 | ||
890 | QFileInfo cuFi( currentFileName); | 887 | QFileInfo cuFi( currentFileName); |
891 | QString filee = cuFi.fileName(); | 888 | QString filee = cuFi.fileName(); |
892 | QString dire = cuFi.dirPath(); | 889 | QString dire = cuFi.dirPath(); |
893 | if(dire==".") | 890 | if(dire==".") |
894 | dire = QPEApplication::documentDir(); | 891 | dire = QPEApplication::documentDir(); |
895 | 892 | ||
896 | QString str; | 893 | QString str; |
897 | if( !featureAutoSave) { | 894 | if( !featureAutoSave) { |
898 | str = OFileDialog::getSaveFileName( 2, dire, filee, map); | 895 | str = OFileDialog::getSaveFileName( 2, dire, filee, map); |
899 | } else | 896 | } else |
900 | str = currentFileName; | 897 | str = currentFileName; |
901 | 898 | ||
902 | if(!str.isEmpty()) { | 899 | if(!str.isEmpty()) { |
903 | QString fileNm=str; | 900 | QString fileNm=str; |
904 | 901 | ||
905 | odebug << "saving filename "+fileNm << oendl; | 902 | odebug << "saving filename "+fileNm << oendl; |
906 | QFileInfo fi(fileNm); | 903 | QFileInfo fi(fileNm); |
907 | currentFileName=fi.fileName(); | 904 | currentFileName=fi.fileName(); |
908 | if(doc) | 905 | if(doc) |
909 | delete doc; | 906 | delete doc; |
910 | 907 | ||
911 | DocLnk nf; | 908 | DocLnk nf; |
912 | nf.setType("text/plain"); | 909 | nf.setType("text/plain"); |
913 | nf.setFile( fileNm); | 910 | nf.setFile( fileNm); |
914 | doc = new DocLnk(nf); | 911 | doc = new DocLnk(nf); |
915 | odebug << "Saving file as "+currentFileName << oendl; | 912 | odebug << "Saving file as "+currentFileName << oendl; |
916 | doc->setName( fi.baseName() ); | 913 | doc->setName( fi.baseName() ); |
917 | updateCaption( currentFileName); | 914 | updateCaption( currentFileName); |
918 | 915 | ||
919 | FileManager fm; | 916 | FileManager fm; |
920 | if ( !fm.saveFile( *doc, rt ) ) { | 917 | if ( !fm.saveFile( *doc, rt ) ) { |
921 | QMessageBox::message(tr("Text Edit"),tr("Save Failed")); | 918 | QMessageBox::message(tr("Text Edit"),tr("Save Failed")); |
922 | return false; | 919 | return false; |
923 | } | 920 | } |
924 | 921 | ||
925 | if( filePerms ) { | 922 | if( filePerms ) { |
926 | filePermissions *filePerm; | 923 | filePermissions *filePerm; |
927 | filePerm = new filePermissions(this, tr("Permissions"),true, 0, | 924 | filePerm = new filePermissions(this, tr("Permissions"),true, 0, |
928 | (const QString &)fileNm); | 925 | (const QString &)fileNm); |
929 | QPEApplication::execDialog( filePerm ); | 926 | QPEApplication::execDialog( filePerm ); |
930 | 927 | ||
931 | delete filePerm; | 928 | delete filePerm; |
932 | } | 929 | } |
933 | editor->setEdited( false); | 930 | editor->setEdited( false); |
934 | edited1 = false; | 931 | edited1 = false; |
935 | edited = false; | 932 | edited = false; |