From patchwork Thu Nov 15 18:45:40 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10684847 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 A315113BF for ; Thu, 15 Nov 2018 18:46:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 90C972CF57 for ; Thu, 15 Nov 2018 18:46:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 855982CF59; Thu, 15 Nov 2018 18:46:02 +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 0A4B32CF57 for ; Thu, 15 Nov 2018 18:46:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388779AbeKPEy5 (ORCPT ); Thu, 15 Nov 2018 23:54:57 -0500 Received: from mail-wr1-f67.google.com ([209.85.221.67]:40858 "EHLO mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726910AbeKPEy4 (ORCPT ); Thu, 15 Nov 2018 23:54:56 -0500 Received: by mail-wr1-f67.google.com with SMTP id p4so13155774wrt.7; Thu, 15 Nov 2018 10:45:59 -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=sgnpXr9g10nqhMSYhrLX2Y1JXlAYakbN6nbGcs8xlV8=; b=a31o+NlIiP6+yljJqPDQeBHY91sZXNXMh3vXV+pAkWyRxAxVs9fDtgbWrK3RSd6oWN LQ0n95vtOqyylZlWuI/FEkXnIdzZnoea+wLhpjUsNQk+WEeSwFS3KcWEuDOvlLI+MFYT h1iHfmN6Q2DsQWTaA7fo9IEksBsGxK0tSu4dypIuL+VYdh+lS55/1CFTcy8nmufQ+0QG 0bit3OnOm9ieNvlVJmmZrtbKY8ztHHgRQIEot9sx48DsHhUscR2eJbl0JicEvKONv8y9 xScZ/lInBJ09pujv4PIoNdZ8hXCOCip0I8lO7rI4pjknGOgwwWFJfOexxOD6V3QxQv/7 jaew== 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=sgnpXr9g10nqhMSYhrLX2Y1JXlAYakbN6nbGcs8xlV8=; b=Le/Ct5Q/RtK33sPiRiUCC3e/FRRWsY9snd8MoxcTq7JAjp4E9aDJVf71OLBwg/g9Dk dc/5qmNZj2wDO4Fpof/Fwya/KunHcbCkHjKLmJYDOtImVJhSRqbtpLjqQoJTqdi/cE/j VYhfYBETKT73XzRiig2DwvTKXCnrv8SRIZ7CV08S6RbmYp9nCeh1MknkFax1G4+qtjrb SZJIQ28Y5mj8sap2kEAj1fg2M2wFSb7xURs/za/XJ8FpA2nzqRRzi+3D3NaSWCFfd9C5 mRwKvp50XT/zTWLpd8XIlRgUOv4KsTq31pKOnH+OWh1IxwzFhtFO4/ucde+IUC/dTWMG v02Q== X-Gm-Message-State: AA+aEWaSJLiXrT2aQIE0pTNmGXy/ucqgVs1v9jUIMHpmbb67PHsC7F1x bU1m1m3j08MpDoAvtA/iCcX7GitH X-Google-Smtp-Source: AFSGD/UILVtZxOI/hjMegTYIASfAlZJKFjuLMOjyNs1m51963Vtrb6gc7YO1mmWy0tiXHBKmr1DdMw== X-Received: by 2002:a5d:454b:: with SMTP id p11-v6mr2580266wrr.86.1542307558136; Thu, 15 Nov 2018 10:45:58 -0800 (PST) Received: from localhost.localdomain ([37.46.46.74]) by smtp.gmail.com with ESMTPSA id s1sm13976327wro.9.2018.11.15.10.45.56 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 Nov 2018 10:45:57 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: Matthew Bobrowski , linux-fsdevel@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v2 5/9] fanotify: copy event fid info to user Date: Thu, 15 Nov 2018 20:45:40 +0200 Message-Id: <20181115184544.30681-6-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20181115184544.30681-1-amir73il@gmail.com> References: <20181115184544.30681-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 d6ed31134321..26752d2f2bd6 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 29f61060af66..7e38d7a1854b 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: