Browse Source

Use mkdtemp and path_make_temp_template instead of tempnam and tmpnam

Those two functions are deprecated, produce warnings at link time,
and should not be used as they are cause of possible race conditions.

As a side effect we don't need to ensure the path is not existing as
mkdtemp has done that for us, which slightly simplifies the code.
Guillem Jover 16 years ago
parent
commit
ffccc65580
3 changed files with 23 additions and 19 deletions
  1. 3 0
      debian/changelog
  2. 5 10
      dpkg-deb/info.c
  3. 15 9
      src/processarc.c

+ 3 - 0
debian/changelog

@@ -108,6 +108,9 @@ dpkg (1.15.6) UNRELEASED; urgency=low
   * Update debian/copyright.
   * Use Debian instead of ‘Debian GNU/Linux’ when referring to the
     distribution.
+  * On dpkg --no-act with --install, --unpack or --record-avail, and
+    dpkg-deb --info or --field use mkdtemp() to create a temporary directory
+    instead of insecure tempnam() or tmpnam() functions.
 
   [ Modestas Vainius ]
   * Implement symbol patterns (Closes: #563752). From now on, it is possible to

+ 5 - 10
dpkg-deb/info.c

@@ -41,6 +41,7 @@
 #include <dpkg/dpkg-db.h>
 #include <dpkg/pkg-format.h>
 #include <dpkg/buffer.h>
+#include <dpkg/path.h>
 #include <dpkg/subproc.h>
 #include <dpkg/myopt.h>
 
@@ -69,21 +70,15 @@ static void info_prepare(const char *const **argvp,
                          const char **directoryp,
                          int admininfo) {
   char *dbuf;
-  pid_t c1;
   
   *debarp= *(*argvp)++;
   if (!*debarp) badusage(_("--%s needs a .deb filename argument"),cipaction->olong);
-  /* This creates a temporary directory, so ignore the warning. */
-  if ((dbuf= tempnam(NULL,"dpkg")) == NULL)
-    ohshite(_("failed to make temporary directoryname"));
+
+  dbuf = mkdtemp(path_make_temp_template("dpkg"));
+  if (!dbuf)
+    ohshite(_("failed to create temporary directory"));
   *directoryp= dbuf;
 
-  c1 = subproc_fork();
-  if (!c1) {
-    execlp(RM, "rm", "-rf", dbuf, NULL);
-    ohshite(_("failed to exec rm -rf"));
-  }
-  subproc_wait_check(c1, "rm -rf", 0);
   push_cleanup(cu_info_prepare, -1, NULL, 0, 1, (void *)dbuf);
   extracthalf(*debarp, dbuf, "mx", admininfo);
 }

+ 15 - 9
src/processarc.c

@@ -40,6 +40,7 @@
 #include <dpkg/i18n.h>
 #include <dpkg/dpkg.h>
 #include <dpkg/dpkg-db.h>
+#include <dpkg/path.h>
 #include <dpkg/buffer.h>
 #include <dpkg/subproc.h>
 #include <dpkg/tarfn.h>
@@ -88,7 +89,6 @@ void process_archive(const char *filename) {
    * variables had better still exist ...
    */
   static int p1[2];
-  static char cidirtmpnambuf[L_tmpnam+100];
   static char *cidirbuf = NULL, *reasmbuf = NULL;
   static struct fileinlist *newconffiles, *newfileslist;
   static enum pkgstatus oldversionstatus;
@@ -186,10 +186,14 @@ void process_archive(const char *filename) {
     
 
   if (f_noact) {
-    cidir= cidirtmpnambuf;
-    /* We use tmpnam here, not to get a unique filename, but to get a unique directory. */
-    if (!tmpnam(cidir)) ohshite(_("unable to get unique filename for control info"));
+    if (!cidirbuf)
+      free(cidirbuf);
+    cidir = cidirbuf = mkdtemp(path_make_temp_template("dpkg"));
+    if (!cidir)
+      ohshite(_("unable to create temporary directory"));
     strcat(cidir,"/");
+
+    cidirrest = cidir + strlen(cidir);
   } else {
     /* We want it to be on the same filesystem so that we can
      * use rename(2) to install the postinst &c.
@@ -199,12 +203,14 @@ void process_archive(const char *filename) {
     cidir= cidirbuf;
     strcpy(cidir,admindir);
     strcat(cidir, "/" CONTROLDIRTMP);
-  }
-  cidirrest= cidir + strlen(cidir);
 
-  assert(*cidir && cidirrest[-1] == '/');
-  cidirrest[-1] = '\0';
-  ensure_pathname_nonexisting(cidir); cidirrest[-1]= '/';
+    cidirrest = cidir + strlen(cidir);
+
+    assert(*cidir && cidirrest[-1] == '/');
+    cidirrest[-1] = '\0';
+    ensure_pathname_nonexisting(cidir);
+    cidirrest[-1] = '/';
+  }
   
   push_cleanup(cu_cidir, ~0, NULL, 0, 2, (void *)cidir, (void *)cidirrest);
   c1 = subproc_fork();