| commit 2aa0974d2573441bffd596b07bff8698b1f2f18c |
| Author: Florian Weimer <fweimer@redhat.com> |
| Date: Fri Oct 20 14:29:50 2023 +0200 |
| |
| elf: ldconfig should skip temporary files created by package managers |
| |
| This avoids crashes due to partially written files, after a package |
| update is interrupted. |
| |
| Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> |
| |
| Conflicts: |
| elf/ldconfig.c |
| (missing alloca removal downstream) |
| |
| diff --git a/elf/ldconfig.c b/elf/ldconfig.c |
| index 8c66d7e5426d8cc4..51de08f91fbaf093 100644 |
| |
| |
| @@ -771,6 +771,31 @@ struct dlib_entry |
| struct dlib_entry *next; |
| }; |
| |
| +/* Skip some temporary DSO files. These files may be partially written |
| + and lead to ldconfig crashes when examined. */ |
| +static bool |
| +skip_dso_based_on_name (const char *name, size_t len) |
| +{ |
| + /* Skip temporary files created by the prelink program. Files with |
| + names like these are never really DSOs we want to look at. */ |
| + if (len >= sizeof (".#prelink#") - 1) |
| + { |
| + if (strcmp (name + len - sizeof (".#prelink#") + 1, |
| + ".#prelink#") == 0) |
| + return true; |
| + if (len >= sizeof (".#prelink#.XXXXXX") - 1 |
| + && memcmp (name + len - sizeof (".#prelink#.XXXXXX") |
| + + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0) |
| + return true; |
| + } |
| + /* Skip temporary files created by RPM. */ |
| + if (memchr (name, len, ';') != NULL) |
| + return true; |
| + /* Skip temporary files created by dpkg. */ |
| + if (len > 4 && memcmp (name + len - 4, ".tmp", 4) == 0) |
| + return true; |
| + return false; |
| +} |
| |
| static void |
| search_dir (const struct dir_entry *entry) |
| @@ -849,18 +874,8 @@ search_dir (const struct dir_entry *entry) |
| continue; |
| |
| size_t len = strlen (direntry->d_name); |
| - /* Skip temporary files created by the prelink program. Files with |
| - names like these are never really DSOs we want to look at. */ |
| - if (len >= sizeof (".#prelink#") - 1) |
| - { |
| - if (strcmp (direntry->d_name + len - sizeof (".#prelink#") + 1, |
| - ".#prelink#") == 0) |
| - continue; |
| - if (len >= sizeof (".#prelink#.XXXXXX") - 1 |
| - && memcmp (direntry->d_name + len - sizeof (".#prelink#.XXXXXX") |
| - + 1, ".#prelink#.", sizeof (".#prelink#.") - 1) == 0) |
| - continue; |
| - } |
| + if (skip_dso_based_on_name (direntry->d_name, len)) |
| + continue; |
| len += strlen (entry->path) + 2; |
| if (len > file_name_len) |
| { |