]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
utils: allow removal of immutable files 3322/head
authorChristian Brauner <christian.brauner@ubuntu.com>
Mon, 23 Mar 2020 15:06:40 +0000 (16:06 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Mon, 23 Mar 2020 15:06:40 +0000 (16:06 +0100)
Closes #3185.
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/utils.c

index 25ae794b0d9756c8ff646ebff6ddbe9407cbf225..c34519084db466b921aee6851a65191cafec244c 100644 (file)
@@ -19,6 +19,8 @@
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/mount.h>
+/* Needs to be after sys/mount.h header */
+#include <linux/fs.h>
 #include <sys/param.h>
 #include <sys/prctl.h>
 #include <sys/stat.h>
@@ -129,9 +131,28 @@ static int _recursive_rmdir(const char *dirname, dev_t pdev,
                        if (_recursive_rmdir(pathname, pdev, exclude, level + 1, onedev) < 0)
                                failed = 1;
                } else {
-                       if (unlink(pathname) < 0) {
-                               SYSERROR("Failed to delete \"%s\"", pathname);
-                               failed = 1;
+                       ret = unlink(pathname);
+                       if (ret < 0) {
+                               __do_close int fd = -EBADF;
+
+                               fd = open(pathname, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
+                               if (fd >= 0) {
+                                       /* The file might be marked immutable. */
+                                       int attr = 0;
+                                       ret = ioctl(fd, FS_IOC_GETFLAGS, &attr);
+                                       if (ret < 0)
+                                               SYSERROR("Failed to retrieve file flags");
+                                       attr &= ~FS_IMMUTABLE_FL;
+                                       ret = ioctl(fd, FS_IOC_SETFLAGS, &attr);
+                                       if (ret < 0)
+                                               SYSERROR("Failed to set file flags");
+                               }
+
+                               ret = unlink(pathname);
+                               if (ret < 0) {
+                                       SYSERROR("Failed to delete \"%s\"", pathname);
+                                       failed = 1;
+                               }
                        }
                }
        }