[LTP] [PATCH] syscalls/inotify: New test for IN_DELETE regression

Amir Goldstein amir73il@gmail.com
Thu Feb 3 07:12:22 CET 2022


Check that files cannot be opened after IN_DELETE was reported
on them.

This test is based on the reproducer provided by Ivan Delalande
for a regression reported in kernel v5.13:
https://lore.kernel.org/linux-fsdevel/YeNyzoDM5hP5LtGW@visor/

Reported-by: Ivan Delalande <colona@arista.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---

Hi Petr,

The fix for this regression was applied to stable kernels
5.4.y, 5.10.y, 5.15.y, 5.16.y.
The mentioned git tag is only the upstream commit.
Feel free to add the stable git tags if you think they are needed.

Thanks,
Amir,

 runtest/syscalls                              |   1 +
 testcases/kernel/syscalls/inotify/.gitignore  |   1 +
 testcases/kernel/syscalls/inotify/inotify11.c | 137 ++++++++++++++++++
 3 files changed, 139 insertions(+)
 create mode 100644 testcases/kernel/syscalls/inotify/inotify11.c

diff --git a/runtest/syscalls b/runtest/syscalls
index 3b2deb64e..2f05dcfa1 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -585,6 +585,7 @@ inotify07 inotify07
 inotify08 inotify08
 inotify09 inotify09
 inotify10 inotify10
+inotify11 inotify11
 
 fanotify01 fanotify01
 fanotify02 fanotify02
diff --git a/testcases/kernel/syscalls/inotify/.gitignore b/testcases/kernel/syscalls/inotify/.gitignore
index da9bfc767..593cf6c04 100644
--- a/testcases/kernel/syscalls/inotify/.gitignore
+++ b/testcases/kernel/syscalls/inotify/.gitignore
@@ -8,3 +8,4 @@
 /inotify08
 /inotify09
 /inotify10
+/inotify11
diff --git a/testcases/kernel/syscalls/inotify/inotify11.c b/testcases/kernel/syscalls/inotify/inotify11.c
new file mode 100644
index 000000000..88ac4d2d7
--- /dev/null
+++ b/testcases/kernel/syscalls/inotify/inotify11.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (c) 2022 CTERA Networks. All Rights Reserved.
+ *
+ * Started by Amir Goldstein <amir73il@gmail.com>
+ * based on reproducer from Ivan Delalande <colona@arista.com>
+ *
+ * DESCRIPTION
+ * Test opening files after receiving IN_DELETE.
+ *
+ * Kernel v5.13 has a regression allowing files to be open after IN_DELETE.
+ *
+ * The problem has been fixed by commit:
+ *  a37d9a17f099 "fsnotify: invalidate dcache before IN_DELETE event".
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <time.h>
+#include <signal.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/syscall.h>
+
+#include "tst_test.h"
+#include "inotify.h"
+
+#if defined(HAVE_SYS_INOTIFY_H)
+#include <sys/inotify.h>
+
+/* Number of files to test */
+#define CHURN_FILES 9999
+
+#define EVENT_MAX 32
+/* Size of the event structure, not including the name */
+#define EVENT_SIZE	(sizeof(struct inotify_event))
+#define EVENT_BUF_LEN	(EVENT_MAX * (EVENT_SIZE + 16))
+
+static pid_t pid;
+
+char event_buf[EVENT_BUF_LEN];
+
+void churn(void)
+{
+	char path[10];
+	int i;
+
+	for (i = 0; i <= CHURN_FILES; ++i) {
+		snprintf(path, sizeof(path), "%d", i);
+		SAFE_FILE_PRINTF(path, "1");
+		SAFE_UNLINK(path);
+	}
+}
+
+static void verify_inotify(void)
+{
+	int nevents = 0, opened = 0;
+	struct inotify_event *event;
+	int inotify_fd;
+
+	pid = SAFE_FORK();
+	if (pid == 0) {
+		churn();
+		return;
+	}
+
+	inotify_fd = SAFE_MYINOTIFY_INIT();
+	SAFE_MYINOTIFY_ADD_WATCH(inotify_fd, ".", IN_DELETE);
+
+	while (!opened && nevents < CHURN_FILES) {
+		int i, fd, len;
+
+		len = read(inotify_fd, event_buf, EVENT_BUF_LEN);
+		if (len == -1)
+			tst_brk(TBROK | TERRNO, "read failed");
+
+		for (i = 0; i < len; i += EVENT_SIZE + event->len) {
+			event = (struct inotify_event *)&event_buf[i];
+
+			if (!(event->mask & IN_DELETE))
+				continue;
+
+			nevents++;
+
+			/* Open file after IN_DELETE should fail */
+			fd = open(event->name, O_RDONLY);
+			if (fd < 0)
+				continue;
+
+			tst_res(TFAIL, "File %s opened after IN_DELETE", event->name);
+			SAFE_CLOSE(fd);
+			opened = 1;
+			break;
+		}
+	}
+
+	SAFE_CLOSE(inotify_fd);
+
+	if (!nevents)
+		tst_res(TFAIL, "Didn't get any IN_DELETE events");
+	else if (!opened)
+		tst_res(TPASS, "Got %d IN_DELETE events", nevents);
+
+	/* Kill the child creating / deleting files and wait for it */
+	SAFE_KILL(pid, SIGKILL);
+	pid = 0;
+	SAFE_WAIT(NULL);
+}
+
+static void cleanup(void)
+{
+	if (pid) {
+		SAFE_KILL(pid, SIGKILL);
+		SAFE_WAIT(NULL);
+	}
+}
+
+static struct tst_test test = {
+	.timeout = 10,
+	.needs_tmpdir = 1,
+	.forks_child = 1,
+	.cleanup = cleanup,
+	.test_all = verify_inotify,
+	.tags = (const struct tst_tag[]) {
+		{"linux-git", "a37d9a17f099"},
+		{}
+	}
+};
+
+#else
+	TST_TEST_TCONF("system doesn't have required inotify support");
+#endif
-- 
2.35.1



More information about the ltp mailing list