[LTP] [PATCH 5/5] syscalls/fanotify10: added support for FAN_OPEN_EXEC mask
Amir Goldstein
amir73il@gmail.com
Wed Jan 23 08:02:59 CET 2019
On Wed, Jan 23, 2019 at 12:36 AM Matthew Bobrowski
<mbobrowski@mbobrowski.org> wrote:
>
> Additional test cases have been added in order to increase the overall
> test coverage for the newly implemented FAN_OPEN_EXEC event mask.
>
A word for Jan for context (not a must to include this info in commit message)
This extension for mask/ignore_mask combination test exercises the
change that became relevant only after the addition of FAN_OPEN_EXEC:
2d10b23082a7 fanotify: return only user requested event types in 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