Просмотр исходного кода

dpkg: Check that all passed archive filenames exist before queueing them

We can prevent many bad situations by performing earlier checks on
the archives. We'll start now by checking if the passed filenames do
actually exist. And we can move some other checks here piece by piece.

Closes: #809963
Guillem Jover лет назад: 10
Родитель
Сommit
b52810ec8c
2 измененных файлов с 16 добавлено и 5 удалено
  1. 2 0
      debian/changelog
  2. 14 5
      src/archives.c

+ 2 - 0
debian/changelog

@@ -8,6 +8,8 @@ dpkg (1.18.5) UNRELEASED; urgency=medium
     C++14 spec when the size-less delete operator is defined.
   * Use EACCES instead of EWOULDBLOCK for fcntl(2) F_SETLK in dselect.
   * Print the archive filename when dpkg cannot access it.
+  * Check that all passed archive filenames to dpkg exist before queueing them.
+    Closes: #809963
   * Perl modules:
     - Add new CTRL_REPO_RELEASE control block type to Dpkg::Control.
     - Add new CTRL_COPYRIGHT_HEADER, CTRL_COPYRIGHT_FILES and

+ 14 - 5
src/archives.c

@@ -1416,8 +1416,8 @@ void cu_fileslist(int argc, void **argv) {
 int
 archivefiles(const char *const *argv)
 {
-  const char *volatile thisarg;
   const char *const *volatile argp;
+  int i;
   jmp_buf ejbuf;
   enum modstatdb_rw msdbflags;
 
@@ -1440,7 +1440,7 @@ archivefiles(const char *const *argv)
   log_message("startup archives %s", cipaction->olong);
 
   if (f_recursive) {
-    int pi[2], nfiles, c, i, rc;
+    int pi[2], nfiles, c, rc;
     pid_t pid;
     FILE *pf;
     static struct varbuf findoutput;
@@ -1505,6 +1505,15 @@ archivefiles(const char *const *argv)
     argp= argv;
   }
 
+  /* Perform some sanity checks on the passed archives. */
+  for (i = 0; argp[i]; i++) {
+    struct stat st;
+
+    /* We need the filename to exist. */
+    if (stat(argp[i], &st) < 0)
+      ohshite(_("cannot access archive '%s'"), argp[i]);
+  }
+
   currenttime = time(NULL);
 
   /* Initialize fname variables contents. */
@@ -1522,18 +1531,18 @@ archivefiles(const char *const *argv)
   ensure_diversions();
   ensure_statoverrides(STATDB_PARSE_NORMAL);
 
-  while ((thisarg = *argp++) != NULL) {
+  for (i = 0; argp[i]; i++) {
     if (setjmp(ejbuf)) {
       pop_error_context(ehflag_bombout);
       if (abort_processing)
         break;
       continue;
     }
-    push_error_context_jump(&ejbuf, print_error_perarchive, thisarg);
+    push_error_context_jump(&ejbuf, print_error_perarchive, argp[i]);
 
     dpkg_selabel_load();
 
-    process_archive(thisarg);
+    process_archive(argp[i]);
     onerr_abort++;
     m_output(stdout, _("<standard output>"));
     m_output(stderr, _("<standard error>"));