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;
 }
 

Attachment: pgpUee3j25ivM.pgp
Description: PGP signature

Reply via email to