소스 검색

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 년 전
부모
커밋
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.
     C++14 spec when the size-less delete operator is defined.
   * Use EACCES instead of EWOULDBLOCK for fcntl(2) F_SETLK in dselect.
   * Use EACCES instead of EWOULDBLOCK for fcntl(2) F_SETLK in dselect.
   * Print the archive filename when dpkg cannot access it.
   * 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:
   * Perl modules:
     - Add new CTRL_REPO_RELEASE control block type to Dpkg::Control.
     - Add new CTRL_REPO_RELEASE control block type to Dpkg::Control.
     - Add new CTRL_COPYRIGHT_HEADER, CTRL_COPYRIGHT_FILES and
     - 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
 int
 archivefiles(const char *const *argv)
 archivefiles(const char *const *argv)
 {
 {
-  const char *volatile thisarg;
   const char *const *volatile argp;
   const char *const *volatile argp;
+  int i;
   jmp_buf ejbuf;
   jmp_buf ejbuf;
   enum modstatdb_rw msdbflags;
   enum modstatdb_rw msdbflags;
 
 
@@ -1440,7 +1440,7 @@ archivefiles(const char *const *argv)
   log_message("startup archives %s", cipaction->olong);
   log_message("startup archives %s", cipaction->olong);
 
 
   if (f_recursive) {
   if (f_recursive) {
-    int pi[2], nfiles, c, i, rc;
+    int pi[2], nfiles, c, rc;
     pid_t pid;
     pid_t pid;
     FILE *pf;
     FILE *pf;
     static struct varbuf findoutput;
     static struct varbuf findoutput;
@@ -1505,6 +1505,15 @@ archivefiles(const char *const *argv)
     argp= 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);
   currenttime = time(NULL);
 
 
   /* Initialize fname variables contents. */
   /* Initialize fname variables contents. */
@@ -1522,18 +1531,18 @@ archivefiles(const char *const *argv)
   ensure_diversions();
   ensure_diversions();
   ensure_statoverrides(STATDB_PARSE_NORMAL);
   ensure_statoverrides(STATDB_PARSE_NORMAL);
 
 
-  while ((thisarg = *argp++) != NULL) {
+  for (i = 0; argp[i]; i++) {
     if (setjmp(ejbuf)) {
     if (setjmp(ejbuf)) {
       pop_error_context(ehflag_bombout);
       pop_error_context(ehflag_bombout);
       if (abort_processing)
       if (abort_processing)
         break;
         break;
       continue;
       continue;
     }
     }
-    push_error_context_jump(&ejbuf, print_error_perarchive, thisarg);
+    push_error_context_jump(&ejbuf, print_error_perarchive, argp[i]);
 
 
     dpkg_selabel_load();
     dpkg_selabel_load();
 
 
-    process_archive(thisarg);
+    process_archive(argp[i]);
     onerr_abort++;
     onerr_abort++;
     m_output(stdout, _("<standard output>"));
     m_output(stdout, _("<standard output>"));
     m_output(stderr, _("<standard error>"));
     m_output(stderr, _("<standard error>"));