[PATCH] dpkg: prevent important directories from being removed

Norbert Lange nolange79 at gmail.com
Fri Feb 14 21:15:07 UTC 2020


busybox will remove directory symlinks, which is at
odds with common layouts that have some of
bin/lib/lib32/lib64 symlinked.

this adds a exludelist for critcal and often symlinked
directories.

Fixes: Bug 12551

Signed-off-by: Norbert Lange <nolange79 at gmail.com>
---
 archival/dpkg.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/archival/dpkg.c b/archival/dpkg.c
index da77fba05..0aeb363a9 100644
--- a/archival/dpkg.c
+++ b/archival/dpkg.c
@@ -1204,6 +1204,26 @@ static char **create_list(const char *filename)
 	return file_list;
 }
 
+/** This tests if the filename is a base directory, which might be symlinked.
+ *  Debians dpkg test if directories are used by other packages, this
+ *  implementation doesn't and would remove for ex. an lib -> usr/lib symlink.
+ */
+static int is_builtin_exclude(const char *name)
+{
+	if (*name++ != '/')
+		return 0;
+	if (is_prefixed_with(name, "usr/")) {
+		name += sizeof("usr/") - 1;
+		if (is_prefixed_with(name, "local/"))
+			name += sizeof("local/") - 1;
+	} else if(index_in_strings(".\0" "etc\0" "opt\0" "srv\0" \
+			"var\0" "var/lib\0", name) >= 0)
+		return 1;
+
+	return index_in_strings("bin\0" "lib\0" "lib32\0" "lib64\0" "sbin\0",
+			name) >= 0;
+}
+
 /* maybe i should try and hook this into remove_file.c somehow */
 static int remove_file_array(char **remove_names, char **exclude_names)
 {
@@ -1215,6 +1235,8 @@ static int remove_file_array(char **remove_names, char **exclude_names)
 		return 0;
 	}
 	for (i = 0; remove_names[i] != NULL; i++) {
+		if (is_builtin_exclude(remove_names[i]))
+			continue;
 		if (exclude_names != NULL) {
 			for (j = 0; exclude_names[j] != NULL; j++) {
 				if (strcmp(remove_names[i], exclude_names[j]) == 0) {
-- 
2.25.0



More information about the busybox mailing list