diff options
author | Norbert Lange <nolange79@gmail.com> | 2020-02-14 22:15:07 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2020-06-29 14:06:40 +0200 |
commit | 86a633ef9aeffc040a7b828034793d056c66a191 (patch) | |
tree | 521bd5063d5cab6fd9effe31f857cc445ea1c91d | |
parent | a16c8ef21253d2fbb8f311ee34514cdc0a3f49a2 (diff) | |
download | busybox-w32-86a633ef9aeffc040a7b828034793d056c66a191.tar.gz busybox-w32-86a633ef9aeffc040a7b828034793d056c66a191.tar.bz2 busybox-w32-86a633ef9aeffc040a7b828034793d056c66a191.zip |
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 <nolange79@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/dpkg.c | 23 |
1 files changed, 23 insertions, 0 deletions
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) | |||
1204 | return file_list; | 1204 | return file_list; |
1205 | } | 1205 | } |
1206 | 1206 | ||
1207 | /** This tests if the filename is an "important" directory, which might be symlinked. | ||
1208 | * Debians dpkg test if directories are used by other packages, this | ||
1209 | * implementation doesn't and would remove for ex. an lib -> usr/lib symlink. | ||
1210 | */ | ||
1211 | static int is_builtin_exclude(const char *name) | ||
1212 | { | ||
1213 | if (*name++ != '/') | ||
1214 | return 0; | ||
1215 | if (index_in_strings(".\0" "etc\0" "opt\0" "srv\0" "var\0" "var/lib\0", | ||
1216 | name) >= 0) | ||
1217 | return 1; | ||
1218 | if (is_prefixed_with(name, "usr/")) { | ||
1219 | name += sizeof("usr/") - 1; | ||
1220 | if (is_prefixed_with(name, "local/")) | ||
1221 | name += sizeof("local/") - 1; | ||
1222 | } | ||
1223 | |||
1224 | return index_in_strings("bin\0" "lib\0" "lib32\0" "lib64\0" "sbin\0", | ||
1225 | name) >= 0; | ||
1226 | } | ||
1227 | |||
1207 | /* maybe i should try and hook this into remove_file.c somehow */ | 1228 | /* maybe i should try and hook this into remove_file.c somehow */ |
1208 | static int remove_file_array(char **remove_names, char **exclude_names) | 1229 | static int remove_file_array(char **remove_names, char **exclude_names) |
1209 | { | 1230 | { |
@@ -1215,6 +1236,8 @@ static int remove_file_array(char **remove_names, char **exclude_names) | |||
1215 | return 0; | 1236 | return 0; |
1216 | } | 1237 | } |
1217 | for (i = 0; remove_names[i] != NULL; i++) { | 1238 | for (i = 0; remove_names[i] != NULL; i++) { |
1239 | if (is_builtin_exclude(remove_names[i])) | ||
1240 | continue; | ||
1218 | if (exclude_names != NULL) { | 1241 | if (exclude_names != NULL) { |
1219 | for (j = 0; exclude_names[j] != NULL; j++) { | 1242 | for (j = 0; exclude_names[j] != NULL; j++) { |
1220 | if (strcmp(remove_names[i], exclude_names[j]) == 0) { | 1243 | if (strcmp(remove_names[i], exclude_names[j]) == 0) { |