]> git.ipfire.org Git - people/stevee/pakfire.git/blobdiff - src/libpakfire/file.c
Hardening: Declare content of /usr/lib/grub as firmware files
[people/stevee/pakfire.git] / src / libpakfire / file.c
index f49e9a9aef8fbeee087b84711fe3ed4b834370d6..819587ef0138f20042a1b65f13044c2640a473ba 100644 (file)
@@ -1334,7 +1334,9 @@ int pakfire_file_compute_digests(struct pakfire_file* file, const int types) {
        return __pakfire_file_compute_digests(file, &file->digests, types);
 }
 
-int pakfire_file_remove(struct pakfire_file* file) {
+static int pakfire_file_remove(struct pakfire_file* file) {
+       int r;
+
        if (!*file->abspath) {
                errno = EINVAL;
                return 1;
@@ -1342,22 +1344,51 @@ int pakfire_file_remove(struct pakfire_file* file) {
 
        DEBUG(file->pakfire, "Removing %s...\n", file->path);
 
-       int r = remove(file->abspath);
-       if (r) {
-               switch (errno) {
-                       // Ignore when we could not remove directories
-                       case ENOTEMPTY:
-                               return 0;
-
-                       // Ignore if the file didn't exist
-                       case ENOENT:
-                               return 0;
-
-                       default:
-                               break;
-               }
+       switch (file->st.st_mode & S_IFMT) {
+               // Call rmdir() for directories
+               case S_IFDIR:
+                       r = rmdir(file->abspath);
+                       if (r) {
+                               switch (errno) {
+                                       // Ignore when the directory is not empty
+                                       case ENOTEMPTY:
+                                               r = 0;
+                                               break;
+
+                                       // Ignore if the directory didn't exist
+                                       case ENOENT:
+                                               r = 0;
+                                               break;
+
+                                       // Ignore if the directory changed type
+                                       case ENOTDIR:
+                                               r = 0;
+                                               break;
+
+                                       // Log anything else
+                                       default:
+                                               ERROR(file->pakfire, "Could not remove directory %s: %m\n", file->path);
+                                               break;
+                               }
+                       }
+                       break;
 
-               ERROR(file->pakfire, "Could not remove %s (%s): %m\n", file->path, file->abspath);
+               // Call unlink() for everything else
+               default:
+                       r = unlink(file->abspath);
+                       if (r) {
+                               switch (errno) {
+                                       // Ignore if the file didn't exist
+                                       case ENOENT:
+                                               r = 0;
+                                               break;
+
+                                       default:
+                                               ERROR(file->pakfire, "Could not remove %s: %m\n", file->path);
+                                               break;
+                               }
+                       }
+                       break;
        }
 
        return r;
@@ -1478,6 +1509,7 @@ static const struct pattern {
        { "*.pm", PAKFIRE_FILE_PERL },
        { "*.pc", PAKFIRE_FILE_PKGCONFIG },
        { "/usr/lib/firmware/*", PAKFIRE_FILE_FIRMWARE },
+       { "/usr/lib/grub/*", PAKFIRE_FILE_FIRMWARE },
        { "/usr/lib*/ld-*.so*", PAKFIRE_FILE_RUNTIME_LINKER },
        { NULL },
 };
@@ -1620,7 +1652,7 @@ int pakfire_file_matches_class(struct pakfire_file* file, const int class) {
        It will try to delete any parent directories as well and ignore if directories
        cannot be deleted because they might contain other files
 */
-int pakfire_file_cleanup(struct pakfire_file* file) {
+int pakfire_file_cleanup(struct pakfire_file* file, int flags) {
        char path[PATH_MAX];
 
        // Try removing the file
@@ -1628,29 +1660,32 @@ int pakfire_file_cleanup(struct pakfire_file* file) {
        if (r)
                return r;
 
-       // Create a working copy of abspath
-       r = pakfire_string_set(path, file->abspath);
-       if (r)
-               return r;
+       // Try to tidy up afterwards
+       if (flags & PAKFIRE_FILE_CLEANUP_TIDY) {
+               // Create a working copy of abspath
+               r = pakfire_string_set(path, file->abspath);
+               if (r)
+                       return r;
 
-       // See how many levels this file has
-       int levels = pakfire_file_levels(file);
+               // See how many levels this file has
+               int levels = pakfire_file_levels(file);
 
-       // Walk all the way up and remove all parent directories if possible
-       while (--levels) {
-               dirname(path);
+               // Walk all the way up and remove all parent directories if possible
+               while (--levels) {
+                       dirname(path);
 
-               // Break if path is suddenly empty
-               if (!*path)
-                       break;
+                       // Break if path is suddenly empty
+                       if (!*path)
+                               break;
 
-               DEBUG(file->pakfire, "Trying to remove parent directory %s\n", path);
+                       DEBUG(file->pakfire, "Trying to remove parent directory %s\n", path);
 
-               r = rmdir(path);
+                       r = rmdir(path);
 
-               // Break on any error
-               if (r)
-                       break;
+                       // Break on any error
+                       if (r)
+                               break;
+               }
        }
 
        return 0;