@@ -502,7 +502,7 @@ static int copy_fid_info_to_user(__kernel_fsid_t *fsid, struct fanotify_fh *fh,
502502 }
503503
504504 /* Pad with 0's */
505- WARN_ON_ONCE (len < 0 || len >= FANOTIFY_EVENT_ALIGN );
505+ WARN_ON_ONCE (len >= FANOTIFY_EVENT_ALIGN );
506506 if (len > 0 && clear_user (buf , len ))
507507 return - EFAULT ;
508508
@@ -1076,15 +1076,15 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
10761076}
10771077
10781078static int fanotify_remove_mark (struct fsnotify_group * group ,
1079- fsnotify_connp_t * connp , __u32 mask ,
1079+ void * obj , unsigned int obj_type , __u32 mask ,
10801080 unsigned int flags , __u32 umask )
10811081{
10821082 struct fsnotify_mark * fsn_mark = NULL ;
10831083 __u32 removed ;
10841084 int destroy_mark ;
10851085
10861086 fsnotify_group_lock (group );
1087- fsn_mark = fsnotify_find_mark (connp , group );
1087+ fsn_mark = fsnotify_find_mark (obj , obj_type , group );
10881088 if (!fsn_mark ) {
10891089 fsnotify_group_unlock (group );
10901090 return - ENOENT ;
@@ -1105,30 +1105,6 @@ static int fanotify_remove_mark(struct fsnotify_group *group,
11051105 return 0 ;
11061106}
11071107
1108- static int fanotify_remove_vfsmount_mark (struct fsnotify_group * group ,
1109- struct vfsmount * mnt , __u32 mask ,
1110- unsigned int flags , __u32 umask )
1111- {
1112- return fanotify_remove_mark (group , & real_mount (mnt )-> mnt_fsnotify_marks ,
1113- mask , flags , umask );
1114- }
1115-
1116- static int fanotify_remove_sb_mark (struct fsnotify_group * group ,
1117- struct super_block * sb , __u32 mask ,
1118- unsigned int flags , __u32 umask )
1119- {
1120- return fanotify_remove_mark (group , & sb -> s_fsnotify_marks , mask ,
1121- flags , umask );
1122- }
1123-
1124- static int fanotify_remove_inode_mark (struct fsnotify_group * group ,
1125- struct inode * inode , __u32 mask ,
1126- unsigned int flags , __u32 umask )
1127- {
1128- return fanotify_remove_mark (group , & inode -> i_fsnotify_marks , mask ,
1129- flags , umask );
1130- }
1131-
11321108static bool fanotify_mark_update_flags (struct fsnotify_mark * fsn_mark ,
11331109 unsigned int fan_flags )
11341110{
@@ -1249,7 +1225,7 @@ static int fanotify_set_mark_fsid(struct fsnotify_group *group,
12491225}
12501226
12511227static struct fsnotify_mark * fanotify_add_new_mark (struct fsnotify_group * group ,
1252- fsnotify_connp_t * connp ,
1228+ void * obj ,
12531229 unsigned int obj_type ,
12541230 unsigned int fan_flags ,
12551231 struct fan_fsid * fsid )
@@ -1288,7 +1264,7 @@ static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
12881264 fan_mark -> fsid .val [0 ] = fan_mark -> fsid .val [1 ] = 0 ;
12891265 }
12901266
1291- ret = fsnotify_add_mark_locked (mark , connp , obj_type , 0 );
1267+ ret = fsnotify_add_mark_locked (mark , obj , obj_type , 0 );
12921268 if (ret )
12931269 goto out_put_mark ;
12941270
@@ -1344,7 +1320,7 @@ static int fanotify_may_update_existing_mark(struct fsnotify_mark *fsn_mark,
13441320}
13451321
13461322static int fanotify_add_mark (struct fsnotify_group * group ,
1347- fsnotify_connp_t * connp , unsigned int obj_type ,
1323+ void * obj , unsigned int obj_type ,
13481324 __u32 mask , unsigned int fan_flags ,
13491325 struct fan_fsid * fsid )
13501326{
@@ -1353,9 +1329,9 @@ static int fanotify_add_mark(struct fsnotify_group *group,
13531329 int ret = 0 ;
13541330
13551331 fsnotify_group_lock (group );
1356- fsn_mark = fsnotify_find_mark (connp , group );
1332+ fsn_mark = fsnotify_find_mark (obj , obj_type , group );
13571333 if (!fsn_mark ) {
1358- fsn_mark = fanotify_add_new_mark (group , connp , obj_type ,
1334+ fsn_mark = fanotify_add_new_mark (group , obj , obj_type ,
13591335 fan_flags , fsid );
13601336 if (IS_ERR (fsn_mark )) {
13611337 fsnotify_group_unlock (group );
@@ -1392,42 +1368,6 @@ static int fanotify_add_mark(struct fsnotify_group *group,
13921368 return ret ;
13931369}
13941370
1395- static int fanotify_add_vfsmount_mark (struct fsnotify_group * group ,
1396- struct vfsmount * mnt , __u32 mask ,
1397- unsigned int flags , struct fan_fsid * fsid )
1398- {
1399- return fanotify_add_mark (group , & real_mount (mnt )-> mnt_fsnotify_marks ,
1400- FSNOTIFY_OBJ_TYPE_VFSMOUNT , mask , flags , fsid );
1401- }
1402-
1403- static int fanotify_add_sb_mark (struct fsnotify_group * group ,
1404- struct super_block * sb , __u32 mask ,
1405- unsigned int flags , struct fan_fsid * fsid )
1406- {
1407- return fanotify_add_mark (group , & sb -> s_fsnotify_marks ,
1408- FSNOTIFY_OBJ_TYPE_SB , mask , flags , fsid );
1409- }
1410-
1411- static int fanotify_add_inode_mark (struct fsnotify_group * group ,
1412- struct inode * inode , __u32 mask ,
1413- unsigned int flags , struct fan_fsid * fsid )
1414- {
1415- pr_debug ("%s: group=%p inode=%p\n" , __func__ , group , inode );
1416-
1417- /*
1418- * If some other task has this inode open for write we should not add
1419- * an ignore mask, unless that ignore mask is supposed to survive
1420- * modification changes anyway.
1421- */
1422- if ((flags & FANOTIFY_MARK_IGNORE_BITS ) &&
1423- !(flags & FAN_MARK_IGNORED_SURV_MODIFY ) &&
1424- inode_is_open_for_write (inode ))
1425- return 0 ;
1426-
1427- return fanotify_add_mark (group , & inode -> i_fsnotify_marks ,
1428- FSNOTIFY_OBJ_TYPE_INODE , mask , flags , fsid );
1429- }
1430-
14311371static struct fsnotify_event * fanotify_alloc_overflow_event (void )
14321372{
14331373 struct fanotify_event * oevent ;
@@ -1576,13 +1516,13 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
15761516 INIT_LIST_HEAD (& group -> fanotify_data .access_list );
15771517 switch (class ) {
15781518 case FAN_CLASS_NOTIF :
1579- group -> priority = FS_PRIO_0 ;
1519+ group -> priority = FSNOTIFY_PRIO_NORMAL ;
15801520 break ;
15811521 case FAN_CLASS_CONTENT :
1582- group -> priority = FS_PRIO_1 ;
1522+ group -> priority = FSNOTIFY_PRIO_CONTENT ;
15831523 break ;
15841524 case FAN_CLASS_PRE_CONTENT :
1585- group -> priority = FS_PRIO_2 ;
1525+ group -> priority = FSNOTIFY_PRIO_PRE_CONTENT ;
15861526 break ;
15871527 default :
15881528 fd = - EINVAL ;
@@ -1750,6 +1690,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
17501690 unsigned int mark_cmd = flags & FANOTIFY_MARK_CMD_BITS ;
17511691 unsigned int ignore = flags & FANOTIFY_MARK_IGNORE_BITS ;
17521692 unsigned int obj_type , fid_mode ;
1693+ void * obj ;
17531694 u32 umask = 0 ;
17541695 int ret ;
17551696
@@ -1833,12 +1774,11 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
18331774 goto fput_and_out ;
18341775
18351776 /*
1836- * group->priority == FS_PRIO_0 == FAN_CLASS_NOTIF. These are not
1837- * allowed to set permissions events.
1777+ * Permission events require minimum priority FAN_CLASS_CONTENT.
18381778 */
18391779 ret = - EINVAL ;
18401780 if (mask & FANOTIFY_PERM_EVENTS &&
1841- group -> priority == FS_PRIO_0 )
1781+ group -> priority < FSNOTIFY_PRIO_CONTENT )
18421782 goto fput_and_out ;
18431783
18441784 if (mask & FAN_FS_ERROR &&
@@ -1908,17 +1848,34 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
19081848 }
19091849
19101850 /* inode held in place by reference to path; group by fget on fd */
1911- if (mark_type == FAN_MARK_INODE )
1851+ if (mark_type == FAN_MARK_INODE ) {
19121852 inode = path .dentry -> d_inode ;
1913- else
1853+ obj = inode ;
1854+ } else {
19141855 mnt = path .mnt ;
1856+ if (mark_type == FAN_MARK_MOUNT )
1857+ obj = mnt ;
1858+ else
1859+ obj = mnt -> mnt_sb ;
1860+ }
19151861
1916- ret = mnt ? - EINVAL : - EISDIR ;
1917- /* FAN_MARK_IGNORE requires SURV_MODIFY for sb/mount/dir marks */
1918- if (mark_cmd == FAN_MARK_ADD && ignore == FAN_MARK_IGNORE &&
1919- (mnt || S_ISDIR (inode -> i_mode )) &&
1920- !(flags & FAN_MARK_IGNORED_SURV_MODIFY ))
1921- goto path_put_and_out ;
1862+ /*
1863+ * If some other task has this inode open for write we should not add
1864+ * an ignore mask, unless that ignore mask is supposed to survive
1865+ * modification changes anyway.
1866+ */
1867+ if (mark_cmd == FAN_MARK_ADD && (flags & FANOTIFY_MARK_IGNORE_BITS ) &&
1868+ !(flags & FAN_MARK_IGNORED_SURV_MODIFY )) {
1869+ ret = mnt ? - EINVAL : - EISDIR ;
1870+ /* FAN_MARK_IGNORE requires SURV_MODIFY for sb/mount/dir marks */
1871+ if (ignore == FAN_MARK_IGNORE &&
1872+ (mnt || S_ISDIR (inode -> i_mode )))
1873+ goto path_put_and_out ;
1874+
1875+ ret = 0 ;
1876+ if (inode && inode_is_open_for_write (inode ))
1877+ goto path_put_and_out ;
1878+ }
19221879
19231880 /* Mask out FAN_EVENT_ON_CHILD flag for sb/mount/non-dir marks */
19241881 if (mnt || !S_ISDIR (inode -> i_mode )) {
@@ -1936,26 +1893,12 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
19361893 /* create/update an inode mark */
19371894 switch (mark_cmd ) {
19381895 case FAN_MARK_ADD :
1939- if (mark_type == FAN_MARK_MOUNT )
1940- ret = fanotify_add_vfsmount_mark (group , mnt , mask ,
1941- flags , fsid );
1942- else if (mark_type == FAN_MARK_FILESYSTEM )
1943- ret = fanotify_add_sb_mark (group , mnt -> mnt_sb , mask ,
1944- flags , fsid );
1945- else
1946- ret = fanotify_add_inode_mark (group , inode , mask ,
1947- flags , fsid );
1896+ ret = fanotify_add_mark (group , obj , obj_type , mask , flags ,
1897+ fsid );
19481898 break ;
19491899 case FAN_MARK_REMOVE :
1950- if (mark_type == FAN_MARK_MOUNT )
1951- ret = fanotify_remove_vfsmount_mark (group , mnt , mask ,
1952- flags , umask );
1953- else if (mark_type == FAN_MARK_FILESYSTEM )
1954- ret = fanotify_remove_sb_mark (group , mnt -> mnt_sb , mask ,
1955- flags , umask );
1956- else
1957- ret = fanotify_remove_inode_mark (group , inode , mask ,
1958- flags , umask );
1900+ ret = fanotify_remove_mark (group , obj , obj_type , mask , flags ,
1901+ umask );
19591902 break ;
19601903 default :
19611904 ret = - EINVAL ;
0 commit comments