From patchwork Thu Jun 20 09:57:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Bobrowski X-Patchwork-Id: 1119321 X-Patchwork-Delegate: petr.vorel@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=lists.linux.it (client-ip=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mbobrowski.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mbobrowski-org.20150623.gappssmtp.com header.i=@mbobrowski-org.20150623.gappssmtp.com header.b="psGeH+1+"; dkim-atps=neutral Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45Ty1c0YDKz9s4V for ; Thu, 20 Jun 2019 19:58:12 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 8EBC82988DD for ; Thu, 20 Jun 2019 11:58:09 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-2.smtp.seeweb.it (in-2.smtp.seeweb.it [IPv6:2001:4b78:1:20::2]) by picard.linux.it (Postfix) with ESMTP id 9DCF82987AA for ; Thu, 20 Jun 2019 11:58:07 +0200 (CEST) Received: from mail-pf1-x444.google.com (mail-pf1-x444.google.com [IPv6:2607:f8b0:4864:20::444]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by in-2.smtp.seeweb.it (Postfix) with ESMTPS id 5FF7860171F for ; Thu, 20 Jun 2019 11:58:06 +0200 (CEST) Received: by mail-pf1-x444.google.com with SMTP id r7so1383723pfl.3 for ; Thu, 20 Jun 2019 02:58:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mbobrowski-org.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=HWDuhh0V+2P3kK1BHp1zd5w27WGVUl/CaXnFSli9abg=; b=psGeH+1+ADIjfmKVGS0ztbMHyQ85bNy1S1PckjZS9OR5zf0oNdH0M8A20r0o1vozUw bKoxAuUW2amfRomtfYGadxKklsKZQyJxwLQDtZ+EWIS7gnIXl6KQRGwydvfegqq/IeKF et/UMQsmnmAwndGS+WziNsrhSJQ+jylto8JvIMC+yYYzse/fEYIAhNiSJnnXAOV9V++x tldkcXCiyDiCoC2WWOc3tftYKJna9n55jJROpEBW/7rSfxpjPo2G3srzIiUQFD/jzyl4 NHqXI/skr3ZnIfu0UbDLwQoAydOdZ6wvbqYuzwyNL6AFI4lmfIGxPXUWRH2iOAKWSj+Z hXow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=HWDuhh0V+2P3kK1BHp1zd5w27WGVUl/CaXnFSli9abg=; b=hGGzDnBWoA102HcLvPpWcumRPSAdjMXNacrgRNKENd43vs2kiMLpPmAlZOgwoIjL2h WzDidXYIbmryllhx6aZnWcHa+4hrLo1s3sXYrk/FbO0i5FwSX9GppJs02xkfKhe/1hpp B5IFagKz+7HPuR+13DKJS2/wOSrrAAXgzdgkoYyAr06rTb04tFNefPDDrBsEPabVtHfq hiTeArTTmsos8NnhteKB4PNJcFKLB3utoqZDFpozYnlQk2V6buSr+ikbvGC0MLASSpa4 3JibhAAljRVC3aFu8V7oCZMwun05ku5X8GVX+m4r3pBAvc4VQQkB1Dgb1WNd8POTME6B bikg== X-Gm-Message-State: APjAAAV0TW4gBuRIC4PVS0qkYkaEm+BGtrmU7TuNbHO8YyCgdW1vIn7l 4mQnET2yQTEYGjDcB23JJmheGMFcTw== X-Google-Smtp-Source: APXvYqxXSU7hvGNr1Qkye74wu2sxBz0FIg2Uoa22icysZ5cJvJz4YikoHxTP2/5894w75uoSVpnLBg== X-Received: by 2002:a17:90a:7148:: with SMTP id g8mr2230918pjs.51.1561024684402; Thu, 20 Jun 2019 02:58:04 -0700 (PDT) Received: from neo.Home ([114.78.0.167]) by smtp.gmail.com with ESMTPSA id p15sm18262999pgj.61.2019.06.20.02.58.01 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Thu, 20 Jun 2019 02:58:03 -0700 (PDT) Date: Thu, 20 Jun 2019 19:57:58 +1000 From: Matthew Bobrowski To: ltp@lists.linux.it Message-ID: <74267e0b0abb151fdeadc7146fbc7536424066b6.1561018312.git.mbobrowski@mbobrowski.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) X-Virus-Scanned: clamav-milter 0.99.2 at in-2.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=0.1 required=7.0 tests=DKIM_SIGNED,DKIM_VALID, SPF_HELO_NONE,SPF_NONE autolearn=disabled version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-2.smtp.seeweb.it Cc: jack@suse.cz Subject: [LTP] [PATCH v5 1/4] syscalls/fanotify13: new test to verify FAN_REPORT_FID functionality X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.18 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" A newly defined test file to validate the fanotify FAN_REPORT_FID functionality. A new line entry for this test file has been added within runtest/syscalls. Additionally, defined a helper function that can be used to obtain __kernel_fsid_t and file_handle objects. This helper will be used by test files related to verifying FAN_REPORT_FID. The name_to_handle_at() function is conditionally added to accommodate for builds on older distributions. Added _GNU_SOURCE feature test macro to syscalls/fanotify05 in order to resolve build warnings. Signed-off-by: Matthew Bobrowski Reviewed-by: Amir Goldstein --- configure.ac | 1 + runtest/syscalls | 1 + testcases/kernel/syscalls/fanotify/.gitignore | 1 + testcases/kernel/syscalls/fanotify/fanotify.h | 56 ++++- testcases/kernel/syscalls/fanotify/fanotify05.c | 1 + testcases/kernel/syscalls/fanotify/fanotify13.c | 316 ++++++++++++++++++++++++ 6 files changed, 373 insertions(+), 3 deletions(-) create mode 100644 testcases/kernel/syscalls/fanotify/fanotify13.c diff --git a/configure.ac b/configure.ac index 5ecc92781..9538b2322 100644 --- a/configure.ac +++ b/configure.ac @@ -70,6 +70,7 @@ AC_CHECK_FUNCS([ \ kcmp \ mkdirat \ mknodat \ + name_to_handle_at \ openat \ preadv \ preadv2 \ diff --git a/runtest/syscalls b/runtest/syscalls index a1106fb84..e682f5087 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -534,6 +534,7 @@ fanotify09 fanotify09 fanotify10 fanotify10 fanotify11 fanotify11 fanotify12 fanotify12 +fanotify13 fanotify13 ioperm01 ioperm01 ioperm02 ioperm02 diff --git a/testcases/kernel/syscalls/fanotify/.gitignore b/testcases/kernel/syscalls/fanotify/.gitignore index 4256b8cd3..16bdd99e5 100644 --- a/testcases/kernel/syscalls/fanotify/.gitignore +++ b/testcases/kernel/syscalls/fanotify/.gitignore @@ -10,4 +10,5 @@ /fanotify10 /fanotify11 /fanotify12 +/fanotify13 /fanotify_child diff --git a/testcases/kernel/syscalls/fanotify/fanotify.h b/testcases/kernel/syscalls/fanotify/fanotify.h index 14654b7c7..a5ac14acb 100644 --- a/testcases/kernel/syscalls/fanotify/fanotify.h +++ b/testcases/kernel/syscalls/fanotify/fanotify.h @@ -29,6 +29,11 @@ #define __FANOTIFY_H__ #include "config.h" +#include +#include +#include +#include +#include #if defined(HAVE_SYS_FANOTIFY_H) @@ -57,9 +62,6 @@ static long fanotify_mark(int fd, unsigned int flags, uint64_t mask, #ifndef FAN_REPORT_TID #define FAN_REPORT_TID 0x00000100 #endif -#ifndef FAN_REPORT_FID -#define FAN_REPORT_FID 0x00000200 -#endif #ifndef FAN_MARK_INODE #define FAN_MARK_INODE 0 @@ -89,6 +91,54 @@ struct fanotify_mark_type { const char * name; }; +#ifndef FAN_REPORT_FID +#define FAN_REPORT_FID 0x00000200 + +struct fanotify_event_info_header { + uint8_t info_type; + uint8_t pad; + uint16_t len; +}; + +struct fanotify_event_info_fid { + struct fanotify_event_info_header hdr; + __kernel_fsid_t fsid; + unsigned char handle[0]; +}; + +#endif + +/* + * Helper function used to obtain __kernel_fsid_t and file_handle objects + * for a given path. Used by test files correlated to FAN_REPORT_FID + * functionality. + */ +static inline void fanotify_get_fid(const char *path, __kernel_fsid_t *fsid, + struct file_handle *handle) +{ + int mount_id; + struct statfs stats; + + if (statfs(path, &stats) == -1) + tst_brk(TBROK | TERRNO, + "statfs(%s, ...) failed", path); + memcpy(fsid, &stats.f_fsid, sizeof(stats.f_fsid)); + +#ifdef HAVE_NAME_TO_HANDLE_AT + if (name_to_handle_at(AT_FDCWD, path, handle, &mount_id, 0) == -1) { + if (errno == EOPNOTSUPP) { + tst_brk(TCONF, + "filesystem %s does not support file handles", + tst_device->fs_type); + } + tst_brk(TBROK | TERRNO, + "name_to_handle_at(AT_FDCWD, %s, ...) failed", path); + } +#else + tst_brk(TCONF, "name_to_handle_at() is not implmented"); +#endif /* HAVE_NAME_TO_HANDLE_AT */ +} + #define INIT_FANOTIFY_MARK_TYPE(t) \ { FAN_MARK_ ## t, "FAN_MARK_" #t } diff --git a/testcases/kernel/syscalls/fanotify/fanotify05.c b/testcases/kernel/syscalls/fanotify/fanotify05.c index de72e346a..112295709 100644 --- a/testcases/kernel/syscalls/fanotify/fanotify05.c +++ b/testcases/kernel/syscalls/fanotify/fanotify05.c @@ -11,6 +11,7 @@ * Generate enough events without reading them and check that overflow * event is generated. */ +#define _GNU_SOURCE #include "config.h" #include diff --git a/testcases/kernel/syscalls/fanotify/fanotify13.c b/testcases/kernel/syscalls/fanotify/fanotify13.c new file mode 100644 index 000000000..33ee2f1c8 --- /dev/null +++ b/testcases/kernel/syscalls/fanotify/fanotify13.c @@ -0,0 +1,316 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018 Matthew Bobrowski. All Rights Reserved. + * + * Started by Matthew Bobrowski + * + * DESCRIPTION + * Validate that the values returned within an event when + * FAN_REPORT_FID is specified matches those that are obtained via + * explicit invocation to system calls statfs(2) and + * name_to_handle_at(2). + */ +#define _GNU_SOURCE +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include "tst_test.h" +#include "fanotify.h" + +#if defined(HAVE_SYS_FANOTIFY_H) +#include + +#define PATH_LEN 128 +#define BUF_SIZE 256 +#define DIR_ONE "dir_one" +#define FILE_ONE "file_one" +#define FILE_TWO "file_two" +#define MOUNT_PATH "mntpoint" +#define EVENT_MAX ARRAY_SIZE(objects) +#define DIR_PATH_ONE MOUNT_PATH"/"DIR_ONE +#define FILE_PATH_ONE MOUNT_PATH"/"FILE_ONE +#define FILE_PATH_TWO MOUNT_PATH"/"FILE_TWO + +struct event_t { + unsigned long long expected_mask; + __kernel_fsid_t fsid; + struct file_handle handle; + char buf[MAX_HANDLE_SZ]; +}; + +static struct object_t { + const char *path; + int is_dir; +} objects[] = { + {FILE_PATH_ONE, 0}, + {FILE_PATH_TWO, 0}, + {DIR_PATH_ONE, 1} +}; + +static struct test_case_t { + struct fanotify_mark_type mark; + unsigned long long mask; +} test_cases[] = { + { + INIT_FANOTIFY_MARK_TYPE(INODE), + FAN_OPEN | FAN_CLOSE_NOWRITE + }, + { + INIT_FANOTIFY_MARK_TYPE(INODE), + FAN_OPEN | FAN_CLOSE_NOWRITE | FAN_ONDIR + }, + { + INIT_FANOTIFY_MARK_TYPE(MOUNT), + FAN_OPEN | FAN_CLOSE_NOWRITE + }, + { + INIT_FANOTIFY_MARK_TYPE(MOUNT), + FAN_OPEN | FAN_CLOSE_NOWRITE | FAN_ONDIR + }, + { + INIT_FANOTIFY_MARK_TYPE(FILESYSTEM), + FAN_OPEN | FAN_CLOSE_NOWRITE + }, + { + INIT_FANOTIFY_MARK_TYPE(FILESYSTEM), + FAN_OPEN | FAN_CLOSE_NOWRITE | FAN_ONDIR + } +}; + +static int fanotify_fd; +static char events_buf[BUF_SIZE]; +static struct event_t event_set[EVENT_MAX]; + +static void create_objects(void) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(objects); i++) { + if (objects[i].is_dir) + SAFE_MKDIR(objects[i].path, 0755); + else + SAFE_FILE_PRINTF(objects[i].path, "0"); + } +} + +static void get_object_stats(void) +{ + unsigned int i; + for (i = 0; i < ARRAY_SIZE(objects); i++) { + event_set[i].handle.handle_bytes = MAX_HANDLE_SZ; + fanotify_get_fid(objects[i].path, &event_set[i].fsid, + &event_set[i].handle); + } +} + +static int setup_marks(unsigned int fd, struct test_case_t *tc) +{ + unsigned int i; + struct fanotify_mark_type *mark = &tc->mark; + + for (i = 0; i < ARRAY_SIZE(objects); i++) { + if (fanotify_mark(fd, FAN_MARK_ADD | mark->flag, tc->mask, + AT_FDCWD, objects[i].path) == -1) { + if (errno == EINVAL && + mark->flag & FAN_MARK_FILESYSTEM) { + tst_res(TCONF, + "FAN_MARK_FILESYSTEM not supported by " + "kernel"); + return 1; + } else if (errno == ENODEV && + !event_set[i].fsid.val[0] && + !event_set[i].fsid.val[1]) { + tst_res(TCONF, + "FAN_REPORT_FID not supported on " + "filesystem type %s", + tst_device->fs_type); + return 1; + } + tst_brk(TBROK | TERRNO, + "fanotify_mark(%d, FAN_MARK_ADD, FAN_OPEN, " + "AT_FDCWD, %s) failed", + fanotify_fd, objects[i].path); + } + + /* Setup the expected mask for each generated event */ + event_set[i].expected_mask = tc->mask; + if (!objects[i].is_dir) + event_set[i].expected_mask &= ~FAN_ONDIR; + } + return 0; +} + +static void do_test(unsigned int number) +{ + unsigned int i; + int len, fds[ARRAY_SIZE(objects)]; + + struct file_handle *event_file_handle; + struct fanotify_event_metadata *metadata; + struct fanotify_event_info_fid *event_fid; + struct test_case_t *tc = &test_cases[number]; + struct fanotify_mark_type *mark = &tc->mark; + + tst_res(TINFO, + "Test #%d: FAN_REPORT_FID with mark flag: %s", + number, mark->name); + + fanotify_fd = fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, O_RDONLY); + if (fanotify_fd == -1) { + if (errno == EINVAL) { + tst_res(TCONF, + "FAN_REPORT_FID not supported by kernel"); + return; + } + tst_brk(TBROK | TERRNO, + "fanotify_init(FAN_CLASS_NOTIF | FAN_REPORT_FID, " + "O_RDONLY) failed"); + } + + /* + * Place marks on a set of objects and setup the expected masks + * for each event that is expected to be generated. + */ + if (setup_marks(fanotify_fd, tc) != 0) + goto out; + + /* Generate sequence of FAN_OPEN events on objects */ + for (i = 0; i < ARRAY_SIZE(objects); i++) + fds[i] = SAFE_OPEN(objects[i].path, O_RDONLY); + + /* + * Generate sequence of FAN_CLOSE_NOWRITE events on objects. Each + * FAN_CLOSE_NOWRITE event is expected to be merged with its + * respective FAN_OPEN event that was performed on the same object. + */ + for (i = 0; i < ARRAY_SIZE(objects); i++) { + if (fds[i] > 0) + SAFE_CLOSE(fds[i]); + } + + /* Read events from event queue */ + len = SAFE_READ(0, fanotify_fd, events_buf, BUF_SIZE); + + /* Iterate over event queue */ + for (i = 0, metadata = (struct fanotify_event_metadata *) events_buf; + FAN_EVENT_OK(metadata, len); + metadata = FAN_EVENT_NEXT(metadata, len), i++) { + event_fid = (struct fanotify_event_info_fid *) (metadata + 1); + event_file_handle = (struct file_handle *) event_fid->handle; + + /* File descriptor is redundant with FAN_REPORT_FID */ + if (metadata->fd != FAN_NOFD) + tst_res(TFAIL, + "Unexpectedly received file descriptor %d in " + "event. Expected to get FAN_NOFD(%d)", + metadata->fd, FAN_NOFD); + + /* Ensure that the correct mask has been reported in event */ + if (metadata->mask != event_set[i].expected_mask) + tst_res(TFAIL, + "Unexpected mask received: %llx (expected: " + "%llx) in event", + metadata->mask, + event_set[i].expected_mask); + + /* Verify handle_bytes returned in event */ + if (event_file_handle->handle_bytes + != event_set[i].handle.handle_bytes) { + tst_res(TFAIL, + "handle_bytes (%x) returned in event does not " + "equal to handle_bytes (%x) returned in " + "name_to_handle_at(2)", + event_file_handle->handle_bytes, + event_set[i].handle.handle_bytes); + continue; + } + + /* Verify handle_type returned in event */ + if (event_file_handle->handle_type != + event_set[i].handle.handle_type) { + tst_res(TFAIL, + "handle_type (%x) returned in event does not " + "equal to handle_type (%x) returned in " + "name_to_handle_at(2)", + event_file_handle->handle_type, + event_set[i].handle.handle_type); + continue; + } + + /* Verify file identifier f_handle returned in event */ + if (memcmp(event_file_handle->f_handle, + event_set[i].handle.f_handle, + event_set[i].handle.handle_bytes) != 0) { + tst_res(TFAIL, + "event_file_handle->f_handle does not match " + "event_set[i].handle.f_handle returned in " + "name_to_handle_at(2)"); + continue; + } + + /* Verify filesystem ID fsid returned in event */ + if (memcmp(&event_fid->fsid, &event_set[i].fsid, + sizeof(event_set[i].fsid)) != 0) { + tst_res(TFAIL, + "event_fid.fsid != stat.f_fsid that was " + "obtained via statfs(2)"); + continue; + } + + tst_res(TPASS, + "got event: mask=%llx, pid=%d, fid=%x.%x.%lx values " + "returned in event match those returned in statfs(2) " + "and name_to_handle_at(2)", + metadata->mask, + getpid(), + event_fid->fsid.val[0], + event_fid->fsid.val[1], + *(unsigned long *) event_file_handle->f_handle); + } +out: + SAFE_CLOSE(fanotify_fd); +} + +static void do_setup(void) +{ + int fd; + + /* Check for kernel fanotify support */ + fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, O_RDONLY); + SAFE_CLOSE(fd); + + /* Create file and directory objects for testing */ + create_objects(); + + /* Get the filesystem fsid and file handle for each created object */ + get_object_stats(); +} + +static void do_cleanup(void) +{ + if (fanotify_fd > 0) + SAFE_CLOSE(fanotify_fd); +} + +static struct tst_test test = { + .test = do_test, + .tcnt = ARRAY_SIZE(test_cases), + .setup = do_setup, + .cleanup = do_cleanup, + .needs_root = 1, + .needs_tmpdir = 1, + .mount_device = 1, + .mntpoint = MOUNT_PATH, + .all_filesystems = 1 +}; + +#else + TST_TEST_TCONF("System does not have required fanotify support"); +#endif From patchwork Thu Jun 20 09:58:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Bobrowski X-Patchwork-Id: 1119322 X-Patchwork-Delegate: petr.vorel@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=lists.linux.it (client-ip=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mbobrowski.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mbobrowski-org.20150623.gappssmtp.com header.i=@mbobrowski-org.20150623.gappssmtp.com header.b="OOILDFfC"; dkim-atps=neutral Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45Ty200HRsz9s4V for ; Thu, 20 Jun 2019 19:58:31 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 81FD8298931 for ; Thu, 20 Jun 2019 11:58:29 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-7.smtp.seeweb.it (in-7.smtp.seeweb.it [217.194.8.7]) by picard.linux.it (Postfix) with ESMTP id B0C7C2987A9 for ; Thu, 20 Jun 2019 11:58:27 +0200 (CEST) Received: from mail-pl1-x643.google.com (mail-pl1-x643.google.com [IPv6:2607:f8b0:4864:20::643]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by in-7.smtp.seeweb.it (Postfix) with ESMTPS id D9EE4201013 for ; Thu, 20 Jun 2019 11:58:26 +0200 (CEST) Received: by mail-pl1-x643.google.com with SMTP id g4so1182916plb.5 for ; Thu, 20 Jun 2019 02:58:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mbobrowski-org.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=KWqMjogGt80KOsQCQmhghuqKSAs8rmfJD0jxQwQMaMw=; b=OOILDFfC+L009bzfvass5jbLdwsxVtT9oCTTQg6+fa6qiVpguSD1lfsaJLXA20L6ib CtSPYBg7NxBuH5sz75r2fYfheM74hk5MG5JK0vSiWyHHMn2Fx0z1KLqrHSJeNyufkdh7 3Ms2ENwp4AYz2Mz6ZWNryoYRxyOG8ZA85ohjKB1xIU+ILgl6cD0rHMNFlmLZIoBXx8Xl HL1zs256mdVieT1+6vE0f2Q41JhM1sdHDf44F3tbmTFMQaxAqU5eo+ST3nSqxp6uvcCw uxofOKuY9FCfk+D3GmimZ1VC+dhyek4nHRsXCTpnpbo6qowKQ5/OwFUrh1bNVzvnahT/ 6Ljg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=KWqMjogGt80KOsQCQmhghuqKSAs8rmfJD0jxQwQMaMw=; b=cyZUcnMn4Ij9Ie2lL3zU9ZbDRriQQdJxXL3PZUPSH9pnfnYLq4hQvnJeCMDijt4A7F zSwWmxkXnSHaTPEV0qW4oN8NsJJ3AOUdzoalkfspG98m+NsvrloUcGF+rAsy8CIO9Qs8 5+CL3c7supum9yL80jFI7Miv7ayK10UwTEvXHJ4V/8Hr4LsTtmNBnz5YTp1WDtDSx6s+ epUNBD9zA9IyXZygPBHgTd5mLffkDbtJuTxGB9QibZvB+PPhNoQumS9kuh9JqQ+kMPpg TPuWgu9MBfVQdpYjILfEfICtpCHWDnZcMf78bdvu5KDxuMjM8EZhFTJS99ND1RV0Tiq2 SsZw== X-Gm-Message-State: APjAAAXSzyi6JjUZF+o/cz9HPLZcaJOqVRffRiP31vaExa7SGDsJM3Ef PRjICmMIG+9Wnu+SzVFz9cLbL5ztKA== X-Google-Smtp-Source: APXvYqzZvhn3tUwmj+ygNS/3LahVkUZjmwRhLAS3025oveF7j2rkZWq/Y3mQeJuUNuXzjUIoLsDPvg== X-Received: by 2002:a17:902:934a:: with SMTP id g10mr114562678plp.18.1561024704893; Thu, 20 Jun 2019 02:58:24 -0700 (PDT) Received: from neo.Home ([114.78.0.167]) by smtp.gmail.com with ESMTPSA id c69sm6456769pje.6.2019.06.20.02.58.22 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Thu, 20 Jun 2019 02:58:23 -0700 (PDT) Date: Thu, 20 Jun 2019 19:58:18 +1000 From: Matthew Bobrowski To: ltp@lists.linux.it Message-ID: <98bc3a5d9591387964b913c497f930a11ea4f7a8.1561018312.git.mbobrowski@mbobrowski.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) X-Virus-Scanned: clamav-milter 0.99.2 at in-7.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=0.1 required=7.0 tests=DKIM_SIGNED,DKIM_VALID, SPF_HELO_NONE,SPF_NONE autolearn=disabled version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-7.smtp.seeweb.it Cc: jack@suse.cz Subject: [LTP] [PATCH v5 2/4] syscalls/fanotify14: new test to validate FAN_REPORT_FID interface return values X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.18 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" A newly defined test file has been introduced to validate that the fanotify interface returns the correct error values upon specifying invalid flags and masks in conjunction with FAN_REPORT_FID. A new line entry within runtest/syscalls for this new test file. Signed-off-by: Matthew Bobrowski Reviewed-by: Amir Goldstein --- runtest/syscalls | 1 + testcases/kernel/syscalls/fanotify/.gitignore | 1 + testcases/kernel/syscalls/fanotify/fanotify.h | 25 ++++ testcases/kernel/syscalls/fanotify/fanotify14.c | 176 ++++++++++++++++++++++++ 4 files changed, 203 insertions(+) create mode 100644 testcases/kernel/syscalls/fanotify/fanotify14.c diff --git a/runtest/syscalls b/runtest/syscalls index e682f5087..56f84824a 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -535,6 +535,7 @@ fanotify10 fanotify10 fanotify11 fanotify11 fanotify12 fanotify12 fanotify13 fanotify13 +fanotify14 fanotify14 ioperm01 ioperm01 ioperm02 ioperm02 diff --git a/testcases/kernel/syscalls/fanotify/.gitignore b/testcases/kernel/syscalls/fanotify/.gitignore index 16bdd99e5..bf389c96a 100644 --- a/testcases/kernel/syscalls/fanotify/.gitignore +++ b/testcases/kernel/syscalls/fanotify/.gitignore @@ -11,4 +11,5 @@ /fanotify11 /fanotify12 /fanotify13 +/fanotify14 /fanotify_child diff --git a/testcases/kernel/syscalls/fanotify/fanotify.h b/testcases/kernel/syscalls/fanotify/fanotify.h index a5ac14acb..f9803c1cc 100644 --- a/testcases/kernel/syscalls/fanotify/fanotify.h +++ b/testcases/kernel/syscalls/fanotify/fanotify.h @@ -69,6 +69,31 @@ static long fanotify_mark(int fd, unsigned int flags, uint64_t mask, #ifndef FAN_MARK_FILESYSTEM #define FAN_MARK_FILESYSTEM 0x00000100 #endif +/* New dirent event masks */ +#ifndef FAN_ATTRIB +#define FAN_ATTRIB 0x00000004 +#endif +#ifndef FAN_MOVED_FROM +#define FAN_MOVED_FROM 0x00000040 +#endif +#ifndef FAN_MOVED_TO +#define FAN_MOVED_TO 0x00000080 +#endif +#ifndef FAN_CREATE +#define FAN_CREATE 0x00000100 +#endif +#ifndef FAN_DELETE +#define FAN_DELETE 0x00000200 +#endif +#ifndef FAN_DELETE_SELF +#define FAN_DELETE_SELF 0x00000400 +#endif +#ifndef FAN_MOVE_SELF +#define FAN_MOVE_SELF 0x00000800 +#endif +#ifndef FAN_MOVE +#define FAN_MOVE (FAN_MOVED_FROM | FAN_MOVED_TO) +#endif #ifndef FAN_OPEN_EXEC #define FAN_OPEN_EXEC 0x00001000 #endif diff --git a/testcases/kernel/syscalls/fanotify/fanotify14.c b/testcases/kernel/syscalls/fanotify/fanotify14.c new file mode 100644 index 000000000..8f502115a --- /dev/null +++ b/testcases/kernel/syscalls/fanotify/fanotify14.c @@ -0,0 +1,176 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018 Matthew Bobrowski. All Rights Reserved. + * + * Started by Matthew Bobrowski + * + * DESCRIPTION + * This test file has been designed to ensure that the fanotify + * system calls fanotify_init(2) and fanotify_mark(2) return the + * correct error code to the calling process when an invalid flag or + * mask value has been specified in conjunction with FAN_REPORT_FID. + */ +#define _GNU_SOURCE +#include "tst_test.h" +#include "fanotify.h" + +#include + +#if defined(HAVE_SYS_FANOTIFY_H) +#include + +#define MNTPOINT "mntpoint" +#define FILE1 MNTPOINT"/file1" + +/* + * List of inode events that are only available when notification group is + * set to report fid. + */ +#define INODE_EVENTS (FAN_ATTRIB | FAN_CREATE | FAN_DELETE | FAN_MOVE | \ + FAN_DELETE_SELF | FAN_MOVE_SELF) + +static int fanotify_fd; + +/* + * Each test case has been designed in a manner whereby the values defined + * within should result in the interface to return an error to the calling + * process. + */ +static struct test_case_t { + unsigned int init_flags; + unsigned int mark_flags; + unsigned long long mask; +} test_cases[] = { + { + FAN_CLASS_CONTENT | FAN_REPORT_FID, 0, 0 + }, + { + FAN_CLASS_PRE_CONTENT | FAN_REPORT_FID, 0, 0 + }, + { + FAN_CLASS_NOTIF, 0, INODE_EVENTS + }, + { + FAN_CLASS_NOTIF | FAN_REPORT_FID, FAN_MARK_MOUNT, INODE_EVENTS + } +}; + +static void do_test(unsigned int number) +{ + int ret; + struct test_case_t *tc = &test_cases[number]; + + fanotify_fd = fanotify_init(tc->init_flags, O_RDONLY); + if (fanotify_fd < 0) { + /* + * EINVAL is to be returned to the calling process when + * an invalid notification class is specified in + * conjunction with FAN_REPORT_FID. + */ + if (errno == EINVAL) { + tst_res(TPASS, + "fanotify_fd=%d, fanotify_init(%x, O_RDONLY) " + "failed with error EINVAL as expected", + fanotify_fd, + tc->init_flags); + return; + } + tst_brk(TBROK | TERRNO, + "fanotify_fd=%d, fanotify_init(%x, O_RDONLY) failed", + fanotify_fd, + tc->init_flags); + } + + /* + * A test case with a mask set to zero indicate that they've been + * specifically designed to test and fail on the fanotify_init() + * system call. + */ + if (tc->mask == 0) { + tst_res(TFAIL, + "fanotify_fd=%d fanotify_init(%x, O_RDONLY) " + "unexpectedly succeeded when tests with mask 0 are" + "expected to fail when calling fanotify_init()", + fanotify_fd, + tc->init_flags); + goto out; + } + + ret = fanotify_mark(fanotify_fd, FAN_MARK_ADD | tc->mark_flags, + tc->mask, AT_FDCWD, FILE1); + if (ret < 0) { + /* + * EINVAL is to be returned to the calling process when + * attempting to use INODE_EVENTS without FAN_REPORT_FID + * specified on the notification group, or using + * INODE_EVENTS with mark type FAN_MARK_MOUNT. + */ + if (errno == EINVAL) { + tst_res(TPASS, + "ret=%d, fanotify_mark(%d, FAN_MARK_ADD | %x, " + "%llx, AT_FDCWD, %s) failed with error EINVAL " + "as expected", + ret, + fanotify_fd, + tc->mark_flags, + tc->mask, + FILE1); + goto out; + } + tst_brk(TBROK | TERRNO, + "ret=%d, fanotify_mark(%d, FAN_MARK_ADD | %x, %llx, " + "AT_FDCWD, %s) failed", + ret, + fanotify_fd, + tc->mark_flags, + tc->mask, + FILE1); + } + + tst_res(TFAIL, + "fanotify_fd=%d, ret=%d, fanotify_init(%x, O_RDONLY) and " + "fanotify_mark(%d, FAN_MARK_ADD | %x, %llx, AT_FDCWD, %s) did " + "not return any errors as expected", + fanotify_fd, + ret, + tc->init_flags, + fanotify_fd, + tc->mark_flags, + tc->mask, + FILE1); +out: + SAFE_CLOSE(fanotify_fd); +} + +static void do_setup(void) +{ + int fd; + + /* Check for kernel fanotify support */ + fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, O_RDONLY); + SAFE_CLOSE(fd); + + /* Create temporary test file to place marks on */ + SAFE_FILE_PRINTF(FILE1, "0"); +} + +static void do_cleanup(void) +{ + if (fanotify_fd > 0) + SAFE_CLOSE(fanotify_fd); +} + +static struct tst_test test = { + .needs_root = 1, + .test = do_test, + .tcnt = ARRAY_SIZE(test_cases), + .setup = do_setup, + .cleanup = do_cleanup, + .mount_device = 1, + .mntpoint = MNTPOINT, + .all_filesystems = 1 +}; + +#else + TST_TEST_TCONF("System does not have required fanotify support") +#endif From patchwork Thu Jun 20 09:58:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Bobrowski X-Patchwork-Id: 1119323 X-Patchwork-Delegate: petr.vorel@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=lists.linux.it (client-ip=213.254.12.146; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mbobrowski.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mbobrowski-org.20150623.gappssmtp.com header.i=@mbobrowski-org.20150623.gappssmtp.com header.b="PNtp6LUf"; dkim-atps=neutral Received: from picard.linux.it (picard.linux.it [213.254.12.146]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45Ty2j2jD9z9s4V for ; Thu, 20 Jun 2019 19:59:09 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id DB6452987D1 for ; Thu, 20 Jun 2019 11:59:06 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-4.smtp.seeweb.it (in-4.smtp.seeweb.it [217.194.8.4]) by picard.linux.it (Postfix) with ESMTP id 8F5F92987A9 for ; Thu, 20 Jun 2019 11:59:04 +0200 (CEST) Received: from mail-pf1-x444.google.com (mail-pf1-x444.google.com [IPv6:2607:f8b0:4864:20::444]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by in-4.smtp.seeweb.it (Postfix) with ESMTPS id 64ABA1000C55 for ; Thu, 20 Jun 2019 11:58:59 +0200 (CEST) Received: by mail-pf1-x444.google.com with SMTP id 81so1356681pfy.13 for ; Thu, 20 Jun 2019 02:59:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mbobrowski-org.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=tbrdB7XQIkDfPPaJQ6aY9O4XEpjUPoQSCh7LhND45Ik=; b=PNtp6LUfQs1yp+i7TiOfZG5Ui6aElsRqYJ5bwexNtb0pR8vhhXjXymjAFArPq65FfW I2knOkC4QbGw5asVYrGi0ItKYXkSA7+VAnGIJP3py3vNsPEHvuEI2u6ZlOnqEkZ/U+Mt E3P7+OSEVQ2q3LV3l7AlX8FXSEOGZMlSPxAFbbQD8iwDz0V9wSgi5DwAmgocX7/sYHfd Erk2zniGXqdSP5xiluEbfs1uVs5Blr5dMnnNWgMezRygo8w1tb8pX3baK9gCfgiOMPeO 9NOsm/QIVr6kYGMsqq1Y0mJAqWvMkINbR+PnkssyBMAnjB18WiP9vDBq5N9cCvjUNR39 RATg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=tbrdB7XQIkDfPPaJQ6aY9O4XEpjUPoQSCh7LhND45Ik=; b=ts5gLgRZbo22acId0j3AnvA178eWLNYPs2KZoCGjLmlcHyOlqtRF4KazaL0t7xUlkr d1NpvuaJ7OQhL2EQ1mCmUSDYNqbY103TlyoAr5zFj6B5Qb9kb5TqC4CrDksslDBE6iWX 9TqDELF2SFUnIvXIL92in+NEsKKio7cPuFYSav5xCwBFcAMn5B/JuDmf/M+Km695XuHZ dCu17exnUfhyScvOG9CML/v/C8oz7D0kzuqIyK/o/Mkkdy+5M7uKh2JOPGx8HY195B4e XjGhaj1JRI1+vqGY8dP1egaRlCLkHz/JOeUDYm9KV4pHbvKJzMj/+Y2XaHZZxFyoFZyM +X8w== X-Gm-Message-State: APjAAAWG/41mxX8E3YDv2DszgdWyevCbPenEIReGdS2q6Bf4f2c2X2q9 Kyq9x1lC/j/nnVccQGwLx9MHEX/YVw== X-Google-Smtp-Source: APXvYqwyB6fE8BQghnhjQd8X5AH7JtVts8VENmJtJXxbNkV+bNW4bbm+zGQgkp7p8zIrCZ8Hxx0+gg== X-Received: by 2002:a17:90a:206a:: with SMTP id n97mr2250368pjc.10.1561024741614; Thu, 20 Jun 2019 02:59:01 -0700 (PDT) Received: from neo.Home ([114.78.0.167]) by smtp.gmail.com with ESMTPSA id 30sm15345875pjk.17.2019.06.20.02.58.59 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Thu, 20 Jun 2019 02:59:00 -0700 (PDT) Date: Thu, 20 Jun 2019 19:58:55 +1000 From: Matthew Bobrowski To: ltp@lists.linux.it Message-ID: <5abce371ba13e202fca416267c6e9c4c250cffda.1561018312.git.mbobrowski@mbobrowski.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) X-Virus-Scanned: clamav-milter 0.99.2 at in-4.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=0.1 required=7.0 tests=DKIM_SIGNED,DKIM_VALID, SPF_HELO_NONE,SPF_NONE autolearn=disabled version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-4.smtp.seeweb.it Cc: jack@suse.cz Subject: [LTP] [PATCH v5 3/4] syscalls/fanotify15: verify fid for dirent events X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.18 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" A new test file that provides coverage for new dirent events has been added. A new line entry within the runtest/syscalls file has been also added to support the testing of these new dirent events. Signed-off-by: Matthew Bobrowski Reviewed-by: Amir Goldstein --- runtest/syscalls | 1 + testcases/kernel/syscalls/fanotify/.gitignore | 1 + testcases/kernel/syscalls/fanotify/fanotify15.c | 246 ++++++++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 testcases/kernel/syscalls/fanotify/fanotify15.c diff --git a/runtest/syscalls b/runtest/syscalls index 56f84824a..25cb29dab 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -536,6 +536,7 @@ fanotify11 fanotify11 fanotify12 fanotify12 fanotify13 fanotify13 fanotify14 fanotify14 +fanotify15 fanotify15 ioperm01 ioperm01 ioperm02 ioperm02 diff --git a/testcases/kernel/syscalls/fanotify/.gitignore b/testcases/kernel/syscalls/fanotify/.gitignore index bf389c96a..68e4cc7aa 100644 --- a/testcases/kernel/syscalls/fanotify/.gitignore +++ b/testcases/kernel/syscalls/fanotify/.gitignore @@ -12,4 +12,5 @@ /fanotify12 /fanotify13 /fanotify14 +/fanotify15 /fanotify_child diff --git a/testcases/kernel/syscalls/fanotify/fanotify15.c b/testcases/kernel/syscalls/fanotify/fanotify15.c new file mode 100644 index 000000000..6981b7891 --- /dev/null +++ b/testcases/kernel/syscalls/fanotify/fanotify15.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2019 CTERA Networks. All Rights Reserved. + * + * Started by Amir Goldstein + * Modified by Matthew Bobrowski + * + * DESCRIPTION + * Test file that has been purposely designed to verify + * FAN_REPORT_FID functionality while using newly defined dirent + * events. + */ +#define _GNU_SOURCE +#include "config.h" + +#include +#include +#include +#include +#include + +#include "tst_test.h" +#include "fanotify.h" + +#if defined(HAVE_SYS_FANOTIFY_H) +#include + +#define BUF_SIZE 256 +#define EVENT_MAX 256 + +#define MOUNT_POINT "mntpoint" +#define TEST_DIR MOUNT_POINT"/test_dir" +#define DIR1 TEST_DIR"/dir1" +#define DIR2 TEST_DIR"/dir2" +#define FILE1 TEST_DIR"/file1" +#define FILE2 TEST_DIR"/file2" + +struct event_t { + unsigned long long mask; + __kernel_fsid_t fsid; + struct file_handle handle; + char buf[MAX_HANDLE_SZ]; +}; + +static int fanotify_fd; +static char events_buf[BUF_SIZE]; +static struct event_t event_set[EVENT_MAX]; + +static void do_test(void) +{ + int i, fd, len, count = 0; + + struct file_handle *event_file_handle; + struct fanotify_event_metadata *metadata; + struct fanotify_event_info_fid *event_fid; + + if (fanotify_mark(fanotify_fd, FAN_MARK_ADD | FAN_MARK_FILESYSTEM, + FAN_CREATE | FAN_DELETE | FAN_ATTRIB | + FAN_MOVED_FROM | FAN_MOVED_TO | + FAN_DELETE_SELF | FAN_ONDIR, + AT_FDCWD, TEST_DIR) == -1) { + if (errno == ENODEV) + tst_brk(TCONF, + "FAN_REPORT_FID not supported on %s " + "filesystem", tst_device->fs_type); + tst_brk(TBROK | TERRNO, + "fanotify_mark(%d, FAN_MARK_ADD, FAN_CREATE | " + "FAN_DELETE | FAN_MOVED_FROM | FAN_MOVED_TO | " + "FAN_DELETE_SELF | FAN_ONDIR, AT_FDCWD, %s) failed", + fanotify_fd, TEST_DIR); + } + + /* Generate a sequence of events */ + event_set[count].mask = FAN_CREATE | FAN_MOVED_FROM | FAN_MOVED_TO | \ + FAN_DELETE; + event_set[count].handle.handle_bytes = MAX_HANDLE_SZ; + fanotify_get_fid(TEST_DIR, &event_set[count].fsid, + &event_set[count].handle); + count++; + + fd = SAFE_CREAT(FILE1, 0644); + SAFE_CLOSE(fd); + + SAFE_RENAME(FILE1, FILE2); + + event_set[count].mask = FAN_ATTRIB | FAN_DELETE_SELF; + event_set[count].handle.handle_bytes = MAX_HANDLE_SZ; + fanotify_get_fid(FILE2, &event_set[count].fsid, + &event_set[count].handle); + count++; + + SAFE_UNLINK(FILE2); + + /* + * Generate a sequence of events on a directory. Subsequent events + * are merged, so it's required that we set FAN_ONDIR once in + * order to acknowledge that changes related to a subdirectory + * took place. Events on subdirectories are not merged with events + * on non-subdirectories. + */ + event_set[count].mask = FAN_ONDIR | FAN_CREATE | FAN_MOVED_FROM | \ + FAN_MOVED_TO | FAN_DELETE; + event_set[count].handle.handle_bytes = MAX_HANDLE_SZ; + fanotify_get_fid(TEST_DIR, &event_set[count].fsid, + &event_set[count].handle); + count++; + + SAFE_MKDIR(DIR1, 0755); + + SAFE_RENAME(DIR1, DIR2); + + event_set[count].mask = FAN_ONDIR | FAN_DELETE_SELF; + event_set[count].handle.handle_bytes = MAX_HANDLE_SZ; + fanotify_get_fid(DIR2, &event_set[count].fsid, + &event_set[count].handle); + count++; + + SAFE_RMDIR(DIR2); + + /* Read events from the event queue */ + len = SAFE_READ(0, fanotify_fd, events_buf, BUF_SIZE); + + /* Process each event in buffer */ + for (i = 0, metadata = (struct fanotify_event_metadata *) events_buf; + FAN_EVENT_OK(metadata, len); + metadata = FAN_EVENT_NEXT(metadata,len), i++) { + event_fid = (struct fanotify_event_info_fid *) (metadata + 1); + event_file_handle = (struct file_handle *) event_fid->handle; + + if (i >= count) { + tst_res(TFAIL, + "got unnecessary event: mask=%llx " + "pid=%u fd=%d", + (unsigned long long) metadata->mask, + metadata->pid, + metadata->fd); + metadata->mask = 0; + } else if (metadata->fd != FAN_NOFD) { + tst_res(TFAIL, + "Received unexpected file descriptor %d in " + "event. Expected to get FAN_NOFD(%d)", + metadata->fd, FAN_NOFD); + } else if (metadata->mask != event_set[i].mask) { + tst_res(TFAIL, + "Got event: mask=%llx (expected %llx) " + "pid=%u fd=%d", + (unsigned long long) metadata->mask, + event_set[i].mask, + (unsigned) metadata->pid, + metadata->fd); + } else if (metadata->pid != getpid()) { + tst_res(TFAIL, + "Got event: mask=%llx pid=%u " + "(expected %u) fd=%d", + (unsigned long long) metadata->mask, + (unsigned) metadata->pid, + (unsigned) getpid(), + metadata->fd); + } else if (event_file_handle->handle_bytes != + event_set[i].handle.handle_bytes) { + tst_res(TFAIL, + "Got event: handle_bytes (%x) returned in " + "event does not equal handle_bytes (%x) " + "retunred in name_to_handle_at(2)", + event_file_handle->handle_bytes, + event_set[i].handle.handle_bytes); + } else if (event_file_handle->handle_type != + event_set[i].handle.handle_type) { + tst_res(TFAIL, + "handle_type (%x) returned in event does not " + "equal to handle_type (%x) returned in " + "name_to_handle_at(2)", + event_file_handle->handle_type, + event_set[i].handle.handle_type); + } else if (memcmp(event_file_handle->f_handle, + event_set[i].handle.f_handle, + event_set[i].handle.handle_bytes) + != 0) { + tst_res(TFAIL, + "event_file_handle->f_handle does not match " + "handle.f_handle returned in " + "name_to_handle_at(2)"); + } else if (memcmp(&event_fid->fsid, &event_set[i].fsid, + sizeof(event_set[i].fsid)) != 0) { + tst_res(TFAIL, + "event_fid->fsid != stats.f_fsid that was " + "obtained via statfs(2)"); + } else { + tst_res(TPASS, + "Got event: mask=%llx, pid=%u, " + "fid=%x.%x.%lx values", + metadata->mask, + getpid(), + event_fid->fsid.val[0], + event_fid->fsid.val[1], + *(unsigned long *) + event_file_handle->f_handle); + } + } + + for (; i < count; i++) + tst_res(TFAIL, + "Didn't receive event: mask=%llx", + event_set[i].mask); +} + +static void do_setup(void) +{ + int fd; + + /* Check kernel for fanotify support */ + fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, O_RDONLY); + SAFE_CLOSE(fd); + + fanotify_fd = fanotify_init(FAN_REPORT_FID, O_RDONLY); + if (fanotify_fd == -1) { + if (errno == EINVAL) + tst_brk(TCONF, + "FAN_REPORT_FID not supported in kernel"); + tst_brk(TBROK | TERRNO, + "fanotify_init(FAN_REPORT_FID, O_RDONLY) failed"); + } + + SAFE_MKDIR(TEST_DIR, 0755); +} + +static void do_cleanup(void) +{ + if (fanotify_fd > 0) + SAFE_CLOSE(fanotify_fd); +} + +static struct tst_test test = { + .needs_root = 1, + .needs_tmpdir = 1, + .mount_device = 1, + .mntpoint = MOUNT_POINT, + .all_filesystems = 1, + .test_all = do_test, + .setup = do_setup, + .cleanup = do_cleanup +}; + +#else + TST_TEST_TCONF("System does not have required fanotify support"); +#endif From patchwork Thu Jun 20 09:59:14 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Bobrowski X-Patchwork-Id: 1119324 X-Patchwork-Delegate: petr.vorel@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=lists.linux.it (client-ip=2001:1418:10:5::2; helo=picard.linux.it; envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mbobrowski.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mbobrowski-org.20150623.gappssmtp.com header.i=@mbobrowski-org.20150623.gappssmtp.com header.b="UzPLnVvv"; dkim-atps=neutral Received: from picard.linux.it (picard.linux.it [IPv6:2001:1418:10:5::2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45Ty341FWfz9s5c for ; Thu, 20 Jun 2019 19:59:28 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 7CD072987B2 for ; Thu, 20 Jun 2019 11:59:25 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-7.smtp.seeweb.it (in-7.smtp.seeweb.it [217.194.8.7]) by picard.linux.it (Postfix) with ESMTP id 583032987A9 for ; Thu, 20 Jun 2019 11:59:23 +0200 (CEST) Received: from mail-pl1-x643.google.com (mail-pl1-x643.google.com [IPv6:2607:f8b0:4864:20::643]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by in-7.smtp.seeweb.it (Postfix) with ESMTPS id BE799200E1A for ; Thu, 20 Jun 2019 11:59:22 +0200 (CEST) Received: by mail-pl1-x643.google.com with SMTP id a93so1187380pla.7 for ; Thu, 20 Jun 2019 02:59:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mbobrowski-org.20150623.gappssmtp.com; s=20150623; h=from:date:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=CV+rOdgs7/olVBOg4xh2sAswn53R8zauEKGixZf20j8=; b=UzPLnVvvAaRS0y09NjR83lmDWG5SpVgBGBAgdVUZwPoHJp31wXohVqOyyUaBzaYXp9 PmAWfplYZA8qjge3RYhchC79qKR+2kU8Q5pziPQ57qOsRMroKrOwDpN62JANr5fo00Qv EQfi9cUG1bEeZZXZnWc0wHdjqpSp3cK6TvW7uiw2Fhew5PZoObMwJl2SzvqrWE2gCWI1 InfBw9WMNY08OP1mx0lwgWYHHbjp/ykB3QONL4Dr2XedEk5Xx+xBMNiQQdozIB6rNvTL Nc80/c8i3pLpPASeQFEIa9WyZ456oMd7ZIkh7EBcu/Ooz9jY9eO3NRf/1C4SkVSzZaCY YdKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:date:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=CV+rOdgs7/olVBOg4xh2sAswn53R8zauEKGixZf20j8=; b=WirhJceLBjnBIY03uel3oMlzPJ/2Pq1vMUwt1Y2/7pkMdEI3EXNaMCtX3k+tp8gbbf zG5N1WOnQX85zALzW8wfIefNLWbII3QtgRDFLSzjkagEcHlHzMl6DZGkVnRuGl22QkZg AS6CKw3U/E3xOdXk44MWIEJFx2ngxdeXWQMHjo/cWWF9VeY8f7TyexmLJ0K/r7zlyafB ixj/6JNCDLj5MdiyVFaZTKqsMshQQzwKtXDzAu56zwpJPpuYEyhsjTTSt7FYcQxDrdrq 7GK4FU5FXX1zOzMb+2GT7zJ0aszY3Wfss54NnGqY064qK71AGDb2B3xkt0c+auaWI3Lk DhPA== X-Gm-Message-State: APjAAAVptZMm2ZnbD/W53Jd9Bvv0/7eCbYbGLNHLB9Au8VD9G+oGGON0 XinzDJ7msLGJI/o1KXkREsgp2Xv2Gw== X-Google-Smtp-Source: APXvYqzmqSCwuq9kduSVb5bpiHZ/hvdTJunk2V1n3QeTLRuAyihCu1I2v156sgeOEFsVfTtxlvBt1A== X-Received: by 2002:a17:902:2ac1:: with SMTP id j59mr51460997plb.156.1561024760888; Thu, 20 Jun 2019 02:59:20 -0700 (PDT) Received: from neo.Home ([114.78.0.167]) by smtp.gmail.com with ESMTPSA id 14sm24727319pfj.36.2019.06.20.02.59.18 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Thu, 20 Jun 2019 02:59:20 -0700 (PDT) From: Amir Goldstein X-Google-Original-From: Amir Goldstein Date: Thu, 20 Jun 2019 19:59:14 +1000 To: ltp@lists.linux.it Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.10.1 (2018-07-13) X-Virus-Scanned: clamav-milter 0.99.2 at in-7.smtp.seeweb.it X-Virus-Status: Clean X-Spam-Status: No, score=0.1 required=7.0 tests=DKIM_SIGNED,DKIM_VALID, SPF_HELO_NONE,SPF_NONE autolearn=disabled version=3.4.0 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on in-7.smtp.seeweb.it Cc: jack@suse.cz Subject: [LTP] [PATCH v5 4/4] syscalls/fanotify13: add test coverage for fsid cache bug X-BeenThere: ltp@lists.linux.it X-Mailman-Version: 2.1.18 Precedence: list List-Id: Linux Test Project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it Sender: "ltp" This bug was reported by syzbot: https://lore.kernel.org/linux-fsdevel/CAOQ4uxhsnOXXVCuOT4p4c_koBMFfprWwdtCPGNGhzprFaJZwRA@mail.gmail.com/T/#t Signed-off-by: Amir Goldstein --- testcases/kernel/syscalls/fanotify/fanotify13.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/testcases/kernel/syscalls/fanotify/fanotify13.c b/testcases/kernel/syscalls/fanotify/fanotify13.c index 33ee2f1c8..8f9baacfa 100644 --- a/testcases/kernel/syscalls/fanotify/fanotify13.c +++ b/testcases/kernel/syscalls/fanotify/fanotify13.c @@ -84,6 +84,7 @@ static struct test_case_t { } }; +static int nofid_fd; static int fanotify_fd; static char events_buf[BUF_SIZE]; static struct event_t event_set[EVENT_MAX]; @@ -280,21 +281,32 @@ out: static void do_setup(void) { - int fd; - /* Check for kernel fanotify support */ - fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, O_RDONLY); - SAFE_CLOSE(fd); + nofid_fd = SAFE_FANOTIFY_INIT(FAN_CLASS_NOTIF, O_RDONLY); /* Create file and directory objects for testing */ create_objects(); + /* + * Create a mark on first inode without FAN_REPORT_FID, to test + * uninitialized connector->fsid cache. This mark remains for all test + * cases and is not expected to get any events (no writes in this test). + */ + if (fanotify_mark(nofid_fd, FAN_MARK_ADD, FAN_CLOSE_WRITE, AT_FDCWD, + FILE_PATH_ONE) == -1) { + tst_brk(TBROK | TERRNO, + "fanotify_mark(%d, FAN_MARK_ADD, FAN_CLOSE_WRITE, " + "AT_FDCWD, "FILE_PATH_ONE") failed", + nofid_fd); + } + /* Get the filesystem fsid and file handle for each created object */ get_object_stats(); } static void do_cleanup(void) { + SAFE_CLOSE(nofid_fd); if (fanotify_fd > 0) SAFE_CLOSE(fanotify_fd); }