From patchwork Sun May 19 05:26:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Matthew Bobrowski X-Patchwork-Id: 1101515 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="OPcGUoHk"; 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 4569Vv5mn4z9s3Z for ; Sun, 19 May 2019 15:26:31 +1000 (AEST) Received: from picard.linux.it (localhost [IPv6:::1]) by picard.linux.it (Postfix) with ESMTP id 1E5523EA441 for ; Sun, 19 May 2019 07:26:29 +0200 (CEST) X-Original-To: ltp@lists.linux.it Delivered-To: ltp@picard.linux.it Received: from in-3.smtp.seeweb.it (in-3.smtp.seeweb.it [IPv6:2001:4b78:1:20::3]) by picard.linux.it (Postfix) with ESMTP id 06B783EA441 for ; Sun, 19 May 2019 07:26:27 +0200 (CEST) Received: from mail-pl1-x641.google.com (mail-pl1-x641.google.com [IPv6:2607:f8b0:4864:20::641]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by in-3.smtp.seeweb.it (Postfix) with ESMTPS id 0C6E51A00EED for ; Sun, 19 May 2019 07:26:26 +0200 (CEST) Received: by mail-pl1-x641.google.com with SMTP id f97so5181662plb.5 for ; Sat, 18 May 2019 22:26:25 -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=OyDU7cjg2B1Qr52Qaxu+gjf1vmW0JFqvbCm/ocS+RuI=; b=OPcGUoHkhRcPlN/kHQYQ4LJx8/+6sSqQ8EJCQEbTkQMjiBB0A1Cd7fcV984o6IZQXO R+iILan1dm0Y/BeXtKWXJBGPjcbbYJtYYYOzu8kbWkPJbpuE65YnctvtGLHOVN72vUJn xBgFh2AuEKlbvtrh6w3LLDgfeaK2Z/GEA25Lyf+nThIgjZ60LshDA3Ajl46oKUc1Rsvg Aq5iAq0sUqkx11TknsvFQS+klb5r+/6VoShY8zjzDBaGl70gLAqB51JrDdcmYDFhY23/ SuebmP8DVoMzgmiRv+tlZooJE+yp1MK0jv6Vq2JRDmBgdp39BxDUB0GFNSteg7LCZ/mh 65VA== 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=OyDU7cjg2B1Qr52Qaxu+gjf1vmW0JFqvbCm/ocS+RuI=; b=e/zL01JFoFmwViTH3ip7Tn7/NkIp3e/+DgQYBe7TpVxqIEVqo/Dookn0S+ffhITVtj UQTrZfxhTpNfzlc4p9f7c3ibnzJOE3c8aFLFomaSBsthiaLz8Cm2Xs3Xs6etMITmDX8R TvEE0kNrCN8f/2ffei4MuYODha8rbck+iZVLwD8L9bb+8ccUBSdEqDA4rEl99HMv8vHY z2EpZvVK+gr6RzNNWtuUFoMuts6KuBI36nLXuHt156OX96tRUTX1c/BrY2JhLTndrPyr BKxz7nbVkgHw3lDEHEf3swS82SNm1iMMBYnn7atCEaSvmLnpZDtYyjgtz/YYiYDN/A3g OKzg== X-Gm-Message-State: APjAAAXQ12YtGPrin5wAgcPaaiGIxhjS2NdLv8rlk0xMEMARyNvNwnBJ IzEIMe2QMT/r8TfopVZKt4ZGhB3yyA== X-Google-Smtp-Source: APXvYqyK4LbGeOINITGdg0IJBq9Hkc44T44NjIqQtEqRQXeerEwO/289FS379qWJ1dn5TIpiO1Bxhw== X-Received: by 2002:a17:902:8c8c:: with SMTP id t12mr68434850plo.116.1558243584156; Sat, 18 May 2019 22:26:24 -0700 (PDT) Received: from poseidon.Home (n114-74-156-190.sbr2.nsw.optusnet.com.au. [114.74.156.190]) by smtp.gmail.com with ESMTPSA id a18sm22393894pfr.22.2019.05.18.22.26.20 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Sat, 18 May 2019 22:26:23 -0700 (PDT) Date: Sun, 19 May 2019 15:26:15 +1000 From: Matthew Bobrowski To: ltp@lists.linux.it Message-ID: <52fcc83b7fee6ba8d3499297fca4311e3fe74906.1558242368.git.mbobrowski@mbobrowski.org> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.11.3 (2019-02-01) X-Virus-Scanned: clamav-milter 0.99.2 at in-3.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-3.smtp.seeweb.it Cc: jack@suse.cz Subject: [LTP] [PATCH v3 3/3] 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 added. A new line entry within the runtest/syscalls file has been also added to support this new test file. Signed-off-by: Matthew Bobrowski Reviewed-by: Amir Goldstein --- runtest/syscalls | 1 + testcases/kernel/syscalls/fanotify/.gitignore | 1 + .../kernel/syscalls/fanotify/fanotify15.c | 245 ++++++++++++++++++ 3 files changed, 247 insertions(+) create mode 100644 testcases/kernel/syscalls/fanotify/fanotify15.c diff --git a/runtest/syscalls b/runtest/syscalls index 5c62895b0..2f9f14736 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -539,6 +539,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..02f3b34ab --- /dev/null +++ b/testcases/kernel/syscalls/fanotify/fanotify15.c @@ -0,0 +1,245 @@ +// 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_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_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_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, + .setup = do_setup, + .test_all = do_test, + .cleanup = do_cleanup +}; + +#else + TST_TEST_CONF("System does not have required fanotify support"); +#endif