From patchwork Sun Nov 25 13:43:43 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10696833 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 ECB505A4 for ; Sun, 25 Nov 2018 13:44:19 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DBDC82916A for ; Sun, 25 Nov 2018 13:44:19 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CFF96291E8; Sun, 25 Nov 2018 13:44:19 +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 45D232916A for ; Sun, 25 Nov 2018 13:44:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726328AbeKZAfY (ORCPT ); Sun, 25 Nov 2018 19:35:24 -0500 Received: from mail-wm1-f68.google.com ([209.85.128.68]:50275 "EHLO mail-wm1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726098AbeKZAfY (ORCPT ); Sun, 25 Nov 2018 19:35:24 -0500 Received: by mail-wm1-f68.google.com with SMTP id 125so15683388wmh.0; Sun, 25 Nov 2018 05:44:14 -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=8+cQjiz/ZgvKrpljk5Ok06qoHeL/JeQEBfa4cj+EC1E=; b=uYrNMXqATyBmEOwUKtMi+GwV3lX+5VgiXFYyogGriAsDX1wo45hdDCK7pn0/EXszaC wABMQ6jCXSG9ll0stFebOgwRJvdcMW2KRA4zEEQHAWSt+Q1e++tOvx2QZkkPwHYYvoAr gHSi2XvPr6UJEWFehpvQv0VFTGXd+HMn6Z3VmGA7EASHhm/z1Qcj0kKZK/1NY8P21Ptv sZ7zufkMVnS6Uh9c1KXc42wlxfVsYzcWcojyP7504AkZLNB7C001cp+BA63iNNdWmsO5 UiOK7bCGBvwsR+RivO51KWaySegS3AT5o7Bnajddg314WOkjGhjKC8Q72xipDSNOmA9I dg6Q== 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=8+cQjiz/ZgvKrpljk5Ok06qoHeL/JeQEBfa4cj+EC1E=; b=HzSEBRk85SUE3bOFQxhK/C710Z2Zr1IefsuQh4XDqVt2zIR2BomE1xyaHDSY/DUDBu Wx2xrbGlSaGmCwYJv2ij5L40V7j6awGvD/TrXe3aI/AgcNfwyPL3QtmNWEZW5wU6IYMc iYez4CC0FR8Dp6o5KdA5qTdQh/IWdA6h8BrYDcmDQ7yw90eG9H3P8BPJdOYL94ecpGfl cXKF7rLJ9jgblOsMbNqeRr15yuNFtBbG9qZRBlE7ykzj3vp/LN6lDk0eF64e+XrqTZvl vBEDlvGRrSVaugDfvGpfJQsE5smsxTNmdhve7lUDBDNINs8uzxfcsSZ1UtCXcalKn0H5 RU6Q== X-Gm-Message-State: AA+aEWaZsT5lG42HlZDfvK+mBMWAb6a8ASXwwRWZ5t2HOAktSFRJpzxt 3IsS+qW26k2oHQG5oDo9Qk4= X-Google-Smtp-Source: AJdET5eBHygBbx9nrIokPB7rd/v/ig6VlYxlMLNOYOxvTmeAG8mf13IcAHte7oYjbnS4InL/Qonv8g== X-Received: by 2002:a1c:e354:: with SMTP id a81mr19960423wmh.120.1543153454107; Sun, 25 Nov 2018 05:44:14 -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.12 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 25 Nov 2018 05:44:13 -0800 (PST) From: Amir Goldstein To: Jan Kara Cc: Matthew Bobrowski , linux-fsdevel@vger.kernel.org, linux-api@vger.kernel.org Subject: [PATCH v3 04/13] fanotify: define the structures to report a unique file identifier Date: Sun, 25 Nov 2018 15:43:43 +0200 Message-Id: <20181125134352.21499-5-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 When user requests the flag FAN_REPORT_FID in fanotify_init(), a unique file indetifier of the event target object will be reported with the event. This commit only defines the internal and user visible structures used to store and report the unique file identifier. The file identifier includes the filesystem's fsid (i.e. from statfs(2)) and an NFS file handle of the file (i.e. from name_to_handle_at(2)). The file identifier makes holding the path reference and passing a file descriptor to user redundant, so those are disabled in a group with FAN_REPORT_FID. Cc: Signed-off-by: Amir Goldstein --- fs/notify/fanotify/fanotify.c | 2 +- fs/notify/fanotify/fanotify.h | 26 ++++++++++++++++---- fs/notify/fanotify/fanotify_user.c | 5 ++-- include/uapi/linux/fanotify.h | 38 +++++++++++++++++++++++++----- 4 files changed, 57 insertions(+), 14 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index ecd5f4aec624..59d093923c97 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -178,7 +178,7 @@ init: __maybe_unused event->pid = get_pid(task_pid(current)); else event->pid = get_pid(task_tgid(current)); - if (path) { + if (path && !FAN_GROUP_FLAG(group, FAN_REPORT_FID)) { event->path = *path; path_get(&event->path); } else { diff --git a/fs/notify/fanotify/fanotify.h b/fs/notify/fanotify/fanotify.h index fb84dd3289f8..2e4fca30afda 100644 --- a/fs/notify/fanotify/fanotify.h +++ b/fs/notify/fanotify/fanotify.h @@ -7,6 +7,14 @@ extern struct kmem_cache *fanotify_mark_cache; extern struct kmem_cache *fanotify_event_cachep; 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)) + +struct fanotify_info { + struct fanotify_event_fid *fid; +}; + /* * Structure for normal fanotify events. It gets allocated in * fanotify_handle_event() and freed when the information is retrieved by @@ -14,11 +22,19 @@ extern struct kmem_cache *fanotify_perm_event_cachep; */ struct fanotify_event { struct fsnotify_event fse; - /* - * We hold ref to this path so it may be dereferenced at any point - * during this object's lifetime - */ - struct path path; + union { + /* + * We hold ref to this path so it may be dereferenced at any + * point during this object's lifetime + */ + struct path path; + /* + * With FAN_REPORT_FID, we do not hold any reference on the + * victim object. Instead we store its NFS file handle and its + * filesystem's fsid as a unique identifier. + */ + struct fanotify_info info; + }; struct pid *pid; }; diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 2dbb2662a92f..93e1aa2a389f 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c @@ -133,9 +133,10 @@ static int fill_event_metadata(struct fsnotify_group *group, metadata->reserved = 0; metadata->mask = fsn_event->mask & FANOTIFY_OUTGOING_EVENTS; metadata->pid = pid_vnr(event->pid); - if (unlikely(fsn_event->mask & FAN_Q_OVERFLOW)) + if (FAN_GROUP_FLAG(group, FAN_REPORT_FID) || + unlikely(fsn_event->mask & FAN_Q_OVERFLOW)) { metadata->fd = FAN_NOFD; - else { + } else { metadata->fd = create_fd(group, event, file); if (metadata->fd < 0) ret = metadata->fd; diff --git a/include/uapi/linux/fanotify.h b/include/uapi/linux/fanotify.h index 909c98fcace2..0fd8736269c4 100644 --- a/include/uapi/linux/fanotify.h +++ b/include/uapi/linux/fanotify.h @@ -44,6 +44,7 @@ /* Flags to determine fanotify event format */ #define FAN_REPORT_TID 0x00000100 /* event->pid is thread id */ +#define FAN_REPORT_FID 0x00000200 /* Report unique file id */ /* Deprecated - do not use this in programs and do not add new flags here! */ #define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | \ @@ -106,6 +107,24 @@ struct fanotify_event_metadata { __s32 pid; }; +#define FAN_EVENT_INFO_TYPE_FID 1 + +/* Variable length info record header following event metadata */ +struct fanotify_event_info { + __u8 info_type; + __u8 reserved; + __u16 info_len; + unsigned char info[0]; +}; + +/* Unique file identifier info record */ +struct fanotify_event_fid { + __kernel_fsid_t fsid; + __u32 handle_bytes; + __s32 handle_type; + unsigned char f_handle[0]; +}; + struct fanotify_response { __s32 fd; __u32 response; @@ -122,12 +141,19 @@ struct fanotify_response { /* Helper functions to deal with fanotify_event_metadata buffers */ #define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata)) -#define FAN_EVENT_NEXT(meta, len) ((len) -= (meta)->event_len, \ - (struct fanotify_event_metadata*)(((char *)(meta)) + \ - (meta)->event_len)) +#define FAN_EVENT_NEXT(meta, len) \ + ((len) -= (meta)->event_len, \ + (struct fanotify_event_metadata *)(((char *)(meta)) + \ + (meta)->event_len)) + +#define FAN_EVENT_OK(meta, len) \ + ((long)(len) >= (long)FAN_EVENT_METADATA_LEN && \ + (long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && \ + (long)(meta)->event_len <= (long)(len)) -#define FAN_EVENT_OK(meta, len) ((long)(len) >= (long)FAN_EVENT_METADATA_LEN && \ - (long)(meta)->event_len >= (long)FAN_EVENT_METADATA_LEN && \ - (long)(meta)->event_len <= (long)(len)) +/* Get the first event info record if one exists */ +#define FAN_EVENT_INFO(meta) \ + ((long)(meta)->event_len > (long)FAN_EVENT_METADATA_LEN ? \ + (struct fanotify_event_info *)((meta) + 1) : NULL) #endif /* _UAPI_LINUX_FANOTIFY_H */