Package: gs-gpl
Version: 8.01-5
Priority: minor
Tags: security patch

While doing a source code audit I've noticed a number of unsafe usage of
/tmp in some of gs-gpl's scripts. Some of they are used in distibution or
building of the package and one (ps2epsi) seems targeted at users, none of
them seem to be included in the Debian binary package which is built from
these sources. Ps2epsi, however seems to be distributed with gs-common.

As for ps2epsi, this was recently fixed in gs-common (see #278282 and 
CAN-2004-0967)

I believe this /tmp usage should be removed from the package altogether
since it might introduces security vulnerabilities in developer's build 
systems.

Attached is a proposed (untested) patch which tries to fix this issues. For 
the Tcl/tk code I've used the sample at http://wiki.tcl.tk/772, it seems 
that tcl does not provide a mktemp() implementation. Consider this patch as 
a sample, to be improved upon.

Hope this is useful, please forward it upstream.

Regards

Javier
diff -Nru gs-gpl-8.01.orig/lib/ps2epsi gs-gpl-8.01/lib/ps2epsi
--- gs-gpl-8.01.orig/lib/ps2epsi        2002-02-21 22:49:28.000000000 +0100
+++ gs-gpl-8.01/lib/ps2epsi     2005-01-20 09:09:31.000000000 +0100
@@ -1,7 +1,9 @@
 #!/bin/sh
 # $Id: ps2epsi,v 1.9 2002/02/21 21:49:28 giles Exp $
 
