From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, Jan Kara <jack@suse.cz>,
Miklos Szeredi <mszeredi@redhat.com>,
Andrew Morton <akpm@linux-foundation.org>,
Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH 4.4 48/73] fanotify: fix list corruption in fanotify_get_response()
Date: Wed, 28 Sep 2016 11:05:18 +0200 [thread overview]
Message-ID: <20160928090437.777389919@linuxfoundation.org> (raw)
In-Reply-To: <20160928090434.509091655@linuxfoundation.org>
4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Kara <jack@suse.cz>
commit 96d41019e3ac55f6f0115b0ce97e4f24a3d636d2 upstream.
fanotify_get_response() calls fsnotify_remove_event() when it finds that
group is being released from fanotify_release() (bypass_perm is set).
However the event it removes need not be only in the group's notification
queue but it can have already moved to access_list (userspace read the
event before closing the fanotify instance fd) which is protected by a
different lock. Thus when fsnotify_remove_event() races with
fanotify_release() operating on access_list, the list can get corrupted.
Fix the problem by moving all the logic removing permission events from
the lists to one place - fanotify_release().
Fixes: 5838d4442bd5 ("fanotify: fix double free of pending permission events")
Link: http://lkml.kernel.org/r/1473797711-14111-3-git-send-email-jack@suse.cz
Signed-off-by: Jan Kara <jack@suse.cz>
Reported-by: Miklos Szeredi <mszeredi@redhat.com>
Tested-by: Miklos Szeredi <mszeredi@redhat.com>
Reviewed-by: Miklos Szeredi <mszeredi@redhat.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/notify/fanotify/fanotify.c | 13 +------------
fs/notify/fanotify/fanotify_user.c | 36 ++++++++++++++++++++++++------------
fs/notify/notification.c | 15 ---------------
include/linux/fsnotify_backend.h | 3 ---
4 files changed, 25 insertions(+), 42 deletions(-)
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -67,18 +67,7 @@ static int fanotify_get_response(struct
pr_debug("%s: group=%p event=%p\n", __func__, group, event);
- wait_event(group->fanotify_data.access_waitq, event->response ||
- atomic_read(&group->fanotify_data.bypass_perm));
-
- if (!event->response) { /* bypass_perm set */
- /*
- * Event was canceled because group is being destroyed. Remove
- * it from group's event list because we are responsible for
- * freeing the permission event.
- */
- fsnotify_remove_event(group, &event->fae.fse);
- return 0;
- }
+ wait_event(group->fanotify_data.access_waitq, event->response);
/* userspace responded, convert to something usable */
switch (event->response) {
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -358,16 +358,20 @@ static int fanotify_release(struct inode
#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
struct fanotify_perm_event_info *event, *next;
+ struct fsnotify_event *fsn_event;
/*
- * There may be still new events arriving in the notification queue
- * but since userspace cannot use fanotify fd anymore, no event can
- * enter or leave access_list by now.
+ * Stop new events from arriving in the notification queue. since
+ * userspace cannot use fanotify fd anymore, no event can enter or
+ * leave access_list by now either.
*/
- spin_lock(&group->fanotify_data.access_lock);
-
- atomic_inc(&group->fanotify_data.bypass_perm);
+ fsnotify_group_stop_queueing(group);
+ /*
+ * Process all permission events on access_list and notification queue
+ * and simulate reply from userspace.
+ */
+ spin_lock(&group->fanotify_data.access_lock);
list_for_each_entry_safe(event, next, &group->fanotify_data.access_list,
fae.fse.list) {
pr_debug("%s: found group=%p event=%p\n", __func__, group,
@@ -379,12 +383,21 @@ static int fanotify_release(struct inode
spin_unlock(&group->fanotify_data.access_lock);
/*
- * Since bypass_perm is set, newly queued events will not wait for
- * access response. Wake up the already sleeping ones now.
- * synchronize_srcu() in fsnotify_destroy_group() will wait for all
- * processes sleeping in fanotify_handle_event() waiting for access
- * response and thus also for all permission events to be freed.
+ * Destroy all non-permission events. For permission events just
+ * dequeue them and set the response. They will be freed once the
+ * response is consumed and fanotify_get_response() returns.
*/
+ mutex_lock(&group->notification_mutex);
+ while (!fsnotify_notify_queue_is_empty(group)) {
+ fsn_event = fsnotify_remove_first_event(group);
+ if (!(fsn_event->mask & FAN_ALL_PERM_EVENTS))
+ fsnotify_destroy_event(group, fsn_event);
+ else
+ FANOTIFY_PE(fsn_event)->response = FAN_ALLOW;
+ }
+ mutex_unlock(&group->notification_mutex);
+
+ /* Response for all permission events it set, wakeup waiters */
wake_up(&group->fanotify_data.access_waitq);
#endif
@@ -755,7 +768,6 @@ SYSCALL_DEFINE2(fanotify_init, unsigned
spin_lock_init(&group->fanotify_data.access_lock);
init_waitqueue_head(&group->fanotify_data.access_waitq);
INIT_LIST_HEAD(&group->fanotify_data.access_list);
- atomic_set(&group->fanotify_data.bypass_perm, 0);
#endif
switch (flags & FAN_ALL_CLASS_BITS) {
case FAN_CLASS_NOTIF:
--- a/fs/notify/notification.c
+++ b/fs/notify/notification.c
@@ -132,21 +132,6 @@ queue:
}
/*
- * Remove @event from group's notification queue. It is the responsibility of
- * the caller to destroy the event.
- */
-void fsnotify_remove_event(struct fsnotify_group *group,
- struct fsnotify_event *event)
-{
- mutex_lock(&group->notification_mutex);
- if (!list_empty(&event->list)) {
- list_del_init(&event->list);
- group->q_len--;
- }
- mutex_unlock(&group->notification_mutex);
-}
-
-/*
* Remove and return the first event from the notification list. It is the
* responsibility of the caller to destroy the obtained event
*/
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -180,7 +180,6 @@ struct fsnotify_group {
spinlock_t access_lock;
struct list_head access_list;
wait_queue_head_t access_waitq;
- atomic_t bypass_perm;
#endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */
int f_flags;
unsigned int max_marks;
@@ -323,8 +322,6 @@ extern int fsnotify_add_event(struct fsn
struct fsnotify_event *event,
int (*merge)(struct list_head *,
struct fsnotify_event *));
-/* Remove passed event from groups notification queue */
-extern void fsnotify_remove_event(struct fsnotify_group *group, struct fsnotify_event *event);
/* true if the group notification queue is empty */
extern bool fsnotify_notify_queue_is_empty(struct fsnotify_group *group);
/* return, but do not dequeue the first event on the notification queue */
next prev parent reply other threads:[~2016-09-28 9:31 UTC|newest]
Thread overview: 69+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20160928090623uscas1p1076bd85a3fd981ed5a1284f5bebb1bbf@uscas1p1.samsung.com>
2016-09-28 9:04 ` [PATCH 4.4 00/73] 4.4.23-stable review Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 01/73] include/linux/kernel.h: change abs() macro so it uses consistent return type Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 02/73] Fix build warning in kernel/cpuset.c Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 03/73] reiserfs: fix "new_insert_key may be used uninitialized ..." Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 09/73] crypto: arm64/aes-ctr - fix NULL dereference in tail processing Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 10/73] crypto: arm/aes-ctr " Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 11/73] crypto: skcipher - Fix blkcipher walk OOM crash Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 12/73] crypto: echainiv - Replace chaining with multiplication Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 13/73] ocfs2/dlm: fix race between convert and migration Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 14/73] ocfs2: fix start offset to ocfs2_zero_range_for_truncate() Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 15/73] kbuild: Do not run modules_install and install in paralel Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 16/73] Makefile: revert "Makefile: Document ability to make file.lst and file.S" partially Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 17/73] tools: Support relative directory path for O= Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 18/73] kbuild: forbid kernel directory to contain spaces and colons Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 19/73] Kbuild: disable maybe-uninitialized warning for CONFIG_PROFILE_ALL_BRANCHES Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 20/73] gcov: disable -Wmaybe-uninitialized warning Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 21/73] Disable "maybe-uninitialized" warning globally Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 23/73] Makefile: Mute warning for __builtin_return_address(>0) for tracing only Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 24/73] net: caif: fix misleading indentation Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 26/73] [media] am437x-vfpe: fix typo in vpfe_get_app_input_index Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 27/73] ath9k: fix misleading indentation Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 28/73] iwlegacy: avoid warning about missing braces Greg Kroah-Hartman
2016-09-28 9:04 ` [PATCH 4.4 29/73] Staging: iio: adc: fix indent on break statement Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 30/73] nouveau: fix nv40_perfctr_next() cleanup regression Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 31/73] megaraid: fix null pointer check in megasas_detach_one() Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 32/73] bonding: Fix bonding crash Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 33/73] Revert "af_unix: Fix splice-bind deadlock" Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 34/73] af_unix: split u->readlock into two: iolock and bindlock Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 35/73] vti: flush x-netns xfrm cache when vti interface is removed Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 36/73] net/irda: handle iriap_register_lsap() allocation failure Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 37/73] tipc: fix NULL pointer dereference in shutdown() Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 38/73] net/mlx5: Added missing check of msg length in verifying its signature Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 39/73] net: dsa: bcm_sf2: Fix race condition while unmasking interrupts Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 40/73] Revert "phy: IRQ cannot be shared" Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 41/73] net: smc91x: fix SMC accesses Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 42/73] bridge: re-introduce fix parsing of MLDv2 reports Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 43/73] pwm: Mark all devices as "might sleep" Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 44/73] autofs races Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 45/73] autofs: use dentry flags to block walks during expire Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 46/73] xfs: prevent dropping ioend completions during buftarg wait Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 47/73] fsnotify: add a way to stop queueing events on group shutdown Greg Kroah-Hartman
2016-09-28 9:05 ` Greg Kroah-Hartman [this message]
2016-09-28 9:05 ` [PATCH 4.4 49/73] fix fault_in_multipages_...() on architectures with no-op access_ok() Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 50/73] mtd: maps: sa1100-flash: potential NULL dereference Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 51/73] mtd: pmcmsp-flash: Allocating too much in init_msp_flash() Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 52/73] power: reset: hisi-reboot: Unmap region obtained by of_iomap Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 53/73] fix memory leaks in tracing_buffers_splice_read() Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 54/73] tracing: Move mutex to protect against resetting of seq data Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 55/73] mm: delete unnecessary and unsafe init_tlb_ubc() Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 56/73] can: flexcan: fix resume function Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 57/73] nl80211: validate number of probe response CSA counters Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 58/73] btrfs: ensure that file descriptor used with subvol ioctls is a dir Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 59/73] i2c-eg20t: fix race between i2c init and interrupt enable Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 60/73] i2c: qup: skip qup_i2c_suspend if the device is already runtime suspended Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 61/73] MIPS: Fix pre-r6 emulation FPU initialisation Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 63/73] MIPS: vDSO: Fix Malta EVA mapping to vDSO page structs Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 64/73] MIPS: Remove compact branch policy Kconfig entries Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 65/73] MIPS: Avoid a BUG warning during prctl(PR_SET_FP_MODE, ...) Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 66/73] MIPS: Add a missing ".set pop" in an early commit Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 67/73] MIPS: paravirt: Fix undefined reference to smp_bootstrap Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 68/73] PM / hibernate: Restore processor state before using per-CPU variables Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 69/73] PM / hibernate: Fix rtree_next_node() to avoid walking off list ends Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 70/73] power_supply: tps65217-charger: fix missing platform_set_drvdata() Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 71/73] power: supply: max17042_battery: fix model download bug Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 72/73] qxl: check for kmap failures Greg Kroah-Hartman
2016-09-28 9:05 ` [PATCH 4.4 73/73] hostfs: Freeing an ERR_PTR in hostfs_fill_sb_common() Greg Kroah-Hartman
2016-09-28 16:45 ` [PATCH 4.4 00/73] 4.4.23-stable review Shuah Khan
2016-09-28 22:43 ` Guenter Roeck
[not found] ` <57ec0f9e.07ddc20a.146f7.4be3@mx.google.com>
2016-09-29 9:01 ` Greg Kroah-Hartman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160928090437.777389919@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=akpm@linux-foundation.org \
--cc=jack@suse.cz \
--cc=linux-kernel@vger.kernel.org \
--cc=mszeredi@redhat.com \
--cc=stable@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox