aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2018-08-08 15:06:29 +0200
committerDmitry Vyukov <dvyukov@google.com>2018-08-08 15:06:29 +0200
commitd46deef51c0809429c414eea99566b82b6d5fbbf (patch)
treea7effa9baf5c0d8134a29713fa145b9b81aa7924
parent3653592507eab917724112e026d4241745e0dd98 (diff)
downloadsyzkaller-d46deef51c0809429c414eea99566b82b6d5fbbf.tar.gz
executor: clean up immutable files
Fixes #650
-rw-r--r--executor/common_linux.h12
-rw-r--r--pkg/csource/generated.go11
-rw-r--r--sys/linux/test/file_immutable7
3 files changed, 30 insertions, 0 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h
index aab854d1c..2a1d14e2b 100644
--- a/executor/common_linux.h
+++ b/executor/common_linux.h
@@ -1734,6 +1734,7 @@ static int do_sandbox_namespace(void)
#if SYZ_EXECUTOR || SYZ_REPEAT && SYZ_USE_TMP_DIR
#include <dirent.h>
#include <errno.h>
+#include <linux/fs.h>
#include <string.h>
#include <sys/mount.h>
@@ -1783,6 +1784,17 @@ retry:
debug("unlink(%s)\n", filename);
if (unlink(filename) == 0)
break;
+ if (errno == EPERM) {
+ // Try to reset FS_XFLAG_IMMUTABLE.
+ int fd = open(filename, O_RDONLY);
+ if (fd != -1) {
+ struct fsxattr attr = {0};
+ if (ioctl(fd, FS_IOC_FSSETXATTR, &attr) == 0)
+ debug("reset FS_XFLAG_IMMUTABLE\n");
+ close(fd);
+ continue;
+ }
+ }
if (errno == EROFS) {
debug("ignoring EROFS\n");
break;
diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go
index f25ee1998..c68c99cc2 100644
--- a/pkg/csource/generated.go
+++ b/pkg/csource/generated.go
@@ -3216,6 +3216,7 @@ static int do_sandbox_namespace(void)
#if SYZ_EXECUTOR || SYZ_REPEAT && SYZ_USE_TMP_DIR
#include <dirent.h>
#include <errno.h>
+#include <linux/fs.h>
#include <string.h>
#include <sys/mount.h>
static void remove_dir(const char* dir)
@@ -3254,6 +3255,16 @@ retry:
debug("unlink(%s)\n", filename);
if (unlink(filename) == 0)
break;
+ if (errno == EPERM) {
+ int fd = open(filename, O_RDONLY);
+ if (fd != -1) {
+ struct fsxattr attr = {0};
+ if (ioctl(fd, FS_IOC_FSSETXATTR, &attr) == 0)
+ debug("reset FS_XFLAG_IMMUTABLE\n");
+ close(fd);
+ continue;
+ }
+ }
if (errno == EROFS) {
debug("ignoring EROFS\n");
break;
diff --git a/sys/linux/test/file_immutable b/sys/linux/test/file_immutable
new file mode 100644
index 000000000..8c22eb857
--- /dev/null
+++ b/sys/linux/test/file_immutable
@@ -0,0 +1,7 @@
+# This creates an immutable file, which we previously failed to clean up.
+# Note: the ioctl only works on ext4 but not on tmpfs, so it will fail with namespace sandbox.
+# It also requires root, so will fail with setuid.
+# requires: -sandbox=namespace -sandbox=setuid
+
+r0 = openat(0xffffffffffffff9c, &(0x7f0000000000)='./file0\x00', 0x26e1, 0x0)
+ioctl$FS_IOC_FSSETXATTR(r0, 0x40086602, &(0x7f0000000100)={0x17e})