From 86a633ef9aeffc040a7b828034793d056c66a191 Mon Sep 17 00:00:00 2001 From: Norbert Lange Date: Fri, 14 Feb 2020 22:15:07 +0100 Subject: dpkg: prevent important directories from being removed 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 function old new delta remove_file_array 139 231 +92 Signed-off-by: Norbert Lange Signed-off-by: Denys Vlasenko --- archival/dpkg.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'archival') diff --git a/archival/dpkg.c b/archival/dpkg.c index da77fba05..68a40bf6e 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c @@ -1204,6 +1204,27 @@ static char **create_list(const char *filename) return file_list; } +/** This tests if the filename is an "important" 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 (index_in_strings(".\0" "etc\0" "opt\0" "srv\0" "var\0" "var/lib\0", + name) >= 0) + return 1; + if (is_prefixed_with(name, "usr/")) { + name += sizeof("usr/") - 1; + if (is_prefixed_with(name, "local/")) + name += sizeof("local/") - 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 +1236,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) { -- cgit v1.2.3