@@ -502,7 +502,7 @@ static int copy_fid_info_to_user(__kernel_fsid_t *fsid, struct fanotify_fh *fh,
502
502
}
503
503
504
504
/* Pad with 0's */
505
- WARN_ON_ONCE (len < 0 || len >= FANOTIFY_EVENT_ALIGN );
505
+ WARN_ON_ONCE (len >= FANOTIFY_EVENT_ALIGN );
506
506
if (len > 0 && clear_user (buf , len ))
507
507
return - EFAULT ;
508
508
@@ -1076,15 +1076,15 @@ static __u32 fanotify_mark_remove_from_mask(struct fsnotify_mark *fsn_mark,
1076
1076
}
1077
1077
1078
1078
static int fanotify_remove_mark (struct fsnotify_group * group ,
1079
- fsnotify_connp_t * connp , __u32 mask ,
1079
+ void * obj , unsigned int obj_type , __u32 mask ,
1080
1080
unsigned int flags , __u32 umask )
1081
1081
{
1082
1082
struct fsnotify_mark * fsn_mark = NULL ;
1083
1083
__u32 removed ;
1084
1084
int destroy_mark ;
1085
1085
1086
1086
fsnotify_group_lock (group );
1087
- fsn_mark = fsnotify_find_mark (connp , group );
1087
+ fsn_mark = fsnotify_find_mark (obj , obj_type , group );
1088
1088
if (!fsn_mark ) {
1089
1089
fsnotify_group_unlock (group );
1090
1090
return - ENOENT ;
@@ -1105,30 +1105,6 @@ static int fanotify_remove_mark(struct fsnotify_group *group,
1105
1105
return 0 ;
1106
1106
}
1107
1107
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
-
1132
1108
static bool fanotify_mark_update_flags (struct fsnotify_mark * fsn_mark ,
1133
1109
unsigned int fan_flags )
1134
1110
{
@@ -1249,7 +1225,7 @@ static int fanotify_set_mark_fsid(struct fsnotify_group *group,
1249
1225
}
1250
1226
1251
1227
static struct fsnotify_mark * fanotify_add_new_mark (struct fsnotify_group * group ,
1252
- fsnotify_connp_t * connp ,
1228
+ void * obj ,
1253
1229
unsigned int obj_type ,
1254
1230
unsigned int fan_flags ,
1255
1231
struct fan_fsid * fsid )
@@ -1288,7 +1264,7 @@ static struct fsnotify_mark *fanotify_add_new_mark(struct fsnotify_group *group,
1288
1264
fan_mark -> fsid .val [0 ] = fan_mark -> fsid .val [1 ] = 0 ;
1289
1265
}
1290
1266
1291
- ret = fsnotify_add_mark_locked (mark , connp , obj_type , 0 );
1267
+ ret = fsnotify_add_mark_locked (mark , obj , obj_type , 0 );
1292
1268
if (ret )
1293
1269
goto out_put_mark ;
1294
1270
@@ -1344,7 +1320,7 @@ static int fanotify_may_update_existing_mark(struct fsnotify_mark *fsn_mark,
1344
1320
}
1345
1321
1346
1322
static int fanotify_add_mark (struct fsnotify_group * group ,
1347
- fsnotify_connp_t * connp , unsigned int obj_type ,
1323
+ void * obj , unsigned int obj_type ,
1348
1324
__u32 mask , unsigned int fan_flags ,
1349
1325
struct fan_fsid * fsid )
1350
1326
{
@@ -1353,9 +1329,9 @@ static int fanotify_add_mark(struct fsnotify_group *group,
1353
1329
int ret = 0 ;
1354
1330
1355
1331
fsnotify_group_lock (group );
1356
- fsn_mark = fsnotify_find_mark (connp , group );
1332
+ fsn_mark = fsnotify_find_mark (obj , obj_type , group );
1357
1333
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 ,
1359
1335
fan_flags , fsid );
1360
1336
if (IS_ERR (fsn_mark )) {
1361
1337
fsnotify_group_unlock (group );
@@ -1392,42 +1368,6 @@ static int fanotify_add_mark(struct fsnotify_group *group,
1392
1368
return ret ;
1393
1369
}
1394
1370
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
-
1431
1371
static struct fsnotify_event * fanotify_alloc_overflow_event (void )
1432
1372
{
1433
1373
struct fanotify_event * oevent ;
@@ -1576,13 +1516,13 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags)
1576
1516
INIT_LIST_HEAD (& group -> fanotify_data .access_list );
1577
1517
switch (class ) {
1578
1518
case FAN_CLASS_NOTIF :
1579
- group -> priority = FS_PRIO_0 ;
1519
+ group -> priority = FSNOTIFY_PRIO_NORMAL ;
1580
1520
break ;
1581
1521
case FAN_CLASS_CONTENT :
1582
- group -> priority = FS_PRIO_1 ;
1522
+ group -> priority = FSNOTIFY_PRIO_CONTENT ;
1583
1523
break ;
1584
1524
case FAN_CLASS_PRE_CONTENT :
1585
- group -> priority = FS_PRIO_2 ;
1525
+ group -> priority = FSNOTIFY_PRIO_PRE_CONTENT ;
1586
1526
break ;
1587
1527
default :
1588
1528
fd = - EINVAL ;
@@ -1750,6 +1690,7 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
1750
1690
unsigned int mark_cmd = flags & FANOTIFY_MARK_CMD_BITS ;
1751
1691
unsigned int ignore = flags & FANOTIFY_MARK_IGNORE_BITS ;
1752
1692
unsigned int obj_type , fid_mode ;
1693
+ void * obj ;
1753
1694
u32 umask = 0 ;
1754
1695
int ret ;
1755
1696
@@ -1833,12 +1774,11 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
1833
1774
goto fput_and_out ;
1834
1775
1835
1776
/*
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.
1838
1778
*/
1839
1779
ret = - EINVAL ;
1840
1780
if (mask & FANOTIFY_PERM_EVENTS &&
1841
- group -> priority == FS_PRIO_0 )
1781
+ group -> priority < FSNOTIFY_PRIO_CONTENT )
1842
1782
goto fput_and_out ;
1843
1783
1844
1784
if (mask & FAN_FS_ERROR &&
@@ -1908,17 +1848,34 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
1908
1848
}
1909
1849
1910
1850
/* 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 ) {
1912
1852
inode = path .dentry -> d_inode ;
1913
- else
1853
+ obj = inode ;
1854
+ } else {
1914
1855
mnt = path .mnt ;
1856
+ if (mark_type == FAN_MARK_MOUNT )
1857
+ obj = mnt ;
1858
+ else
1859
+ obj = mnt -> mnt_sb ;
1860
+ }
1915
1861
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
+ }
1922
1879
1923
1880
/* Mask out FAN_EVENT_ON_CHILD flag for sb/mount/non-dir marks */
1924
1881
if (mnt || !S_ISDIR (inode -> i_mode )) {
@@ -1936,26 +1893,12 @@ static int do_fanotify_mark(int fanotify_fd, unsigned int flags, __u64 mask,
1936
1893
/* create/update an inode mark */
1937
1894
switch (mark_cmd ) {
1938
1895
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 );
1948
1898
break ;
1949
1899
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 );
1959
1902
break ;
1960
1903
default :
1961
1904
ret = - EINVAL ;
0 commit comments