Hi, I am going to 0-day NMU this bug. The attached bug fixes the issue, I backported the changes for the CVE from the upstream release as well as the data corruption.
The patch will be also: http://people.debian.org/~nion/nmu-diff/qgit_1.5.5-1_1.5.5-1.1.patch Kind regards Nico -- Nico Golde - http://ngolde.de - [EMAIL PROTECTED] - GPG: 0x73647CFF For security reasons, all text in this mail is double-rot13 encrypted.
diff -u qgit-1.5.5/debian/changelog qgit-1.5.5/debian/changelog --- qgit-1.5.5/debian/changelog +++ qgit-1.5.5/debian/changelog @@ -1,3 +1,11 @@ +qgit (1.5.5-1.1) unstable; urgency=high + + * Non-maintainer upload by testing security team. + * Fix insecure handling of temporary files (CVE-2007-4631) + and a data corruption on interfacing to stgit (Closes: #441280,#440950). + + -- Nico Golde <[EMAIL PROTECTED]> Mon, 10 Sep 2007 14:24:52 +0200 + qgit (1.5.5-1) unstable; urgency=low * New upstream release diff -u qgit-1.5.5/config.sub qgit-1.5.5/config.sub --- qgit-1.5.5/config.sub +++ qgit-1.5.5/config.sub @@ -4,7 +4,7 @@ # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, # Inc. -timestamp='2006-09-20' +timestamp='2007-06-28' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -245,12 +245,12 @@ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ + | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | mcore \ + | maxq | mb | microblaze | mcore | mep \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ @@ -324,7 +324,7 @@ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ @@ -475,8 +475,8 @@ basic_machine=craynv-cray os=-unicosmp ;; - cr16c) - basic_machine=cr16c-unknown + cr16) + basic_machine=cr16-unknown os=-elf ;; crds | unos) @@ -683,6 +683,10 @@ basic_machine=i386-pc os=-mingw32 ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; miniframe) basic_machine=m68000-convergent ;; @@ -925,6 +929,9 @@ basic_machine=sh-hitachi os=-hms ;; + sh5el) + basic_machine=sh5le-unknown + ;; sh64) basic_machine=sh64-unknown ;; @@ -1219,7 +1226,7 @@ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1414,6 +1421,9 @@ m68*-cisco) os=-aout ;; + mep-*) + os=-elf + ;; mips*-cisco) os=-elf ;; diff -u qgit-1.5.5/config.guess qgit-1.5.5/config.guess --- qgit-1.5.5/config.guess +++ qgit-1.5.5/config.guess @@ -4,7 +4,7 @@ # 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, # Inc. -timestamp='2006-07-02' +timestamp='2007-07-22' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -161,6 +161,7 @@ arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched @@ -329,7 +330,7 @@ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; - i86pc:SunOS:5.*:*) + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) @@ -780,7 +781,7 @@ i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; - i*:MINGW*:*) + *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) @@ -790,12 +791,15 @@ i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; - x86:Interix*:[3456]*) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - EM64T:Interix*:[3456]*) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; @@ -950,6 +954,9 @@ x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; + xtensa:Linux:*:*) + echo xtensa-unknown-linux-gnu + exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent @@ -1208,6 +1215,15 @@ SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; only in patch2: unchanged: --- qgit-1.5.5.orig/src/common.h +++ qgit-1.5.5/src/common.h @@ -234,7 +234,8 @@ // misc helpers bool stripPartialParaghraps(SCRef src, QString* dst, QString* prev); - bool writeToFile(SCRef fileName, SCRef data); + bool writeToFile(SCRef fileName, SCRef data, bool setExecutable = false); + bool writeToFile(SCRef fileName, const QByteArray& data, bool setExecutable = false); bool readFromFile(SCRef fileName, QString& data); // cache file only in patch2: unchanged: --- qgit-1.5.5.orig/src/git.h +++ qgit-1.5.5/src/git.h @@ -112,7 +112,7 @@ bool commitFiles(SCList files, SCRef msg); bool makeTag(SCRef sha, SCRef tag, SCRef msg); bool deleteTag(SCRef sha); - bool applyPatchFile(SCRef patchPath, bool commit, bool fold, bool sign); + bool applyPatchFile(SCRef patchPath,bool fold, bool sign); bool resetCommits(int parentDepth); bool stgCommit(SCList selFiles, SCRef msg, SCRef patchName, bool fold); bool stgPush(SCRef sha); only in patch2: unchanged: --- qgit-1.5.5.orig/src/revsview.cpp +++ qgit-1.5.5/src/revsview.cpp @@ -274,8 +274,9 @@ m()->statusBar()->message(tmp); return; } - bool commit, fold; - if (!m()->askApplyPatchParameters(&commit, &fold)) + + bool workDirOnly, fold; + if (!m()->askApplyPatchParameters(&workDirOnly, &fold)) return; // ok, let's go @@ -310,7 +311,7 @@ break; } SCRef fn(dr.absFilePath(dr[0])); - if (!git->applyPatchFile(fn, commit, fold, Git::optDragDrop)) + if (!git->applyPatchFile(fn, fold, Git::optDragDrop)) break; dr.remove(fn); @@ -322,7 +323,7 @@ else m()->statusBar()->message("Failed to import revision " + QString::number(revNum--)); - if (!commit && (revNum > 0)) + if (workDirOnly && (revNum > 0)) git->resetCommits(revNum); dr.rmdir(dr.absPath()); // 'dr' must be already empty only in patch2: unchanged: --- qgit-1.5.5.orig/src/mainimpl.cpp +++ qgit-1.5.5/src/mainimpl.cpp @@ -1315,25 +1315,22 @@ QApplication::restoreOverrideCursor(); } -bool MainImpl::askApplyPatchParameters(bool* commit, bool* fold) { +bool MainImpl::askApplyPatchParameters(bool* workDirOnly, bool* fold) { - int ret = QMessageBox::question(this, "Apply Patch", - "Do you want to commit or just to apply changes to " - "working directory?", "&Cancel", "&Working dir", "&Commit", 0, 0); - if (ret == 0) - return false; - - *commit = (ret == 2); - *fold = false; - if (*commit && git->isStGITStack()) { + int ret = 0; + if (!git->isStGITStack()) { + ret = QMessageBox::question(this, "Apply Patch", + "Do you want to commit or just to apply changes to " + "working directory?", "&Cancel", "&Working dir", "&Commit", 0, 0); + *workDirOnly = (ret == 1); + *fold = false; + } else { ret = QMessageBox::question(this, "Apply Patch", "Do you want to " "import or fold the patch?", "&Cancel", "&Fold", "&Import", 0, 0); - if (ret == 0) - return false; - + *workDirOnly = false; *fold = (ret == 1); } - return true; + return (ret != 0); } void MainImpl::ActMailApplyPatch_activated() { @@ -1348,13 +1345,14 @@ QFileInfo f(patchName); settings.writeEntry(APP_KEY + FP_DIR_KEY, f.dirPath(true)); - bool commit, fold; - if (!askApplyPatchParameters(&commit, &fold)) + bool workDirOnly, fold; + if (!askApplyPatchParameters(&workDirOnly, &fold)) return; QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); - if (git->applyPatchFile(f.absFilePath(), commit, fold, !Git::optDragDrop) && !commit) + bool ok = git->applyPatchFile(f.absFilePath(), fold, !Git::optDragDrop); + if (workDirOnly && ok) git->resetCommits(1); QApplication::restoreOverrideCursor(); only in patch2: unchanged: --- qgit-1.5.5.orig/src/git.cpp +++ qgit-1.5.5/src/git.cpp @@ -471,7 +471,7 @@ MyProcess* Git::runAsScript(SCRef runCmd, QObject* receiver, SCRef buf) { const QString scriptFile(workDir + "/qgit_script.sh"); - if (!writeToFile(scriptFile, runCmd)) + if (!writeToFile(scriptFile, runCmd, true)) return NULL; chmod(scriptFile, 0755); @@ -1053,13 +1053,16 @@ return run(runCmd); } -bool Git::applyPatchFile(SCRef patchPath, bool commit, bool fold, bool isDragDrop) { +bool Git::applyPatchFile(SCRef patchPath,bool fold, bool isDragDrop) { - if (commit && isStGIT) { - if (fold) - return run("stg fold " + quote(patchPath)); - - return run("stg import --mail " + quote(patchPath)); + if (isStGIT) { + if (fold) { + bool ok = run("stg fold " + quote(patchPath)); // merge in working dir + if (ok) + ok = run("stg refresh"); // update top patch + return ok; + } else + return run("stg import --mail " + quote(patchPath)); } QString runCmd("git am --utf8 --3way "); if (isDragDrop) only in patch2: unchanged: --- qgit-1.5.5.orig/src/dataloader.cpp +++ qgit-1.5.5/src/dataloader.cpp @@ -6,6 +6,9 @@ Copyright: See COPYING file that comes with this distribution */ + +#include <stdlib.h> // rand() +#include <time.h> // time() #include <sys/types.h> // used by chmod() #include <sys/stat.h> // used by chmod() #include <qcstring.h> @@ -233,25 +236,43 @@ } bool DataLoader::doStart(SCList args, SCRef wd) { - - // ensure unique names for our DataLoader instance file - dataFileName = "/qgit_" + QString::number((ulong)this) + ".txt"; - scriptFileName = "/qgit_" + QString::number((ulong)this) + ".sh"; - // create a script to redirect 'git rev-list' stdout to dataFile - QDir dir("/tmp"); // use a tmpfs mounted filesystem if available - bool foundTmpDir = (dir.exists() && dir.isReadable()); - scriptFileName.prepend(foundTmpDir ? "/tmp" : wd); - dataFileName.prepend(foundTmpDir ? "/tmp" : wd); + const QString tmpfsDir("/tmp"); + QDir dir(tmpfsDir); // use a tmpfs mounted filesystem if available + bool useTmpfsDir = (dir.exists() && dir.isReadable()); + bool noexec; + srand (time(NULL)); + do { + do { + // ensure unique names for our DataLoader instance file + QString t = QString::number(rand(), 16); + dataFileName = "/qgit_" + t + ".txt"; + scriptFileName = "/qgit_" + t + ".sh"; + dataFileName.prepend(useTmpfsDir ? tmpfsDir : wd); + scriptFileName.prepend(useTmpfsDir ? tmpfsDir : wd); + } while (dir.exists(dataFileName) || dir.exists(scriptFileName)); + + /* in case we use '/tmp' be sure is writable and executable */ + noexec = ( useTmpfsDir && + !QGit::writeToFile(scriptFileName, "test exec bit", true)); + if (noexec) + useTmpfsDir = false; + } while (noexec); + dataFile.setName(dataFileName); - QString runCmd(args.join(" ") + " > " + dataFileName); + QString runCmd; + FOREACH_SL (it, args) + if ((*it).contains(' ')) + runCmd.append("\"" + *it + "\" "); + else + runCmd.append(*it + " "); + + runCmd.append("> " + dataFileName); runCmd.append(" &\necho $!\nwait"); // we want to read git-rev-list PID runCmd.prepend("cd " + wd + "\n"); - - if (!QGit::writeToFile(scriptFileName, runCmd)) + if (!QGit::writeToFile(scriptFileName, runCmd, true)) return false; - chmod(scriptFileName, 0755); // set script as executable proc = git->runAsync(scriptFileName, this, ""); return (proc != NULL); } only in patch2: unchanged: --- qgit-1.5.5.orig/src/namespace_def.cpp +++ qgit-1.5.5/src/namespace_def.cpp @@ -11,8 +11,12 @@ data in each file where QGit namespace is included. */ + +#include <sys/types.h> // used by chmod() +#include <sys/stat.h> // used by chmod() #include <qsettings.h> #include <qfile.h> +#include <qdir.h> #include "common.h" // minimum git version required @@ -123,9 +127,9 @@ return true; } -bool QGit::writeToFile(SCRef fileName, SCRef data) { +bool QGit::writeToFile(SCRef fileName, SCRef data, bool setExecutable) { - QFile file(QFile::encodeName(fileName)); + QFile file(fileName); if (!file.open(IO_WriteOnly)) { dbp("ERROR: unable to write file %1", fileName); return false; @@ -133,6 +137,29 @@ QTextStream stream(&file); stream << data; file.close(); + if (setExecutable) { + if (chmod(fileName, 0755)) { + dbp("ERROR: unable to set executable bit to file %1", fileName); + QDir d; + d.remove(fileName); + return false; + } + } + return true; +} + +bool QGit::writeToFile(SCRef fileName, const QByteArray& data, bool setExecutable) { + + QFile file(fileName); + if (!file.open(IO_WriteOnly)) { + dbp("ERROR: unable to write file %1", fileName); + return false; + } + QDataStream stream(&file); + stream.writeRawBytes(data.data(), data.size()); + file.close(); + if (setExecutable) + chmod(fileName, 0755); return true; }
pgpUee3j25ivM.pgp
Description: PGP signature