Skip to content

Commit

Permalink
inotify: hide internal kernel bits from fdinfo
Browse files Browse the repository at this point in the history
There was a report that my patch:

    inotify: actually check for invalid bits in sys_inotify_add_watch()

broke CRIU.

The reason is that CRIU looks up raw flags in /proc/$pid/fdinfo/* to
figure out how to rebuild inotify watches and then passes those flags
directly back in to the inotify API.  One of those flags
(FS_EVENT_ON_CHILD) is set in mark->mask, but is not part of the inotify
API.  It is used inside the kernel to _implement_ inotify but it is not
and has never been part of the API.

My patch above ensured that we only allow bits which are part of the API
(IN_ALL_EVENTS).  This broke CRIU.

FS_EVENT_ON_CHILD is really internal to the kernel.  It is set _anyway_ on
all inotify marks.  So, CRIU was really just trying to set a bit that was
already set.

This patch hides that bit from fdinfo.  CRIU will not see the bit, not try
to set it, and should work as before.  We should not have been exposing
this bit in the first place, so this is a good patch independent of the
CRIU problem.

Signed-off-by: Dave Hansen <[email protected]>
Reported-by: Andrey Wagin <[email protected]>
Acked-by: Andrey Vagin <[email protected]>
Acked-by: Cyrill Gorcunov <[email protected]>
Acked-by: Eric Paris <[email protected]>
Cc: Pavel Emelyanov <[email protected]>
Cc: John McCutchan <[email protected]>
Cc: Robert Love <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
hansendc authored and torvalds committed Nov 6, 2015
1 parent 8e483ed commit 6933599
Showing 1 changed file with 8 additions and 1 deletion.
9 changes: 8 additions & 1 deletion fs/notify/fdinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,16 @@ static void inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark);
inode = igrab(mark->inode);
if (inode) {
/*
* IN_ALL_EVENTS represents all of the mask bits
* that we expose to userspace. There is at
* least one bit (FS_EVENT_ON_CHILD) which is
* used only internally to the kernel.
*/
u32 mask = mark->mask & IN_ALL_EVENTS;
seq_printf(m, "inotify wd:%x ino:%lx sdev:%x mask:%x ignored_mask:%x ",
inode_mark->wd, inode->i_ino, inode->i_sb->s_dev,
mark->mask, mark->ignored_mask);
mask, mark->ignored_mask);
show_mark_fhandle(m, inode);
seq_putc(m, '\n');
iput(inode);
Expand Down

0 comments on commit 6933599

Please sign in to comment.