Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0d6ec079 authored by Miklos Szeredi's avatar Miklos Szeredi Committed by Jan Kara
Browse files

fsnotify: pin both inode and vfsmount mark



We may fail to pin one of the marks in fsnotify_prepare_user_wait() when
dropping the srcu read lock, resulting in use after free at the next
iteration.

Solution is to store both marks in iter_info instead of just the one we'll
be sending the event for.

Reviewed-by: default avatarAmir Goldstein <amir73il@gmail.com>
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
Fixes: 9385a84d ("fsnotify: Pass fsnotify_iter_info into handle_event handler")
Cc: <stable@vger.kernel.org> # v4.12
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent 24c20305
Loading
Loading
Loading
Loading
+7 −3
Original line number Original line Diff line number Diff line
@@ -335,6 +335,13 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
						    struct fsnotify_mark, obj_list);
						    struct fsnotify_mark, obj_list);
			vfsmount_group = vfsmount_mark->group;
			vfsmount_group = vfsmount_mark->group;
		}
		}
		/*
		 * Need to protect both marks against freeing so that we can
		 * continue iteration from this place, regardless of which mark
		 * we actually happen to send an event for.
		 */
		iter_info.inode_mark = inode_mark;
		iter_info.vfsmount_mark = vfsmount_mark;


		if (inode_group && vfsmount_group) {
		if (inode_group && vfsmount_group) {
			int cmp = fsnotify_compare_groups(inode_group,
			int cmp = fsnotify_compare_groups(inode_group,
@@ -348,9 +355,6 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is,
			}
			}
		}
		}


		iter_info.inode_mark = inode_mark;
		iter_info.vfsmount_mark = vfsmount_mark;

		ret = send_to_group(to_tell, inode_mark, vfsmount_mark, mask,
		ret = send_to_group(to_tell, inode_mark, vfsmount_mark, mask,
				    data, data_is, cookie, file_name,
				    data, data_is, cookie, file_name,
				    &iter_info);
				    &iter_info);