From patchwork Tue Oct 30 18:29:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10661381 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 E96A71932 for ; Tue, 30 Oct 2018 18:30:10 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F30322AA80 for ; Tue, 30 Oct 2018 18:30:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E73BD2AA89; Tue, 30 Oct 2018 18:30:10 +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 7C9432AA80 for ; Tue, 30 Oct 2018 18:30:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727672AbeJaDYn (ORCPT ); Tue, 30 Oct 2018 23:24:43 -0400 Received: from mail-wm1-f65.google.com ([209.85.128.65]:56310 "EHLO mail-wm1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726522AbeJaDYn (ORCPT ); Tue, 30 Oct 2018 23:24:43 -0400 Received: by mail-wm1-f65.google.com with SMTP id s10-v6so12777793wmc.5; Tue, 30 Oct 2018 11:30:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=HdTqnsq6phGC+vSJOWFqlmgLxhDOA3zamLMOrdFx22I=; b=O+oHSuYbKeDGpmPLqPqlxB9xHEBkAvyMFEtmePPc0jYuqFRwRa+1VJ5HR2YbCl5acY R/qmAgax7ca0JbAsYcGfKp0z/Am3UO62ezx3JJwuAgrBoY+LCmGFNqiwIaTjiVE+e4ht NxLL9rAV8bThcwKxaeD+oMBscAVXTKMwl3LNVzbeWxE4nkBsWxwx415VPOYMM7K7TuJw H7NaTO7Q/WIhQtpV51Q+cHG7fCIkEn7yxK+rciFyQw7Lh+9qCCzKdCryyFJxUJwffZ5S xGGZxT0vzG6rBswK4LZKp6CBYizeF5RZjb2lEl5bOXBynfRYOycNdT8QuKfuXrxcCrSw J2Kw== 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; bh=HdTqnsq6phGC+vSJOWFqlmgLxhDOA3zamLMOrdFx22I=; b=jsZgNm3GuixGr6XddeAojKhfXNpt2rdlGolgDfrbk+4eNWJsFOEuoHFtsNXcnzaOIv 3PLGMyNl86oK7qFXkMs4lZZ7frhW3t5i6/lNbVDl78Q90Q0d1+ZgkT4iCsghFwxv+LfB 4ERU626dYEmI3v2R1FuHxsapqUXDpIeNcuiC0McwIDQTsPj8sJfg5RqVFWKA/2CczbEA LONONjcvc4EVryt2lg4CROY+R/q2TQW8NH0X9fuNhCD7nzwD4pQFiiijb19vjuTPQhI6 mrku6+vEpTRK+TNdCMnoLGsx4uVAIOoynR3VjBnfrSiktFCwxTrbvSUc88B0IkhtUCgR peLQ== X-Gm-Message-State: AGRZ1gLKHc0w+4umzA9BBRdkrM6Hl3W10TIkXX3l6FRT/kb1TF42SAyO 7PqZMhJiF47q+wT5hkgJJcE= X-Google-Smtp-Source: AJdET5dqf9r7O57KAh/mqCZ7DBqtETa0T1oCaHth9JoN9mx7Moal+7QB3kUvN3yM3hXyo5SUXlSIug== X-Received: by 2002:a1c:7dd7:: with SMTP id y206-v6mr11482wmc.78.1540924206958; Tue, 30 Oct 2018 11:30:06 -0700 (PDT) Received: from localhost.localdomain ([5.102.239.131]) by smtp.gmail.com with ESMTPSA id n76-v6sm5005912wmd.47.2018.10.30.11.30.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 Oct 2018 11:30:06 -0700 (PDT) From: Amir Goldstein To: Jan Kara Cc: Matthew Bobrowski , linux-fsdevel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH] fanotify: fix handling of events on child sub-directory Date: Tue, 30 Oct 2018 20:29:53 +0200 Message-Id: <20181030182953.1676-1-amir73il@gmail.com> X-Mailer: git-send-email 2.17.1 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 an event is reported on a sub-directory and the parent inode has a mark mask with FS_EVENT_ON_CHILD|FS_ISDIR, the event will be sent to fsnotify() even if the event type is not in the parent mark mask (e.g. FS_OPEN). Further more, if that event happened on a mount or a filesystem with a mount/sb mark that does have that event type in their mask, the "on child" event will be reported on the mount/sb mark. That is not desired, because user will get a duplicate event for the same action. Note that the event reported on the victim inode is never merged with the event reported on the parent inode, because of the check in should_merge(): old_fsn->inode == new_fsn->inode. Fix this by looking for a match of an actual event type (i.e. not just FS_ISDIR) in parent's inode mark mask and by not reporting an "on child" event to group if event type is only found on mount/sb marks. [backport hint: The bug seems to have always been in fanotify, but this patch will only apply cleanly to v4.19.y] Cc: # v4.19 Signed-off-by: Amir Goldstein --- Jan, The bugs with merging directory children mark and mount mark are unfolding slowly. I have extended fanotify09, which checks another bug on this type to also cover this case [1]. Tested that bug existed as far back as v4.10, but I guess it was always there. Thanks, Amir. [1] https://github.com/amir73il/ltp/commits/fanotify_ignore fs/notify/fanotify/fanotify.c | 10 +++++----- fs/notify/fsnotify.c | 7 +++++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 5769cf3ff035..e08a6647267b 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -115,12 +115,12 @@ static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info, continue; mark = iter_info->marks[type]; /* - * if the event is for a child and this inode doesn't care about - * events on the child, don't send it! + * If the event is for a child and this mark doesn't care about + * events on a child, don't send it! */ - if (type == FSNOTIFY_OBJ_TYPE_INODE && - (event_mask & FS_EVENT_ON_CHILD) && - !(mark->mask & FS_EVENT_ON_CHILD)) + if (event_mask & FS_EVENT_ON_CHILD && + (type != FSNOTIFY_OBJ_TYPE_INODE || + !(mark->mask & FS_EVENT_ON_CHILD))) continue; marks_mask |= mark->mask; diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 2172ba516c61..d2c34900ae05 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -167,9 +167,9 @@ int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask parent = dget_parent(dentry); p_inode = parent->d_inode; - if (unlikely(!fsnotify_inode_watches_children(p_inode))) + if (unlikely(!fsnotify_inode_watches_children(p_inode))) { __fsnotify_update_child_dentry_flags(p_inode); - else if (p_inode->i_fsnotify_mask & mask) { + } else if (p_inode->i_fsnotify_mask & mask & ALL_FSNOTIFY_EVENTS) { struct name_snapshot name; /* we are notifying a parent so come up with the new mask which @@ -339,6 +339,9 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, sb = mnt->mnt.mnt_sb; mnt_or_sb_mask = mnt->mnt_fsnotify_mask | sb->s_fsnotify_mask; } + /* An event "on child" is not intended for a mount/sb mark */ + if (mask & FS_EVENT_ON_CHILD) + mnt_or_sb_mask = 0; /* * Optimization: srcu_read_lock() has a memory barrier which can