Procházet zdrojové kódy

dpkg: Never try to remove the root directory or its backups

It should never have backups around, and we should never try to remove
it as it can never be removed anyway.

This also causes problems with setups where the root directory is
read-only with a read-write overlay or a symlink farm.

Requested-by: sepero111@gmx.com
Guillem Jover před 12 roky
rodič
revize
a1920c1323
3 změnil soubory, kde provedl 25 přidání a 10 odebrání
  1. 3 0
      debian/changelog
  2. 14 10
      src/remove.c
  3. 8 0
      src/unpack.c

+ 3 - 0
debian/changelog

@@ -86,6 +86,9 @@ dpkg (1.17.14) UNRELEASED; urgency=low
   * Normalize instdir in dpkg by removing trailing «/» and «/.». This gets
     rid of several inconsistencies and doubled «/» in syscalls and output
     messages.
+  * Never try to remove the root directory or its backups. There's no point in
+    it, and makes life more difficult for a read-only root with a read-write
+    overlay or a symlink farm. Requested by sepero111@gmx.com.
 
   [ Raphaël Hertzog ]
   * Explain better in deb-triggers(5) why interest/activate-noawait should be

+ 14 - 10
src/remove.c

@@ -303,6 +303,13 @@ removal_bulk_remove_files(struct pkginfo *pkg)
         }
         if (dir_is_used_by_others(namenode, pkg))
           continue;
+
+        if (strcmp(usenode->name, "/.") == 0) {
+          debug(dbg_eachfiledetail,
+                "removal_bulk '%s' root directory, cannot remove", fnvb.buf);
+          push_leftover(&leftover, namenode);
+          continue;
+        }
       }
 
       trig_path_activate(usenode, pkg);
@@ -336,11 +343,6 @@ removal_bulk_remove_files(struct pkginfo *pkg)
                 pkg_name(pkg, pnaw_nonambig), namenode->name, strerror(errno));
         push_leftover(&leftover,namenode);
         continue;
-      } else if (errno == EINVAL && strcmp(usenode->name, "/.") == 0) {
-        debug(dbg_eachfiledetail, "removal_bulk '%s' root directory, cannot remove",
-              fnvb.buf);
-        push_leftover(&leftover, namenode);
-        continue;
       }
       if (errno != ENOTDIR) ohshite(_("cannot remove `%.250s'"),fnvb.buf);
       debug(dbg_eachfiledetail, "removal_bulk unlinking '%s'", fnvb.buf);
@@ -410,6 +412,13 @@ static void removal_bulk_remove_leftover_dirs(struct pkginfo *pkg) {
       }
       if (dir_is_used_by_others(namenode, pkg))
         continue;
+
+      if (strcmp(usenode->name, "/.") == 0) {
+        debug(dbg_eachfiledetail,
+              "removal_bulk '%s' root directory, cannot remove", fnvb.buf);
+        push_leftover(&leftover, namenode);
+        continue;
+      }
     }
 
     trig_path_activate(usenode, pkg);
@@ -427,11 +436,6 @@ static void removal_bulk_remove_leftover_dirs(struct pkginfo *pkg) {
               pkg_name(pkg, pnaw_nonambig), namenode->name, strerror(errno));
       push_leftover(&leftover,namenode);
       continue;
-    } else if (errno == EINVAL && strcmp(usenode->name, "/.") == 0) {
-      debug(dbg_eachfiledetail, "removal_bulk '%s' root directory, cannot remove",
-            fnvb.buf);
-      push_leftover(&leftover, namenode);
-      continue;
     }
     if (errno != ENOTDIR) ohshite(_("cannot remove `%.250s'"),fnvb.buf);
 

+ 8 - 0
src/unpack.c

@@ -1042,6 +1042,10 @@ void process_archive(const char *filename) {
     if (S_ISDIR(oldfs.st_mode)) {
       trig_path_activate(usenode, pkg);
 
+      /* Do not try to remove the root directory. */
+      if (strcmp(usenode->name, "/.") == 0)
+        continue;
+
       if (rmdir(fnamevb.buf)) {
 	warning(_("unable to delete old directory '%.250s': %s"),
 	        namenode->name, strerror(errno));
@@ -1445,6 +1449,10 @@ void process_archive(const char *filename) {
 
     usenode = namenodetouse(cfile->namenode, pkg, &pkg->installed);
 
+    /* Do not try to remove backups for the root directory. */
+    if (strcmp(usenode->name, "/.") == 0)
+      continue;
+
     varbuf_trunc(&fnametmpvb, fnameidlu);
     varbuf_add_str(&fnametmpvb, usenode->name);
     varbuf_add_str(&fnametmpvb, DPKGTEMPEXT);