-tmpfile=/tmp/ps2epsi$$
+tmpfile=`mktemp -t ps2epsi.XXXXXX || tempfile --prefix=ps2epsi` || { echo "$0: 
Cannot create temporary file" >&2; exit 1; }
+trap "rm -f -- \"$tmpfile\";" 0 1 2 3 13 15
+
 
 export outfile
 
@@ -52,7 +54,6 @@
        ' U="$USERNAME$LOGNAME"  F=1 - F=2 "${infile}" >$tmpfile
 
 gs -q -dNOPAUSE -dSAFER -dDELAYSAFER -r72 -sDEVICE=bit -sOutputFile=/dev/null 
$tmpfile ps2epsi.ps $tmpfile <"${infile}" 1>&2
-rm -f $tmpfile
 
 (
 cat << BEGINEPS
diff -Nru gs-gpl-8.01.orig/toolbin/3way.tcl gs-gpl-8.01/toolbin/3way.tcl
--- gs-gpl-8.01.orig/toolbin/3way.tcl   2002-02-21 23:44:45.000000000 +0100
+++ gs-gpl-8.01/toolbin/3way.tcl        2005-01-20 09:20:34.000000000 +0100
@@ -25,7 +25,29 @@
 # produces a report for merging the olddir/branchdir changes into maindir.
 
 proc filesame {f1 f2} {
-    set t /tmp/t
+    # There is no Tcl builtin for temporary files
+    # This is taken from http://wiki.tcl.tk/772
+    switch $tcl_platform(platform) {
+       unix {
+               set tmpdir /tmp   # or even $::env(TMPDIR), at times.
+       } macintosh {
+               set tmpdir $::env(TRASH_FOLDER)  ;# a better place?
+       } default {
+               set tmpdir [pwd]
+                       catch {set tmpdir $::env(TMP)}
+               catch {set tmpdir $::env(TEMP)}
+       }
+    }
+    set t [file join $tmpdir [pid]]
+    set access [list RDWR CREAT EXCL TRUNC]
+    set perm 0600
+    if {[catch {open $t $access $perm} fid ]} {
+        # something went wrong
+        error "Could not open tempfile."
+     }
+    if {[catch {close $t} err]} {
+         error "Failed closing temporary file: $err"
+    }
     if {![catch {exec diff $f1 $f2 > $t}]} {
        return 1
     }
@@ -50,6 +72,9 @@
        break
     }
     close $in
+    if {![catch {exec rm $t}]} {
+         error "Failed removing temporary file"
+    }
     return $same
 }
 
diff -Nru gs-gpl-8.01.orig/toolbin/gsindent gs-gpl-8.01/toolbin/gsindent
--- gs-gpl-8.01.orig/toolbin/gsindent   2002-02-21 23:44:45.000000000 +0100
+++ gs-gpl-8.01/toolbin/gsindent        2005-01-20 09:21:46.000000000 +0100
@@ -21,12 +21,13 @@
 # The perl invocations work around a bug in GNU indent.
 
 if [ $# -ne 0 ]; then
+    tempfile=`mktemp -t || tempfile` || { echo "$0: Cannot create temporary 
file" >&2; exit 1; }
     for f in $*
     do
-       $0 < $f > /tmp/$$
+       $0 < $f > $tempfile
        cp -p $f $f.bak
        if ( test ! -e $f~ ) then cp -p $f $f~; fi
-       mv /tmp/$$ $f
+       mv $tempfile $f
     done
     exit
 fi
diff -Nru gs-gpl-8.01.orig/toolbin/gssubst gs-gpl-8.01/toolbin/gssubst
--- gs-gpl-8.01.orig/toolbin/gssubst    2002-02-21 23:44:45.000000000 +0100
+++ gs-gpl-8.01/toolbin/gssubst 2005-01-20 09:24:18.000000000 +0100
@@ -35,7 +35,27 @@
 }
 puts "$from => $to"
 flush stdout
-set tmp /tmp/[pid]
+switch $tcl_platform(platform) {
+       unix {
+               set tmpdir /tmp   # or even $::env(TMPDIR), at times.
+       } macintosh {
+               set tmpdir $::env(TRASH_FOLDER)  ;# a better place?
+       } default {
+               set tmpdir [pwd]
+                       catch {set tmpdir $::env(TMP)}
+               catch {set tmpdir $::env(TEMP)}
+       }
+}
+set tmp [file join $tmpdir [pid]]
+set access [list RDWR CREAT EXCL TRUNC]
+set perm 0600
+if {[catch {open $tmp $access $perm} fid ]} {
+# something went wrong
+       error "Could not open tempfile."
+}
+if {[catch {close $tmp} err]} {
+       error "Failed closing temporary file: $err"
+}
 foreach f [lreplace $argv 0 1] {
     if {![file exists $f~]} {exec cp -p $f $f~}
     exec perl -pe "s\{\\b${from}\\b\}\{${to}\}g" < $f > $tmp
diff -Nru gs-gpl-8.01.orig/toolbin/makeset.tcl gs-gpl-8.01/toolbin/makeset.tcl
--- gs-gpl-8.01.orig/toolbin/makeset.tcl        2002-08-07 01:24:47.000000000 
+0200
+++ gs-gpl-8.01/toolbin/makeset.tcl     2005-01-20 09:37:42.000000000 +0100
@@ -157,7 +157,23 @@
     set ogfonts $cwd/gnu-gs-fonts-other-$Dot.tar.gz
 
     file delete $afonts $ofonts $agfonts $ogfonts
-    set tmp /tmp/[pid].tmp
+    switch $tcl_platform(platform) {
+        unix {
+                set tmpdir /tmp   # or even $::env(TMPDIR), at times.
+        } macintosh {
+                set tmpdir $::env(TRASH_FOLDER)  ;# a better place?
+        } default {
+                set tmpdir [pwd]
+                        catch {set tmpdir $::env(TMP)}
+                catch {set tmpdir $::env(TEMP)}
+        }
+    }
+    set tmp [file join $tmpdir [pid]]
+    exec umask 077
+    if {[catch {exec mkdir $tmp}]} {
+        # something went wrong
+        error "Could not create temporary dir."
+     }
 
     licensefonts $tmp annotURWAladdin -u
     sh -c "\
@@ -346,7 +362,15 @@
 proc makehist {} {
     global Dot
 
-    set tmpname /tmp/[pid].htm
+    set tmpname [file join $tmpdir [pid] htm]
+    set access [list RDWR CREAT EXCL TRUNC]
+    set perm 0600
+    if {[catch {open $tmpname $access $perm} fid ]} {
+           error "Could not open tempfile."
+    }
+    if {[catch {close $tmpname} err]} {
+           error "Failed closing temporary file: $err"
+    }
     set news [open doc/News.htm]
     set changes [open doc/Changes.htm]
     set inum [expr int($Dot)]
@@ -379,7 +403,15 @@
     set cwd [pwd]
     set atmp $cwd/gs${Num3}.zip
     set asetup gs${Num3}.bat
-    set tmp /tmp/[pid].tmp
+    set tmp [file join $tmpdir [pid] tmp]
+    set access [list RDWR CREAT EXCL TRUNC]
+    set perm 0600
+    if {[catch {open $tmp $access $perm} fid ]} {
+           error "Could not open tempfile."
+    }
+    if {[catch {close $tmp} err]} {
+           error "Failed closing temporary file: $err"
+    }
 
     file delete $atmp $asetup $Dir
     ln-s . $Dir
diff -Nru gs-gpl-8.01.orig/toolbin/many2pdf.tcl gs-gpl-8.01/toolbin/many2pdf.tcl
--- gs-gpl-8.01.orig/toolbin/many2pdf.tcl       2002-02-21 23:44:45.000000000 
+0100
+++ gs-gpl-8.01/toolbin/many2pdf.tcl    2005-01-20 09:39:47.000000000 +0100
@@ -24,7 +24,24 @@
 # Define the file containing the list of input file names.
 set LIST_FILE_NAME /gs/show.lst
 # Define the directory where the output will be stored.
-set PDF_DIR /gs/tmp-pdf
+switch $tcl_platform(platform) {
+   unix {
+          set tmpdir /tmp   # or even $::env(TMPDIR), at times.
+   } macintosh {
+          set tmpdir $::env(TRASH_FOLDER)  ;# a better place?
+   } default {
+          set tmpdir [pwd]
+          catch {set tmpdir $::env(TMP)}
+          catch {set tmpdir $::env(TEMP)}
+   }
+}
+set PDF_DIR [file join $tmpdir [pid]]
+set perm 0600
+exec umask 077
+if {[catch {exec mkdir $PDF_DIR} ]} {
+    # something went wrong
+    error "Could not create temporary directory."
+}
 
 proc maxwaitfor {filesize} {
     return [expr $filesize / 5000 + 30]
@@ -50,8 +67,22 @@
            puts "****** $ps FAILED, DOES NOT EXIST ******"
            continue
        }
-       set script /tmp/${pid}.tcl
-       set status /tmp/${pid}.out
+       set script [file join $tmpdir [pid] .tcl ]
+       set status [file join $tmpdir [pid] .out ]
+       set access [list RDWR CREAT EXCL TRUNC]
+       set perm 0600
+       if {[catch {open $script $access $perm} fid ]} {
+               error "Could not open tempfile."
+       }
+       if {[catch {close $script} err]} {
+               error "Failed closing temporary file: $err"
+       }
+       if {[catch {open $status $access $perm} fid ]} {
+               error "Could not open tempfile."
+       }
+       if {[catch {close $status} err]} {
+               error "Failed closing temporary file: $err"
+       }
        set tmp [open $script w]
        puts $tmp "\
        set tmp \[open $status w\]
diff -Nru gs-gpl-8.01.orig/toolbin/pre.tcl gs-gpl-8.01/toolbin/pre.tcl
--- gs-gpl-8.01.orig/toolbin/pre.tcl    2002-03-29 01:44:34.000000000 +0100
+++ gs-gpl-8.01/toolbin/pre.tcl 2005-01-20 09:34:32.000000000 +0100
@@ -183,12 +183,31 @@
        lappend doclist $d
     }
 }
+switch $tcl_platform(platform) {
+     unix {
+         set tmpdir /tmp   # or even $::env(TMPDIR), at times.
+     } macintosh {
+         set tmpdir $::env(TRASH_FOLDER)  ;# a better place?
+     } default {
+         set tmpdir [pwd]
+         catch {set tmpdir $::env(TMP)}
+         catch {set tmpdir $::env(TEMP)}
+     }
+}
 
 if {$argv == {update}} {
        # Update dates in .htm and .1 files.
     proc updoc {doc before after} {
-       set tmpfile /tmp/[pid]
-       catch {file delete $tmpfile}
+        set tmpfile [file join $tmpdir [pid]]
+        set access [list RDWR CREAT EXCL TRUNC]
+        set perm 0600
+        if {[catch {open $tempfile $access $perm} fid ]} {
+             # something went wrong
+             error "Could not open tempfile."
+        }
+        if {[catch {close $t} err]} {
+             error "Failed closing temporary file: $err"
+        }
        exec perl -pwe "s{$before}{$after}" < $doc > $tmpfile
        file rename -force $tmpfile $doc
     }

Attachment: signature.asc
Description: Digital signature

Reply via email to