[LTP] [PATCH 5/5] syscalls/fanotify10: added support for FAN_OPEN_EXEC mask
Matthew Bobrowski
mbobrowski@mbobrowski.org
Tue Jan 22 23:36:41 CET 2019
Additional test cases have been added in order to increase the overall
test coverage for the newly implemented FAN_OPEN_EXEC event mask.
Signed-off-by: Matthew Bobrowski <mbobrowski@mbobrowski.org>
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
---
testcases/kernel/syscalls/fanotify/fanotify10.c | 157 ++++++++++++++++++++----
1 file changed, 133 insertions(+), 24 deletions(-)
diff --git a/testcases/kernel/syscalls/fanotify/fanotify10.c b/testcases/kernel/syscalls/fanotify/fanotify10.c
index 820c50a8a..2431a9b29 100644
--- a/testcases/kernel/syscalls/fanotify/fanotify10.c
+++ b/testcases/kernel/syscalls/fanotify/fanotify10.c
@@ -22,9 +22,11 @@
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/wait.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
+#include <stdlib.h>
#include <sys/mount.h>
#include <sys/syscall.h>
#include "tst_test.h"
@@ -56,11 +58,18 @@ static char event_buf[EVENT_BUF_LEN];
#define MNT2_PATH "mntpoint"
#define FILE_NAME "testfile"
#define FILE2_NAME "testfile2"
+#define TEST_APP "fanotify_child"
+#define TEST_APP2 "fanotify_child2"
#define FILE_PATH MOUNT_PATH"/"FILE_NAME
#define FILE2_PATH MOUNT_PATH"/"FILE2_NAME
+#define FILE_EXEC_PATH MOUNT_PATH"/"TEST_APP
+#define FILE2_EXEC_PATH MOUNT_PATH"/"TEST_APP2
#define FILE_MNT2 MNT2_PATH"/"FILE_NAME
#define FILE2_MNT2 MNT2_PATH"/"FILE2_NAME
+#define FILE_EXEC_PATH2 MNT2_PATH"/"TEST_APP
+#define FILE2_EXEC_PATH2 MNT2_PATH"/"TEST_APP2
+static pid_t child_pid;
static int bind_mount_created;
enum {
@@ -82,56 +91,109 @@ static struct tcase {
const char *ignore_path;
int ignore_mark_type;
const char *event_path;
- int expect_event;
+ unsigned long long expected_mask_with_ignore;
+ unsigned long long expected_mask_without_ignore;
} tcases[] = {
{
"ignore mount events created on a specific file",
MOUNT_PATH, FANOTIFY_MOUNT,
FILE_MNT2, FANOTIFY_INODE,
- FILE_PATH, 0
+ FILE_PATH, 0, FAN_OPEN
+ },
+ {
+ "ignore exec mount events created on a specific file",
+ MOUNT_PATH, FANOTIFY_MOUNT,
+ FILE_EXEC_PATH2, FANOTIFY_INODE,
+ FILE_EXEC_PATH, FAN_OPEN_EXEC, FAN_OPEN | FAN_OPEN_EXEC
},
{
"don't ignore mount events created on another file",
MOUNT_PATH, FANOTIFY_MOUNT,
FILE_PATH, FANOTIFY_INODE,
- FILE2_PATH, 1
+ FILE2_PATH, FAN_OPEN, FAN_OPEN
+ },
+ {
+ "don't ignore exec mount events created on another file",
+ MOUNT_PATH, FANOTIFY_MOUNT,
+ FILE_EXEC_PATH, FANOTIFY_INODE,
+ FILE2_EXEC_PATH, FAN_OPEN | FAN_OPEN_EXEC,
+ FAN_OPEN | FAN_OPEN_EXEC
},
{
"ignore inode events created on a specific mount point",
FILE_PATH, FANOTIFY_INODE,
MNT2_PATH, FANOTIFY_MOUNT,
- FILE_MNT2, 0
+ FILE_MNT2, 0, FAN_OPEN
+ },
+ {
+ "ignore exec inode events created on a specific mount point",
+ FILE_EXEC_PATH, FANOTIFY_INODE,
+ MNT2_PATH, FANOTIFY_MOUNT,
+ FILE_EXEC_PATH2, FAN_OPEN_EXEC, FAN_OPEN | FAN_OPEN_EXEC
},
{
"don't ignore inode events created on another mount point",
FILE_MNT2, FANOTIFY_INODE,
MNT2_PATH, FANOTIFY_MOUNT,
- FILE_PATH, 1
+ FILE_PATH, FAN_OPEN, FAN_OPEN
+ },
+ {
+ "don't ignore exec inode events created on another mount point",
+ FILE_EXEC_PATH2, FANOTIFY_INODE,
+ MNT2_PATH, FANOTIFY_MOUNT,
+ FILE_EXEC_PATH, FAN_OPEN | FAN_OPEN_EXEC,
+ FAN_OPEN | FAN_OPEN_EXEC
},
{
"ignore fs events created on a specific file",
MOUNT_PATH, FANOTIFY_FILESYSTEM,
FILE_PATH, FANOTIFY_INODE,
- FILE_PATH, 0
+ FILE_PATH, 0, FAN_OPEN
+ },
+ {
+ "ignore exec fs events created on a specific file",
+ MOUNT_PATH, FANOTIFY_FILESYSTEM,
+ FILE_EXEC_PATH, FANOTIFY_INODE,
+ FILE_EXEC_PATH, FAN_OPEN_EXEC, FAN_OPEN | FAN_OPEN_EXEC
},
{
"don't ignore mount events created on another file",
MOUNT_PATH, FANOTIFY_FILESYSTEM,
FILE_PATH, FANOTIFY_INODE,
- FILE2_PATH, 1
+ FILE2_PATH, FAN_OPEN, FAN_OPEN
+ },
+ {
+ "don't ignore exec mount events created on another file",
+ MOUNT_PATH, FANOTIFY_FILESYSTEM,
+ FILE_EXEC_PATH, FANOTIFY_INODE,
+ FILE2_EXEC_PATH, FAN_OPEN | FAN_OPEN_EXEC,
+ FAN_OPEN | FAN_OPEN_EXEC
},
{
"ignore fs events created on a specific mount point",
MOUNT_PATH, FANOTIFY_FILESYSTEM,
MNT2_PATH, FANOTIFY_MOUNT,
- FILE_MNT2, 0
+ FILE_MNT2, 0, FAN_OPEN
+ },
+ {
+ "ignore exec fs events created on a specific mount point",
+ MOUNT_PATH, FANOTIFY_FILESYSTEM,
+ MNT2_PATH, FANOTIFY_MOUNT,
+ FILE_EXEC_PATH2, FAN_OPEN_EXEC, FAN_OPEN | FAN_OPEN_EXEC
},
{
"don't ignore fs events created on another mount point",
MOUNT_PATH, FANOTIFY_FILESYSTEM,
MNT2_PATH, FANOTIFY_MOUNT,
- FILE_PATH, 1
+ FILE_PATH, FAN_OPEN, FAN_OPEN
},
+ {
+ "don't ignore exec fs events created on another mount point",
+ MOUNT_PATH, FANOTIFY_FILESYSTEM,
+ MNT2_PATH, FANOTIFY_MOUNT,
+ FILE_EXEC_PATH, FAN_OPEN | FAN_OPEN_EXEC,
+ FAN_OPEN | FAN_OPEN_EXEC
+ }
};
static int create_fanotify_groups(unsigned int n)
@@ -153,7 +215,8 @@ static int create_fanotify_groups(unsigned int n)
/* Add mark for each group */
ret = fanotify_mark(fd_notify[p][i],
FAN_MARK_ADD | mark->flag,
- FAN_OPEN, AT_FDCWD, tc->mark_path);
+ tc->expected_mask_without_ignore,
+ AT_FDCWD, tc->mark_path);
if (ret < 0) {
if (errno == EINVAL &&
tc->mark_type == FANOTIFY_FILESYSTEM) {
@@ -161,6 +224,13 @@ static int create_fanotify_groups(unsigned int n)
"FAN_MARK_FILESYSTEM not "
"supported in kernel?");
return -1;
+ } else if (errno == EINVAL &&
+ tc->expected_mask_without_ignore &
+ FAN_OPEN_EXEC) {
+ tst_res(TCONF,
+ "FAN_OPEN_EXEC not supported "
+ "by kernel?");
+ return -1;
}
tst_brk(TBROK | TERRNO,
"fanotify_mark(%d, FAN_MARK_ADD | %s,"
@@ -203,14 +273,15 @@ static void cleanup_fanotify_groups(void)
}
}
-static void verify_event(int group, struct fanotify_event_metadata *event)
+static void verify_event(int group, struct fanotify_event_metadata *event,
+ unsigned long long expected_mask)
{
- if (event->mask != FAN_OPEN) {
+ if (event->mask != expected_mask) {
tst_res(TFAIL, "group %d got event: mask %llx (expected %llx) "
"pid=%u fd=%u", group, (unsigned long long)event->mask,
- (unsigned long long)FAN_OPEN,
+ (unsigned long long) expected_mask,
(unsigned)event->pid, event->fd);
- } else if (event->pid != getpid()) {
+ } else if (event->pid != child_pid) {
tst_res(TFAIL, "group %d got event: mask %llx pid=%u "
"(expected %u) fd=%u", group,
(unsigned long long)event->mask, (unsigned)event->pid,
@@ -222,11 +293,38 @@ static void verify_event(int group, struct fanotify_event_metadata *event)
}
}
+static int generate_event(const char *event_path,
+ unsigned long long expected_mask)
+{
+ int fd, status;
+
+ child_pid = SAFE_FORK();
+
+ if (child_pid == 0) {
+ if (expected_mask & FAN_OPEN_EXEC) {
+ SAFE_EXECL(event_path, event_path, NULL);
+ } else {
+ fd = SAFE_OPEN(event_path, O_RDONLY);
+
+ if (fd > 0)
+ SAFE_CLOSE(fd);
+ }
+
+ exit(0);
+ }
+
+ SAFE_WAITPID(child_pid, &status, 0);
+
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0)
+ return 1;
+ return 0;
+}
+
static void test_fanotify(unsigned int n)
{
struct tcase *tc = &tcases[n];
struct fanotify_mark_type *mark, *ignore_mark;
- int ret, fd;
+ int ret;
unsigned int p, i;
struct fanotify_event_metadata *event;
@@ -238,15 +336,13 @@ static void test_fanotify(unsigned int n)
mark = &fanotify_mark_types[tc->mark_type];
ignore_mark = &fanotify_mark_types[tc->ignore_mark_type];
- /*
- * generate sequence of events
- */
- fd = SAFE_OPEN(tc->event_path, O_RDONLY);
- SAFE_CLOSE(fd);
+ /* Generate event in child process */
+ if (!generate_event(tc->event_path, tc->expected_mask_with_ignore))
+ tst_brk(TBROK, "Child process terminated incorrectly");
/* First verify all groups without matching ignore mask got the event */
for (p = 0; p < FANOTIFY_PRIORITIES; p++) {
- if (p > 0 && !tc->expect_event)
+ if (p > 0 && !tc->expected_mask_with_ignore)
break;
for (i = 0; i < GROUPS_PER_PRIO; i++) {
@@ -273,14 +369,17 @@ static void test_fanotify(unsigned int n)
i, p, mark->name, ret,
event->event_len);
} else {
- verify_event(i, event);
+ verify_event(i, event, p == 0 ?
+ tc->expected_mask_without_ignore :
+ tc->expected_mask_with_ignore);
}
if (event->fd != FAN_NOFD)
SAFE_CLOSE(event->fd);
}
}
/* Then verify all groups with matching ignore mask did got the event */
- for (p = 1; p < FANOTIFY_PRIORITIES && !tc->expect_event; p++) {
+ for (p = 1; p < FANOTIFY_PRIORITIES &&
+ !tc->expected_mask_with_ignore; p++) {
for (i = 0; i < GROUPS_PER_PRIO; i++) {
ret = read(fd_notify[p][i], event_buf, EVENT_BUF_LEN);
if (ret == 0) {
@@ -316,6 +415,9 @@ static void setup(void)
SAFE_FILE_PRINTF(FILE_PATH, "1");
SAFE_FILE_PRINTF(FILE2_PATH, "1");
+
+ SAFE_CP(TEST_APP, FILE_EXEC_PATH);
+ SAFE_CP(TEST_APP, FILE2_EXEC_PATH);
}
static void cleanup(void)
@@ -326,6 +428,11 @@ static void cleanup(void)
tst_brk(TBROK | TERRNO, "bind umount failed");
}
+static const char *const resource_files[] = {
+ TEST_APP,
+ NULL
+};
+
static struct tst_test test = {
.test = test_fanotify,
.tcnt = ARRAY_SIZE(tcases),
@@ -334,7 +441,9 @@ static struct tst_test test = {
.mount_device = 1,
.mntpoint = MOUNT_PATH,
.needs_tmpdir = 1,
- .needs_root = 1
+ .needs_root = 1,
+ .forks_child = 1,
+ .resource_files = resource_files
};
#else
--
2.16.4
--
Matthew Bobrowski
More information about the ltp
mailing list