From patchwork Sun Nov 25 13:43:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10696837 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B7A605A4 for ; Sun, 25 Nov 2018 13:44:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A701F2916A for ; Sun, 25 Nov 2018 13:44:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9B93D291E8; Sun, 25 Nov 2018 13:44:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 0BA382916A for ; Sun, 25 Nov 2018 13:44:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726388AbeKZAf0 (ORCPT ); Sun, 25 Nov 2018 19:35:26 -0500 Received: from mail-wr1-f67.google.com ([209.85.221.67]:40644 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726356AbeKZAfZ (ORCPT ); Sun, 25 Nov 2018 19:35:25 -0500 Received: by mail-wr1-f67.google.com with SMTP id p4so16223909wrt.7 for ; Sun, 25 Nov 2018 05:44:18 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=oLYSAqQuByVHL5yCkuqvqx0tgI+e4ugqmeVtjf7caVw=; b=JFrRcjDyGtyx3MI8l8gBk9aLPvpk8axoRYhwGAxVbppDMe1J4gYJa49ddHRydHK+Gs 9/Rpsd7OB9zThT+CBzKjoKaK8a3nBtrf99yHYNoDgRGfuhIZg+udQn+VAKJE/e6VxLKx cXBr5bYWO7xkQjktYzeGHZMNzgkW1bJMD1PRCGdMqQfXtyqkOeaZD8ty4r34uk8tk7Ao EX+Q23Gh5VEDAuRYq9bhlwvoY7T1BpbEbYtbunnbOA7+hO2/FwuOIis0jfzH7y22buOS iSBBWjITwkWdxSh9A3dkzzGm5V2ZniwYDy+j560JrRsQxDhLz+MS8zwxvMOE0+dCACEI EC7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=oLYSAqQuByVHL5yCkuqvqx0tgI+e4ugqmeVtjf7caVw=; b=BR5aYXX+8dSbiktqkAC2rzrplCemuwCQJiI7j2VfuGEiGC7ibJ+UhTAg7bgPnVDW2f sG+metTntyzpEEJ6jeEUCR0qwdDJxX4vr4mVrpK38rzPLX4g2Q9vch0X6Zl0Fs2cfhx1 IzEnj792kKbhvo3f6lr30nnMBcKyWXmYkPp5GGnxEJy9+2YNz+QyeOYzuV6HAqcnViQJ zzdY2cxNCdaBKuZ/T+f4dp79hPuZCsESQjA7x6B0QxMD7wyY6+czNSSmAAyIyKh8haJP klaqCc03WtoASv3HiCacDyqVa/jM8yAqOBJS4eh2CvB8IGuAa5ng4YjoPOG2w0rKqicj e8CA== X-Gm-Message-State: AA+aEWadbLATNP+LrNYyh6pdnltvhOCxnkR6o9g9I7YqFCTK9L929uVV 8q3BtWVQ9RRVxnPq43d7nujndxyQ X-Google-Smtp-Source: AFSGD/X6fAiVXv1+rpYdQYViGkc+PRcXUX3ZYeDVwmpKiL/Zup0WtsOOmbgqbSrg9FUy0d+601QpQg== X-Received: by 2002:a5d:4a8e:: with SMTP id o14mr19496935wrq.159.1543153457645; Sun, 25 Nov 2018 05:44:17 -0800 (PST) Received: from localhost.localdomain (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id 125sm17354274wml.35.2018.11.25.05.44.16 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 25 Nov 2018 05:44:17 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: Matthew Bobrowski , linux-fsdevel@vger.kernel.org Subject: [PATCH v3 07/13] fanotify: copy event fid info to user Date: Sun, 25 Nov 2018 15:43:46 +0200 Message-Id: <20181125134352.21499-8-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181125134352.21499-1-amir73il@gmail.com> References: <20181125134352.21499-1-amir73il@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP If group requested FAN_REPORT_FID and event has file identifier copy that information to user reading the event after reading event metadata. metadata->event_len includes the length of the fid information. Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.h | 3 ++ fs/notify/fanotify/fanotify_user.c | 72 +++++++++++++++++++++++++++--- 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index a79dcbd41702..0e57fa0674d7 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -10,6 +10,9 @@ extern struct kmem_cache *fanotify_perm_event_cachep; /* The size of the variable length buffer storing fsid and file handle */ #define FANOTIFY_FID_LEN(handle_bytes) \ (sizeof(struct fanotify_event_fid) + (handle_bytes)) +#define FANOTIFY_FID_INFO_LEN(event) \ + (sizeof(struct fanotify_event_info) + \ + FANOTIFY_FID_LEN((event)->info.fid->handle_bytes)) struct fanotify_info { struct fanotify_event_fid *fid; diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 47e8bf3bcd28..ea8e81a3e80b 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -47,6 +47,16 @@ struct kmem_cache *fanotify_mark_cache __read_mostly; struct kmem_cache *fanotify_event_cachep __read_mostly; struct kmem_cache *fanotify_perm_event_cachep __read_mostly; +static int round_event_fid_len(struct fsnotify_event *fsn_event) +{ + struct fanotify_event *event = FANOTIFY_E(fsn_event); + + if (!FANOTIFY_HAS_FID(event)) + return 0; + + return roundup(FANOTIFY_FID_INFO_LEN(event), FAN_EVENT_METADATA_LEN); +} + /* * Get an fsnotify notification event if one exists and is small * enough to fit in "count". Return an error pointer if the count @@ -57,6 +67,9 @@ struct kmem_cache *fanotify_perm_event_cachep __read_mostly; static struct fsnotify_event *get_one_event(struct fsnotify_group *group, size_t count) { + size_t event_size = FAN_EVENT_METADATA_LEN; + struct fsnotify_event *event; + assert_spin_locked(&group->notification_lock); pr_debug("%s: group=%p count=%zd\n", __func__, group, count); @@ -64,11 +77,18 @@ static struct fsnotify_event *get_one_event(struct fsnotify_group *group, if (fsnotify_notify_queue_is_empty(group)) return NULL; - if (FAN_EVENT_METADATA_LEN > count) + if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { + event = fsnotify_peek_first_event(group); + event_size += round_event_fid_len(event); + } + + if (event_size > count) return ERR_PTR(-EINVAL); - /* held the notification_lock the whole time, so this is the - * same event we peeked above */ + /* + * Held the notification_lock the whole time, so this is the + * same event we peeked above + */ return fsnotify_remove_first_event(group); } @@ -129,7 +149,7 @@ static int fill_event_metadata(struct fsnotify_group *group, group, metadata, fsn_event); *file = NULL; - event = container_of(fsn_event, struct fanotify_event, fse); + event = FANOTIFY_E(fsn_event); metadata->event_len = FAN_EVENT_METADATA_LEN; metadata->metadata_len = FAN_EVENT_METADATA_LEN; metadata->vers = FANOTIFY_METADATA_VERSION; @@ -139,6 +159,7 @@ static int fill_event_metadata(struct fsnotify_group *group, if (FAN_GROUP_FLAG(group, FAN_REPORT_FID) || unlikely(fsn_event->mask & FAN_Q_OVERFLOW)) { metadata->fd = FAN_NOFD; + metadata->event_len += round_event_fid_len(fsn_event); } else { metadata->fd = create_fd(group, event, file); if (metadata->fd < 0) @@ -208,6 +229,38 @@ static int process_access_response(struct fsnotify_group *group, return 0; } +static int copy_fid_to_user(struct fsnotify_event *fsn_event, char __user *buf) +{ + struct fanotify_event *event = FANOTIFY_E(fsn_event); + struct fanotify_event_info ei; + size_t fid_len; + size_t pad_len = round_event_fid_len(fsn_event); + + if (!pad_len) + return 0; + + /* Copy event info header followed by fid buffer */ + fid_len = FANOTIFY_FID_INFO_LEN(event); + pad_len -= fid_len; + ei.info_type = FAN_EVENT_INFO_TYPE_FID; + ei.reserved = 0; + ei.info_len = fid_len; + if (copy_to_user(buf, &ei, sizeof(ei))) + return -EFAULT; + + buf += sizeof(ei); + fid_len -= sizeof(ei); + if (copy_to_user(buf, event->info.fid, fid_len)) + return -EFAULT; + + /* Pad with 0's */ + buf += fid_len; + if (pad_len && clear_user(buf, pad_len)) + return -EFAULT; + + return 0; +} + static ssize_t copy_event_to_user(struct fsnotify_group *group, struct fsnotify_event *event, char __user *buf) @@ -224,15 +277,20 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, fd = fanotify_event_metadata.fd; ret = -EFAULT; - if (copy_to_user(buf, &fanotify_event_metadata, - fanotify_event_metadata.event_len)) + if (copy_to_user(buf, &fanotify_event_metadata, FAN_EVENT_METADATA_LEN)) goto out_close_fd; if (fanotify_is_perm_event(event->mask)) FANOTIFY_PE(event)->fd = fd; - if (fd != FAN_NOFD) + if (fd != FAN_NOFD) { fd_install(fd, f); + } else if (FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { + ret = copy_fid_to_user(event, buf + FAN_EVENT_METADATA_LEN); + if (ret < 0) + return ret; + } + return fanotify_event_metadata.event_len; out_close_fd: