Merge branch 'for-linus' of git://git.infradead.org/users/eparis/notify

* 'for-linus' of git://git.infradead.org/users/eparis/notify: (22 commits)
Ensure FMODE_NONOTIFY is not set by userspace
make fanotify_read() restartable across signals
fsnotify: remove alignment padding from fsnotify_mark on 64 bit builds
fs/notify/fanotify/fanotify_user.c: fix warnings
fanotify: Fix FAN_CLOSE comments
fanotify: do not recalculate the mask if the ignored mask changed
fanotify: ignore events on directories unless specifically requested
fsnotify: rename FS_IN_ISDIR to FS_ISDIR
fanotify: do not send events for irregular files
fanotify: limit number of listeners per user
fanotify: allow userspace to override max marks
fanotify: limit the number of marks in a single fanotify group
fanotify: allow userspace to override max queue depth
fsnotify: implement a default maximum queue depth
fanotify: ignore fanotify ignore marks if open writers
fanotify: allow userspace to flush all marks
fsnotify: call fsnotify_parent in perm events
fsnotify: correctly handle return codes from listeners
fanotify: use __aligned_u64 in fanotify userspace metadata
fanotify: implement fanotify listener ordering
...

+219 -64
+1 -1
fs/notify/Kconfig
··· 3 4 source "fs/notify/dnotify/Kconfig" 5 source "fs/notify/inotify/Kconfig" 6 - #source "fs/notify/fanotify/Kconfig"
··· 3 4 source "fs/notify/dnotify/Kconfig" 5 source "fs/notify/inotify/Kconfig" 6 + source "fs/notify/fanotify/Kconfig"
+21 -6
fs/notify/fanotify/fanotify.c
··· 131 BUILD_BUG_ON(FAN_Q_OVERFLOW != FS_Q_OVERFLOW); 132 BUILD_BUG_ON(FAN_OPEN_PERM != FS_OPEN_PERM); 133 BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM); 134 135 pr_debug("%s: group=%p event=%p\n", __func__, group, event); 136 ··· 161 __u32 event_mask, void *data, int data_type) 162 { 163 __u32 marks_mask, marks_ignored_mask; 164 165 pr_debug("%s: group=%p to_tell=%p inode_mark=%p vfsmnt_mark=%p " 166 "mask=%x data=%p data_type=%d\n", __func__, group, to_tell, 167 inode_mark, vfsmnt_mark, event_mask, data, data_type); 168 169 - /* sorry, fanotify only gives a damn about files and dirs */ 170 - if (!S_ISREG(to_tell->i_mode) && 171 - !S_ISDIR(to_tell->i_mode)) 172 - return false; 173 - 174 /* if we don't have enough info to send an event to userspace say no */ 175 if (data_type != FSNOTIFY_EVENT_PATH) 176 return false; 177 178 if (inode_mark && vfsmnt_mark) { ··· 196 BUG(); 197 } 198 199 if (event_mask & marks_mask & ~marks_ignored_mask) 200 return true; 201 202 return false; 203 } 204 205 const struct fsnotify_ops fanotify_fsnotify_ops = { 206 .handle_event = fanotify_handle_event, 207 .should_send_event = fanotify_should_send_event, 208 - .free_group_priv = NULL, 209 .free_event_priv = NULL, 210 .freeing_mark = NULL, 211 };
··· 131 BUILD_BUG_ON(FAN_Q_OVERFLOW != FS_Q_OVERFLOW); 132 BUILD_BUG_ON(FAN_OPEN_PERM != FS_OPEN_PERM); 133 BUILD_BUG_ON(FAN_ACCESS_PERM != FS_ACCESS_PERM); 134 + BUILD_BUG_ON(FAN_ONDIR != FS_ISDIR); 135 136 pr_debug("%s: group=%p event=%p\n", __func__, group, event); 137 ··· 160 __u32 event_mask, void *data, int data_type) 161 { 162 __u32 marks_mask, marks_ignored_mask; 163 + struct path *path = data; 164 165 pr_debug("%s: group=%p to_tell=%p inode_mark=%p vfsmnt_mark=%p " 166 "mask=%x data=%p data_type=%d\n", __func__, group, to_tell, 167 inode_mark, vfsmnt_mark, event_mask, data, data_type); 168 169 /* if we don't have enough info to send an event to userspace say no */ 170 if (data_type != FSNOTIFY_EVENT_PATH) 171 + return false; 172 + 173 + /* sorry, fanotify only gives a damn about files and dirs */ 174 + if (!S_ISREG(path->dentry->d_inode->i_mode) && 175 + !S_ISDIR(path->dentry->d_inode->i_mode)) 176 return false; 177 178 if (inode_mark && vfsmnt_mark) { ··· 194 BUG(); 195 } 196 197 + if (S_ISDIR(path->dentry->d_inode->i_mode) && 198 + (marks_ignored_mask & FS_ISDIR)) 199 + return false; 200 + 201 if (event_mask & marks_mask & ~marks_ignored_mask) 202 return true; 203 204 return false; 205 } 206 207 + static void fanotify_free_group_priv(struct fsnotify_group *group) 208 + { 209 + struct user_struct *user; 210 + 211 + user = group->fanotify_data.user; 212 + atomic_dec(&user->fanotify_listeners); 213 + free_uid(user); 214 + } 215 + 216 const struct fsnotify_ops fanotify_fsnotify_ops = { 217 .handle_event = fanotify_handle_event, 218 .should_send_event = fanotify_should_send_event, 219 + .free_group_priv = fanotify_free_group_priv, 220 .free_event_priv = NULL, 221 .freeing_mark = NULL, 222 };
+90 -8
fs/notify/fanotify/fanotify_user.c
··· 16 17 #include <asm/ioctls.h> 18 19 extern const struct fsnotify_ops fanotify_fsnotify_ops; 20 21 static struct kmem_cache *fanotify_mark_cache __read_mostly; ··· 330 ret = -EAGAIN; 331 if (file->f_flags & O_NONBLOCK) 332 break; 333 - ret = -EINTR; 334 if (signal_pending(current)) 335 break; 336 ··· 376 static int fanotify_release(struct inode *ignored, struct file *file) 377 { 378 struct fsnotify_group *group = file->private_data; 379 - struct fanotify_response_event *re, *lre; 380 - 381 - pr_debug("%s: file=%p group=%p\n", __func__, file, group); 382 383 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS 384 mutex_lock(&group->fanotify_data.access_mutex); 385 386 group->fanotify_data.bypass_perm = true; ··· 557 __u32 mask, 558 unsigned int flags) 559 { 560 - __u32 oldmask; 561 562 spin_lock(&fsn_mark->lock); 563 if (!(flags & FAN_MARK_IGNORED_MASK)) { 564 oldmask = fsn_mark->mask; 565 fsnotify_set_mark_mask_locked(fsn_mark, (oldmask | mask)); 566 } else { 567 - oldmask = fsn_mark->ignored_mask; 568 - fsnotify_set_mark_ignored_mask_locked(fsn_mark, (oldmask | mask)); 569 if (flags & FAN_MARK_IGNORED_SURV_MODIFY) 570 fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY; 571 } 572 spin_unlock(&fsn_mark->lock); 573 574 return mask & ~oldmask; ··· 590 fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); 591 if (!fsn_mark) { 592 int ret; 593 594 fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL); 595 if (!fsn_mark) ··· 622 623 pr_debug("%s: group=%p inode=%p\n", __func__, group, inode); 624 625 fsn_mark = fsnotify_find_inode_mark(group, inode); 626 if (!fsn_mark) { 627 int ret; 628 629 fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL); 630 if (!fsn_mark) ··· 662 { 663 struct fsnotify_group *group; 664 int f_flags, fd; 665 666 pr_debug("%s: flags=%d event_f_flags=%d\n", 667 __func__, flags, event_f_flags); ··· 672 673 if (flags & ~FAN_ALL_INIT_FLAGS) 674 return -EINVAL; 675 676 f_flags = O_RDWR | FMODE_NONOTIFY; 677 if (flags & FAN_CLOEXEC) ··· 690 if (IS_ERR(group)) 691 return PTR_ERR(group); 692 693 group->fanotify_data.f_flags = event_f_flags; 694 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS 695 mutex_init(&group->fanotify_data.access_mutex); 696 init_waitqueue_head(&group->fanotify_data.access_waitq); 697 INIT_LIST_HEAD(&group->fanotify_data.access_list); 698 #endif 699 700 fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags); 701 if (fd < 0) ··· 771 default: 772 return -EINVAL; 773 } 774 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS 775 if (mask & ~(FAN_ALL_EVENTS | FAN_ALL_PERM_EVENTS | FAN_EVENT_ON_CHILD)) 776 #else ··· 792 ret = -EINVAL; 793 if (unlikely(filp->f_op != &fanotify_fops)) 794 goto fput_and_out; 795 796 ret = fanotify_find_path(dfd, pathname, &path, flags); 797 if (ret) ··· 812 inode = path.dentry->d_inode; 813 else 814 mnt = path.mnt; 815 - group = filp->private_data; 816 817 /* create/update an inode mark */ 818 switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {
··· 16 17 #include <asm/ioctls.h> 18 19 + #define FANOTIFY_DEFAULT_MAX_EVENTS 16384 20 + #define FANOTIFY_DEFAULT_MAX_MARKS 8192 21 + #define FANOTIFY_DEFAULT_MAX_LISTENERS 128 22 + 23 extern const struct fsnotify_ops fanotify_fsnotify_ops; 24 25 static struct kmem_cache *fanotify_mark_cache __read_mostly; ··· 326 ret = -EAGAIN; 327 if (file->f_flags & O_NONBLOCK) 328 break; 329 + ret = -ERESTARTSYS; 330 if (signal_pending(current)) 331 break; 332 ··· 372 static int fanotify_release(struct inode *ignored, struct file *file) 373 { 374 struct fsnotify_group *group = file->private_data; 375 376 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS 377 + struct fanotify_response_event *re, *lre; 378 + 379 mutex_lock(&group->fanotify_data.access_mutex); 380 381 group->fanotify_data.bypass_perm = true; ··· 554 __u32 mask, 555 unsigned int flags) 556 { 557 + __u32 oldmask = -1; 558 559 spin_lock(&fsn_mark->lock); 560 if (!(flags & FAN_MARK_IGNORED_MASK)) { 561 oldmask = fsn_mark->mask; 562 fsnotify_set_mark_mask_locked(fsn_mark, (oldmask | mask)); 563 } else { 564 + __u32 tmask = fsn_mark->ignored_mask | mask; 565 + fsnotify_set_mark_ignored_mask_locked(fsn_mark, tmask); 566 if (flags & FAN_MARK_IGNORED_SURV_MODIFY) 567 fsn_mark->flags |= FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY; 568 } 569 + 570 + if (!(flags & FAN_MARK_ONDIR)) { 571 + __u32 tmask = fsn_mark->ignored_mask | FAN_ONDIR; 572 + fsnotify_set_mark_ignored_mask_locked(fsn_mark, tmask); 573 + } 574 + 575 spin_unlock(&fsn_mark->lock); 576 577 return mask & ~oldmask; ··· 581 fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); 582 if (!fsn_mark) { 583 int ret; 584 + 585 + if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) 586 + return -ENOSPC; 587 588 fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL); 589 if (!fsn_mark) ··· 610 611 pr_debug("%s: group=%p inode=%p\n", __func__, group, inode); 612 613 + /* 614 + * If some other task has this inode open for write we should not add 615 + * an ignored mark, unless that ignored mark is supposed to survive 616 + * modification changes anyway. 617 + */ 618 + if ((flags & FAN_MARK_IGNORED_MASK) && 619 + !(flags & FAN_MARK_IGNORED_SURV_MODIFY) && 620 + (atomic_read(&inode->i_writecount) > 0)) 621 + return 0; 622 + 623 fsn_mark = fsnotify_find_inode_mark(group, inode); 624 if (!fsn_mark) { 625 int ret; 626 + 627 + if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) 628 + return -ENOSPC; 629 630 fsn_mark = kmem_cache_alloc(fanotify_mark_cache, GFP_KERNEL); 631 if (!fsn_mark) ··· 637 { 638 struct fsnotify_group *group; 639 int f_flags, fd; 640 + struct user_struct *user; 641 642 pr_debug("%s: flags=%d event_f_flags=%d\n", 643 __func__, flags, event_f_flags); ··· 646 647 if (flags & ~FAN_ALL_INIT_FLAGS) 648 return -EINVAL; 649 + 650 + user = get_current_user(); 651 + if (atomic_read(&user->fanotify_listeners) > FANOTIFY_DEFAULT_MAX_LISTENERS) { 652 + free_uid(user); 653 + return -EMFILE; 654 + } 655 656 f_flags = O_RDWR | FMODE_NONOTIFY; 657 if (flags & FAN_CLOEXEC) ··· 658 if (IS_ERR(group)) 659 return PTR_ERR(group); 660 661 + group->fanotify_data.user = user; 662 + atomic_inc(&user->fanotify_listeners); 663 + 664 group->fanotify_data.f_flags = event_f_flags; 665 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS 666 mutex_init(&group->fanotify_data.access_mutex); 667 init_waitqueue_head(&group->fanotify_data.access_waitq); 668 INIT_LIST_HEAD(&group->fanotify_data.access_list); 669 #endif 670 + switch (flags & FAN_ALL_CLASS_BITS) { 671 + case FAN_CLASS_NOTIF: 672 + group->priority = FS_PRIO_0; 673 + break; 674 + case FAN_CLASS_CONTENT: 675 + group->priority = FS_PRIO_1; 676 + break; 677 + case FAN_CLASS_PRE_CONTENT: 678 + group->priority = FS_PRIO_2; 679 + break; 680 + default: 681 + fd = -EINVAL; 682 + goto out_put_group; 683 + } 684 + 685 + if (flags & FAN_UNLIMITED_QUEUE) { 686 + fd = -EPERM; 687 + if (!capable(CAP_SYS_ADMIN)) 688 + goto out_put_group; 689 + group->max_events = UINT_MAX; 690 + } else { 691 + group->max_events = FANOTIFY_DEFAULT_MAX_EVENTS; 692 + } 693 + 694 + if (flags & FAN_UNLIMITED_MARKS) { 695 + fd = -EPERM; 696 + if (!capable(CAP_SYS_ADMIN)) 697 + goto out_put_group; 698 + group->fanotify_data.max_marks = UINT_MAX; 699 + } else { 700 + group->fanotify_data.max_marks = FANOTIFY_DEFAULT_MAX_MARKS; 701 + } 702 703 fd = anon_inode_getfd("[fanotify]", &fanotify_fops, group, f_flags); 704 if (fd < 0) ··· 704 default: 705 return -EINVAL; 706 } 707 + 708 + if (mask & FAN_ONDIR) { 709 + flags |= FAN_MARK_ONDIR; 710 + mask &= ~FAN_ONDIR; 711 + } 712 + 713 #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS 714 if (mask & ~(FAN_ALL_EVENTS | FAN_ALL_PERM_EVENTS | FAN_EVENT_ON_CHILD)) 715 #else ··· 719 ret = -EINVAL; 720 if (unlikely(filp->f_op != &fanotify_fops)) 721 goto fput_and_out; 722 + group = filp->private_data; 723 + 724 + /* 725 + * group->priority == FS_PRIO_0 == FAN_CLASS_NOTIF. These are not 726 + * allowed to set permissions events. 727 + */ 728 + ret = -EINVAL; 729 + if (mask & FAN_ALL_PERM_EVENTS && 730 + group->priority == FS_PRIO_0) 731 + goto fput_and_out; 732 733 ret = fanotify_find_path(dfd, pathname, &path, flags); 734 if (ret) ··· 729 inode = path.dentry->d_inode; 730 else 731 mnt = path.mnt; 732 733 /* create/update an inode mark */ 734 switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) {
+21 -14
fs/notify/fsnotify.c
··· 84 } 85 86 /* Notify this dentry's parent about a child's events. */ 87 - void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask) 88 { 89 struct dentry *parent; 90 struct inode *p_inode; 91 92 if (!dentry) 93 dentry = path->dentry; 94 95 if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED)) 96 - return; 97 98 parent = dget_parent(dentry); 99 p_inode = parent->d_inode; ··· 107 mask |= FS_EVENT_ON_CHILD; 108 109 if (path) 110 - fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH, 111 - dentry->d_name.name, 0); 112 else 113 - fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE, 114 - dentry->d_name.name, 0); 115 } 116 117 dput(parent); 118 } 119 EXPORT_SYMBOL_GPL(__fsnotify_parent); 120 ··· 255 256 if (inode_group > vfsmount_group) { 257 /* handle inode */ 258 - send_to_group(to_tell, NULL, inode_mark, NULL, mask, data, 259 - data_is, cookie, file_name, &event); 260 /* we didn't use the vfsmount_mark */ 261 vfsmount_group = NULL; 262 } else if (vfsmount_group > inode_group) { 263 - send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data, 264 - data_is, cookie, file_name, &event); 265 inode_group = NULL; 266 } else { 267 - send_to_group(to_tell, mnt, inode_mark, vfsmount_mark, 268 - mask, data, data_is, cookie, file_name, 269 - &event); 270 } 271 272 if (inode_group) 273 inode_node = srcu_dereference(inode_node->next, ··· 279 vfsmount_node = srcu_dereference(vfsmount_node->next, 280 &fsnotify_mark_srcu); 281 } 282 - 283 srcu_read_unlock(&fsnotify_mark_srcu, idx); 284 /* 285 * fsnotify_create_event() took a reference so the event can't be cleaned
··· 84 } 85 86 /* Notify this dentry's parent about a child's events. */ 87 + int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask) 88 { 89 struct dentry *parent; 90 struct inode *p_inode; 91 + int ret = 0; 92 93 if (!dentry) 94 dentry = path->dentry; 95 96 if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED)) 97 + return 0; 98 99 parent = dget_parent(dentry); 100 p_inode = parent->d_inode; ··· 106 mask |= FS_EVENT_ON_CHILD; 107 108 if (path) 109 + ret = fsnotify(p_inode, mask, path, FSNOTIFY_EVENT_PATH, 110 + dentry->d_name.name, 0); 111 else 112 + ret = fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE, 113 + dentry->d_name.name, 0); 114 } 115 116 dput(parent); 117 + 118 + return ret; 119 } 120 EXPORT_SYMBOL_GPL(__fsnotify_parent); 121 ··· 252 253 if (inode_group > vfsmount_group) { 254 /* handle inode */ 255 + ret = send_to_group(to_tell, NULL, inode_mark, NULL, mask, data, 256 + data_is, cookie, file_name, &event); 257 /* we didn't use the vfsmount_mark */ 258 vfsmount_group = NULL; 259 } else if (vfsmount_group > inode_group) { 260 + ret = send_to_group(to_tell, mnt, NULL, vfsmount_mark, mask, data, 261 + data_is, cookie, file_name, &event); 262 inode_group = NULL; 263 } else { 264 + ret = send_to_group(to_tell, mnt, inode_mark, vfsmount_mark, 265 + mask, data, data_is, cookie, file_name, 266 + &event); 267 } 268 + 269 + if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS)) 270 + goto out; 271 272 if (inode_group) 273 inode_node = srcu_dereference(inode_node->next, ··· 273 vfsmount_node = srcu_dereference(vfsmount_node->next, 274 &fsnotify_mark_srcu); 275 } 276 + ret = 0; 277 + out: 278 srcu_read_unlock(&fsnotify_mark_srcu, idx); 279 /* 280 * fsnotify_create_event() took a reference so the event can't be cleaned
+7 -2
fs/notify/inode_mark.c
··· 177 * Attach an initialized mark to a given inode. 178 * These marks may be used for the fsnotify backend to determine which 179 * event types should be delivered to which group and for which inodes. These 180 - * marks are ordered according to the group's location in memory. 181 */ 182 int fsnotify_add_inode_mark(struct fsnotify_mark *mark, 183 struct fsnotify_group *group, struct inode *inode, ··· 212 goto out; 213 } 214 215 - if (mark->group < lmark->group) 216 continue; 217 218 hlist_add_before_rcu(&mark->i.i_list, &lmark->i.i_list);
··· 177 * Attach an initialized mark to a given inode. 178 * These marks may be used for the fsnotify backend to determine which 179 * event types should be delivered to which group and for which inodes. These 180 + * marks are ordered according to priority, highest number first, and then by 181 + * the group's location in memory. 182 */ 183 int fsnotify_add_inode_mark(struct fsnotify_mark *mark, 184 struct fsnotify_group *group, struct inode *inode, ··· 211 goto out; 212 } 213 214 + if (mark->group->priority < lmark->group->priority) 215 + continue; 216 + 217 + if ((mark->group->priority == lmark->group->priority) && 218 + (mark->group < lmark->group)) 219 continue; 220 221 hlist_add_before_rcu(&mark->i.i_list, &lmark->i.i_list);
+1 -1
fs/notify/inotify/inotify_user.c
··· 862 BUILD_BUG_ON(IN_Q_OVERFLOW != FS_Q_OVERFLOW); 863 BUILD_BUG_ON(IN_IGNORED != FS_IN_IGNORED); 864 BUILD_BUG_ON(IN_EXCL_UNLINK != FS_EXCL_UNLINK); 865 - BUILD_BUG_ON(IN_ISDIR != FS_IN_ISDIR); 866 BUILD_BUG_ON(IN_ONESHOT != FS_IN_ONESHOT); 867 868 BUG_ON(hweight32(ALL_INOTIFY_BITS) != 21);
··· 862 BUILD_BUG_ON(IN_Q_OVERFLOW != FS_Q_OVERFLOW); 863 BUILD_BUG_ON(IN_IGNORED != FS_IN_IGNORED); 864 BUILD_BUG_ON(IN_EXCL_UNLINK != FS_EXCL_UNLINK); 865 + BUILD_BUG_ON(IN_ISDIR != FS_ISDIR); 866 BUILD_BUG_ON(IN_ONESHOT != FS_IN_ONESHOT); 867 868 BUG_ON(hweight32(ALL_INOTIFY_BITS) != 21);
+5 -1
fs/notify/vfsmount_mark.c
··· 169 goto out; 170 } 171 172 - if (mark->group < lmark->group) 173 continue; 174 175 hlist_add_before_rcu(&mark->m.m_list, &lmark->m.m_list);
··· 169 goto out; 170 } 171 172 + if (mark->group->priority < lmark->group->priority) 173 + continue; 174 + 175 + if ((mark->group->priority == lmark->group->priority) && 176 + (mark->group < lmark->group)) 177 continue; 178 179 hlist_add_before_rcu(&mark->m.m_list, &lmark->m.m_list);
+1
include/linux/Kbuild
··· 118 header-y += ext2_fs.h 119 header-y += fadvise.h 120 header-y += falloc.h 121 header-y += fb.h 122 header-y += fcntl.h 123 header-y += fd.h
··· 118 header-y += ext2_fs.h 119 header-y += fadvise.h 120 header-y += falloc.h 121 + header-y += fanotify.h 122 header-y += fb.h 123 header-y += fcntl.h 124 header-y += fd.h
+27 -9
include/linux/fanotify.h
··· 6 /* the following events that user-space can register for */ 7 #define FAN_ACCESS 0x00000001 /* File was accessed */ 8 #define FAN_MODIFY 0x00000002 /* File was modified */ 9 - #define FAN_CLOSE_WRITE 0x00000008 /* Unwrittable file closed */ 10 - #define FAN_CLOSE_NOWRITE 0x00000010 /* Writtable file closed */ 11 #define FAN_OPEN 0x00000020 /* File was opened */ 12 13 - #define FAN_EVENT_ON_CHILD 0x08000000 /* interested in child events */ 14 - 15 - /* FIXME currently Q's have no limit.... */ 16 #define FAN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ 17 18 #define FAN_OPEN_PERM 0x00010000 /* File open in perm check */ 19 #define FAN_ACCESS_PERM 0x00020000 /* File accessed in perm check */ 20 21 /* helper events */ 22 #define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */ ··· 26 #define FAN_CLOEXEC 0x00000001 27 #define FAN_NONBLOCK 0x00000002 28 29 - #define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK) 30 31 /* flags used for fanotify_modify_mark() */ 32 #define FAN_MARK_ADD 0x00000001 ··· 49 #define FAN_MARK_IGNORED_MASK 0x00000020 50 #define FAN_MARK_IGNORED_SURV_MODIFY 0x00000040 51 #define FAN_MARK_FLUSH 0x00000080 52 53 #define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD |\ 54 FAN_MARK_REMOVE |\ ··· 60 FAN_MARK_ONLYDIR |\ 61 FAN_MARK_MOUNT |\ 62 FAN_MARK_IGNORED_MASK |\ 63 - FAN_MARK_IGNORED_SURV_MODIFY) 64 65 /* 66 * All of the events - we build the list by hand so that we can add flags in ··· 88 struct fanotify_event_metadata { 89 __u32 event_len; 90 __u32 vers; 91 - __u64 mask; 92 __s32 fd; 93 __s32 pid; 94 - } __attribute__ ((packed)); 95 96 struct fanotify_response { 97 __s32 fd;
··· 6 /* the following events that user-space can register for */ 7 #define FAN_ACCESS 0x00000001 /* File was accessed */ 8 #define FAN_MODIFY 0x00000002 /* File was modified */ 9 + #define FAN_CLOSE_WRITE 0x00000008 /* Writtable file closed */ 10 + #define FAN_CLOSE_NOWRITE 0x00000010 /* Unwrittable file closed */ 11 #define FAN_OPEN 0x00000020 /* File was opened */ 12 13 #define FAN_Q_OVERFLOW 0x00004000 /* Event queued overflowed */ 14 15 #define FAN_OPEN_PERM 0x00010000 /* File open in perm check */ 16 #define FAN_ACCESS_PERM 0x00020000 /* File accessed in perm check */ 17 + 18 + #define FAN_ONDIR 0x40000000 /* event occurred against dir */ 19 + 20 + #define FAN_EVENT_ON_CHILD 0x08000000 /* interested in child events */ 21 22 /* helper events */ 23 #define FAN_CLOSE (FAN_CLOSE_WRITE | FAN_CLOSE_NOWRITE) /* close */ ··· 25 #define FAN_CLOEXEC 0x00000001 26 #define FAN_NONBLOCK 0x00000002 27 28 + /* These are NOT bitwise flags. Both bits are used togther. */ 29 + #define FAN_CLASS_NOTIF 0x00000000 30 + #define FAN_CLASS_CONTENT 0x00000004 31 + #define FAN_CLASS_PRE_CONTENT 0x00000008 32 + #define FAN_ALL_CLASS_BITS (FAN_CLASS_NOTIF | FAN_CLASS_CONTENT | \ 33 + FAN_CLASS_PRE_CONTENT) 34 + 35 + #define FAN_UNLIMITED_QUEUE 0x00000010 36 + #define FAN_UNLIMITED_MARKS 0x00000020 37 + 38 + #define FAN_ALL_INIT_FLAGS (FAN_CLOEXEC | FAN_NONBLOCK | \ 39 + FAN_ALL_CLASS_BITS | FAN_UNLIMITED_QUEUE |\ 40 + FAN_UNLIMITED_MARKS) 41 42 /* flags used for fanotify_modify_mark() */ 43 #define FAN_MARK_ADD 0x00000001 ··· 36 #define FAN_MARK_IGNORED_MASK 0x00000020 37 #define FAN_MARK_IGNORED_SURV_MODIFY 0x00000040 38 #define FAN_MARK_FLUSH 0x00000080 39 + #ifdef __KERNEL__ 40 + /* not valid from userspace, only kernel internal */ 41 + #define FAN_MARK_ONDIR 0x00000100 42 + #endif 43 44 #define FAN_ALL_MARK_FLAGS (FAN_MARK_ADD |\ 45 FAN_MARK_REMOVE |\ ··· 43 FAN_MARK_ONLYDIR |\ 44 FAN_MARK_MOUNT |\ 45 FAN_MARK_IGNORED_MASK |\ 46 + FAN_MARK_IGNORED_SURV_MODIFY |\ 47 + FAN_MARK_FLUSH) 48 49 /* 50 * All of the events - we build the list by hand so that we can add flags in ··· 70 struct fanotify_event_metadata { 71 __u32 event_len; 72 __u32 vers; 73 + __aligned_u64 mask; 74 __s32 fd; 75 __s32 pid; 76 + }; 77 78 struct fanotify_response { 79 __s32 fd;
+22 -16
include/linux/fsnotify.h
··· 26 } 27 28 /* Notify this dentry's parent about a child's events. */ 29 - static inline void fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask) 30 { 31 if (!dentry) 32 dentry = path->dentry; 33 34 - __fsnotify_parent(path, dentry, mask); 35 } 36 37 /* simple call site for access decisions */ ··· 40 struct path *path = &file->f_path; 41 struct inode *inode = path->dentry->d_inode; 42 __u32 fsnotify_mask = 0; 43 44 if (file->f_mode & FMODE_NONOTIFY) 45 return 0; ··· 52 fsnotify_mask = FS_ACCESS_PERM; 53 else 54 BUG(); 55 56 return fsnotify(inode, fsnotify_mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); 57 } ··· 98 old_dir_mask |= FS_DN_RENAME; 99 100 if (isdir) { 101 - old_dir_mask |= FS_IN_ISDIR; 102 - new_dir_mask |= FS_IN_ISDIR; 103 } 104 105 fsnotify(old_dir, old_dir_mask, old_dir, FSNOTIFY_EVENT_INODE, old_name, fs_cookie); ··· 137 __u32 mask = FS_DELETE; 138 139 if (isdir) 140 - mask |= FS_IN_ISDIR; 141 142 fsnotify_parent(NULL, dentry, mask); 143 } ··· 179 */ 180 static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) 181 { 182 - __u32 mask = (FS_CREATE | FS_IN_ISDIR); 183 struct inode *d_inode = dentry->d_inode; 184 185 audit_inode_child(dentry, inode); ··· 197 __u32 mask = FS_ACCESS; 198 199 if (S_ISDIR(inode->i_mode)) 200 - mask |= FS_IN_ISDIR; 201 202 if (!(file->f_mode & FMODE_NONOTIFY)) { 203 fsnotify_parent(path, NULL, mask); ··· 215 __u32 mask = FS_MODIFY; 216 217 if (S_ISDIR(inode->i_mode)) 218 - mask |= FS_IN_ISDIR; 219 220 if (!(file->f_mode & FMODE_NONOTIFY)) { 221 fsnotify_parent(path, NULL, mask); ··· 233 __u32 mask = FS_OPEN; 234 235 if (S_ISDIR(inode->i_mode)) 236 - mask |= FS_IN_ISDIR; 237 238 - if (!(file->f_mode & FMODE_NONOTIFY)) { 239 - fsnotify_parent(path, NULL, mask); 240 - fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); 241 - } 242 } 243 244 /* ··· 253 __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE; 254 255 if (S_ISDIR(inode->i_mode)) 256 - mask |= FS_IN_ISDIR; 257 258 if (!(file->f_mode & FMODE_NONOTIFY)) { 259 fsnotify_parent(path, NULL, mask); ··· 270 __u32 mask = FS_ATTRIB; 271 272 if (S_ISDIR(inode->i_mode)) 273 - mask |= FS_IN_ISDIR; 274 275 fsnotify_parent(NULL, dentry, mask); 276 fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); ··· 305 306 if (mask) { 307 if (S_ISDIR(inode->i_mode)) 308 - mask |= FS_IN_ISDIR; 309 310 fsnotify_parent(NULL, dentry, mask); 311 fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
··· 26 } 27 28 /* Notify this dentry's parent about a child's events. */ 29 + static inline int fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask) 30 { 31 if (!dentry) 32 dentry = path->dentry; 33 34 + return __fsnotify_parent(path, dentry, mask); 35 } 36 37 /* simple call site for access decisions */ ··· 40 struct path *path = &file->f_path; 41 struct inode *inode = path->dentry->d_inode; 42 __u32 fsnotify_mask = 0; 43 + int ret; 44 45 if (file->f_mode & FMODE_NONOTIFY) 46 return 0; ··· 51 fsnotify_mask = FS_ACCESS_PERM; 52 else 53 BUG(); 54 + 55 + ret = fsnotify_parent(path, NULL, fsnotify_mask); 56 + if (ret) 57 + return ret; 58 59 return fsnotify(inode, fsnotify_mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); 60 } ··· 93 old_dir_mask |= FS_DN_RENAME; 94 95 if (isdir) { 96 + old_dir_mask |= FS_ISDIR; 97 + new_dir_mask |= FS_ISDIR; 98 } 99 100 fsnotify(old_dir, old_dir_mask, old_dir, FSNOTIFY_EVENT_INODE, old_name, fs_cookie); ··· 132 __u32 mask = FS_DELETE; 133 134 if (isdir) 135 + mask |= FS_ISDIR; 136 137 fsnotify_parent(NULL, dentry, mask); 138 } ··· 174 */ 175 static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) 176 { 177 + __u32 mask = (FS_CREATE | FS_ISDIR); 178 struct inode *d_inode = dentry->d_inode; 179 180 audit_inode_child(dentry, inode); ··· 192 __u32 mask = FS_ACCESS; 193 194 if (S_ISDIR(inode->i_mode)) 195 + mask |= FS_ISDIR; 196 197 if (!(file->f_mode & FMODE_NONOTIFY)) { 198 fsnotify_parent(path, NULL, mask); ··· 210 __u32 mask = FS_MODIFY; 211 212 if (S_ISDIR(inode->i_mode)) 213 + mask |= FS_ISDIR; 214 215 if (!(file->f_mode & FMODE_NONOTIFY)) { 216 fsnotify_parent(path, NULL, mask); ··· 228 __u32 mask = FS_OPEN; 229 230 if (S_ISDIR(inode->i_mode)) 231 + mask |= FS_ISDIR; 232 233 + /* FMODE_NONOTIFY must never be set from user */ 234 + file->f_mode &= ~FMODE_NONOTIFY; 235 + 236 + fsnotify_parent(path, NULL, mask); 237 + fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); 238 } 239 240 /* ··· 247 __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE; 248 249 if (S_ISDIR(inode->i_mode)) 250 + mask |= FS_ISDIR; 251 252 if (!(file->f_mode & FMODE_NONOTIFY)) { 253 fsnotify_parent(path, NULL, mask); ··· 264 __u32 mask = FS_ATTRIB; 265 266 if (S_ISDIR(inode->i_mode)) 267 + mask |= FS_ISDIR; 268 269 fsnotify_parent(NULL, dentry, mask); 270 fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); ··· 299 300 if (mask) { 301 if (S_ISDIR(inode->i_mode)) 302 + mask |= FS_ISDIR; 303 304 fsnotify_parent(NULL, dentry, mask); 305 fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
+20 -6
include/linux/fsnotify_backend.h
··· 45 #define FS_ACCESS_PERM 0x00020000 /* access event in a permissions hook */ 46 47 #define FS_EXCL_UNLINK 0x04000000 /* do not send events if object is unlinked */ 48 - #define FS_IN_ISDIR 0x40000000 /* event occurred against dir */ 49 #define FS_IN_ONESHOT 0x80000000 /* only send event once */ 50 51 #define FS_DN_RENAME 0x10000000 /* file renamed */ ··· 64 65 #define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO) 66 67 #define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \ 68 FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \ 69 FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \ 70 FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \ 71 FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \ 72 FS_OPEN_PERM | FS_ACCESS_PERM | FS_EXCL_UNLINK | \ 73 - FS_IN_ISDIR | FS_IN_ONESHOT | FS_DN_RENAME | \ 74 FS_DN_MULTISHOT | FS_EVENT_ON_CHILD) 75 76 struct fsnotify_group; ··· 131 wait_queue_head_t notification_waitq; /* read() on the notification file blocks on this waitq */ 132 unsigned int q_len; /* events on the queue */ 133 unsigned int max_events; /* maximum events allowed on the list */ 134 135 /* stores all fastpath marks assoc with this group so they can be cleaned on unregister */ 136 spinlock_t mark_lock; /* protect marks_list */ ··· 169 bool bypass_perm; /* protected by access_mutex */ 170 #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ 171 int f_flags; 172 } fanotify_data; 173 #endif /* CONFIG_FANOTIFY */ 174 }; ··· 287 struct fsnotify_inode_mark i; 288 struct fsnotify_vfsmount_mark m; 289 }; 290 - __u32 ignored_mask; /* events types to ignore */ 291 struct list_head free_g_list; /* tmp list used when freeing this mark */ 292 #define FSNOTIFY_MARK_FLAG_INODE 0x01 293 #define FSNOTIFY_MARK_FLAG_VFSMOUNT 0x02 294 #define FSNOTIFY_MARK_FLAG_OBJECT_PINNED 0x04 ··· 306 /* main fsnotify call to send events */ 307 extern int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, 308 const unsigned char *name, u32 cookie); 309 - extern void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask); 310 extern void __fsnotify_inode_delete(struct inode *inode); 311 extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt); 312 extern u32 fsnotify_get_cookie(void); ··· 435 return 0; 436 } 437 438 - static inline void __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask) 439 - {} 440 441 static inline void __fsnotify_inode_delete(struct inode *inode) 442 {}
··· 45 #define FS_ACCESS_PERM 0x00020000 /* access event in a permissions hook */ 46 47 #define FS_EXCL_UNLINK 0x04000000 /* do not send events if object is unlinked */ 48 + #define FS_ISDIR 0x40000000 /* event occurred against dir */ 49 #define FS_IN_ONESHOT 0x80000000 /* only send event once */ 50 51 #define FS_DN_RENAME 0x10000000 /* file renamed */ ··· 64 65 #define FS_MOVE (FS_MOVED_FROM | FS_MOVED_TO) 66 67 + #define ALL_FSNOTIFY_PERM_EVENTS (FS_OPEN_PERM | FS_ACCESS_PERM) 68 + 69 #define ALL_FSNOTIFY_EVENTS (FS_ACCESS | FS_MODIFY | FS_ATTRIB | \ 70 FS_CLOSE_WRITE | FS_CLOSE_NOWRITE | FS_OPEN | \ 71 FS_MOVED_FROM | FS_MOVED_TO | FS_CREATE | \ 72 FS_DELETE | FS_DELETE_SELF | FS_MOVE_SELF | \ 73 FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \ 74 FS_OPEN_PERM | FS_ACCESS_PERM | FS_EXCL_UNLINK | \ 75 + FS_ISDIR | FS_IN_ONESHOT | FS_DN_RENAME | \ 76 FS_DN_MULTISHOT | FS_EVENT_ON_CHILD) 77 78 struct fsnotify_group; ··· 129 wait_queue_head_t notification_waitq; /* read() on the notification file blocks on this waitq */ 130 unsigned int q_len; /* events on the queue */ 131 unsigned int max_events; /* maximum events allowed on the list */ 132 + /* 133 + * Valid fsnotify group priorities. Events are send in order from highest 134 + * priority to lowest priority. We default to the lowest priority. 135 + */ 136 + #define FS_PRIO_0 0 /* normal notifiers, no permissions */ 137 + #define FS_PRIO_1 1 /* fanotify content based access control */ 138 + #define FS_PRIO_2 2 /* fanotify pre-content access */ 139 + unsigned int priority; 140 141 /* stores all fastpath marks assoc with this group so they can be cleaned on unregister */ 142 spinlock_t mark_lock; /* protect marks_list */ ··· 159 bool bypass_perm; /* protected by access_mutex */ 160 #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ 161 int f_flags; 162 + unsigned int max_marks; 163 + struct user_struct *user; 164 } fanotify_data; 165 #endif /* CONFIG_FANOTIFY */ 166 }; ··· 275 struct fsnotify_inode_mark i; 276 struct fsnotify_vfsmount_mark m; 277 }; 278 struct list_head free_g_list; /* tmp list used when freeing this mark */ 279 + __u32 ignored_mask; /* events types to ignore */ 280 #define FSNOTIFY_MARK_FLAG_INODE 0x01 281 #define FSNOTIFY_MARK_FLAG_VFSMOUNT 0x02 282 #define FSNOTIFY_MARK_FLAG_OBJECT_PINNED 0x04 ··· 294 /* main fsnotify call to send events */ 295 extern int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, 296 const unsigned char *name, u32 cookie); 297 + extern int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask); 298 extern void __fsnotify_inode_delete(struct inode *inode); 299 extern void __fsnotify_vfsmount_delete(struct vfsmount *mnt); 300 extern u32 fsnotify_get_cookie(void); ··· 423 return 0; 424 } 425 426 + static inline int __fsnotify_parent(struct path *path, struct dentry *dentry, __u32 mask) 427 + { 428 + return 0; 429 + } 430 431 static inline void __fsnotify_inode_delete(struct inode *inode) 432 {}
+3
include/linux/sched.h
··· 672 atomic_t inotify_watches; /* How many inotify watches does this user have? */ 673 atomic_t inotify_devs; /* How many inotify devs does this user have opened? */ 674 #endif 675 #ifdef CONFIG_EPOLL 676 atomic_t epoll_watches; /* The number of file descriptors currently watched */ 677 #endif
··· 672 atomic_t inotify_watches; /* How many inotify watches does this user have? */ 673 atomic_t inotify_devs; /* How many inotify devs does this user have opened? */ 674 #endif 675 + #ifdef CONFIG_FANOTIFY 676 + atomic_t fanotify_listeners; 677 + #endif 678 #ifdef CONFIG_EPOLL 679 atomic_t epoll_watches; /* The number of file descriptors currently watched */ 680 #endif