@@ -265,13 +265,6 @@ static int create_fd(struct fsnotify_group *group, const struct path *path,
265
265
group -> fanotify_data .f_flags | __FMODE_NONOTIFY ,
266
266
current_cred ());
267
267
if (IS_ERR (new_file )) {
268
- /*
269
- * we still send an event even if we can't open the file. this
270
- * can happen when say tasks are gone and we try to open their
271
- * /proc files or we try to open a WRONLY file like in sysfs
272
- * we just send the errno to userspace since there isn't much
273
- * else we can do.
274
- */
275
268
put_unused_fd (client_fd );
276
269
client_fd = PTR_ERR (new_file );
277
270
} else {
@@ -662,7 +655,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
662
655
unsigned int info_mode = FAN_GROUP_FLAG (group , FANOTIFY_INFO_MODES );
663
656
unsigned int pidfd_mode = info_mode & FAN_REPORT_PIDFD ;
664
657
struct file * f = NULL , * pidfd_file = NULL ;
665
- int ret , pidfd = FAN_NOPIDFD , fd = FAN_NOFD ;
658
+ int ret , pidfd = - ESRCH , fd = - EBADF ;
666
659
667
660
pr_debug ("%s: group=%p event=%p\n" , __func__ , group , event );
668
661
@@ -690,10 +683,39 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
690
683
if (!FAN_GROUP_FLAG (group , FANOTIFY_UNPRIV ) &&
691
684
path && path -> mnt && path -> dentry ) {
692
685
fd = create_fd (group , path , & f );
693
- if (fd < 0 )
694
- return fd ;
686
+ /*
687
+ * Opening an fd from dentry can fail for several reasons.
688
+ * For example, when tasks are gone and we try to open their
689
+ * /proc files or we try to open a WRONLY file like in sysfs
690
+ * or when trying to open a file that was deleted on the
691
+ * remote network server.
692
+ *
693
+ * For a group with FAN_REPORT_FD_ERROR, we will send the
694
+ * event with the error instead of the open fd, otherwise
695
+ * Userspace may not get the error at all.
696
+ * In any case, userspace will not know which file failed to
697
+ * open, so add a debug print for further investigation.
698
+ */
699
+ if (fd < 0 ) {
700
+ pr_debug ("fanotify: create_fd(%pd2) failed err=%d\n" ,
701
+ path -> dentry , fd );
702
+ if (!FAN_GROUP_FLAG (group , FAN_REPORT_FD_ERROR )) {
703
+ /*
704
+ * Historically, we've handled EOPENSTALE in a
705
+ * special way and silently dropped such
706
+ * events. Now we have to keep it to maintain
707
+ * backward compatibility...
708
+ */
709
+ if (fd == - EOPENSTALE )
710
+ fd = 0 ;
711
+ return fd ;
712
+ }
713
+ }
695
714
}
696
- metadata .fd = fd ;
715
+ if (FAN_GROUP_FLAG (group , FAN_REPORT_FD_ERROR ))
716
+ metadata .fd = fd ;
717
+ else
718
+ metadata .fd = fd >= 0 ? fd : FAN_NOFD ;
697
719
698
720
if (pidfd_mode ) {
699
721
/*
@@ -708,18 +730,16 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
708
730
* The PIDTYPE_TGID check for an event->pid is performed
709
731
* preemptively in an attempt to catch out cases where the event
710
732
* listener reads events after the event generating process has
711
- * already terminated. Report FAN_NOPIDFD to the event listener
712
- * in those cases, with all other pidfd creation errors being
713
- * reported as FAN_EPIDFD.
733
+ * already terminated. Depending on flag FAN_REPORT_FD_ERROR,
734
+ * report either -ESRCH or FAN_NOPIDFD to the event listener in
735
+ * those cases with all other pidfd creation errors reported as
736
+ * the error code itself or as FAN_EPIDFD.
714
737
*/
715
- if (metadata .pid == 0 ||
716
- !pid_has_task (event -> pid , PIDTYPE_TGID )) {
717
- pidfd = FAN_NOPIDFD ;
718
- } else {
738
+ if (metadata .pid && pid_has_task (event -> pid , PIDTYPE_TGID ))
719
739
pidfd = pidfd_prepare (event -> pid , 0 , & pidfd_file );
720
- if ( pidfd < 0 )
721
- pidfd = FAN_EPIDFD ;
722
- }
740
+
741
+ if (! FAN_GROUP_FLAG ( group , FAN_REPORT_FD_ERROR ) && pidfd < 0 )
742
+ pidfd = pidfd == - ESRCH ? FAN_NOPIDFD : FAN_EPIDFD ;
723
743
}
724
744
725
745
ret = - EFAULT ;
@@ -736,9 +756,6 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
736
756
buf += FAN_EVENT_METADATA_LEN ;
737
757
count -= FAN_EVENT_METADATA_LEN ;
738
758
739
- if (fanotify_is_perm_event (event -> mask ))
740
- FANOTIFY_PERM (event )-> fd = fd ;
741
-
742
759
if (info_mode ) {
743
760
ret = copy_info_records_to_user (event , info , info_mode , pidfd ,
744
761
buf , count );
@@ -752,15 +769,18 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
752
769
if (pidfd_file )
753
770
fd_install (pidfd , pidfd_file );
754
771
772
+ if (fanotify_is_perm_event (event -> mask ))
773
+ FANOTIFY_PERM (event )-> fd = fd ;
774
+
755
775
return metadata .event_len ;
756
776
757
777
out_close_fd :
758
- if (fd != FAN_NOFD ) {
778
+ if (f ) {
759
779
put_unused_fd (fd );
760
780
fput (f );
761
781
}
762
782
763
- if (pidfd >= 0 ) {
783
+ if (pidfd_file ) {
764
784
put_unused_fd (pidfd );
765
785
fput (pidfd_file );
766
786
}
@@ -827,15 +847,6 @@ static ssize_t fanotify_read(struct file *file, char __user *buf,
827
847
}
828
848
829
849
ret = copy_event_to_user (group , event , buf , count );
830
- if (unlikely (ret == - EOPENSTALE )) {
831
- /*
832
- * We cannot report events with stale fd so drop it.
833
- * Setting ret to 0 will continue the event loop and
834
- * do the right thing if there are no more events to
835
- * read (i.e. return bytes read, -EAGAIN or wait).
836
- */
837
- ret = 0 ;
838
- }
839
850
840
851
/*
841
852
* Permission events get queued to wait for response. Other
@@ -844,7 +855,7 @@ static ssize_t fanotify_read(struct file *file, char __user *buf,
844
855
if (!fanotify_is_perm_event (event -> mask )) {
845
856
fsnotify_destroy_event (group , & event -> fse );
846
857
} else {
847
- if (ret <= 0 ) {
858
+ if (ret <= 0 || FANOTIFY_PERM ( event ) -> fd < 0 ) {
848
859
spin_lock (& group -> notification_lock );
849
860
finish_permission_event (group ,
850
861
FANOTIFY_PERM (event ), FAN_DENY , NULL );
@@ -1941,7 +1952,7 @@ static int __init fanotify_user_setup(void)
1941
1952
FANOTIFY_DEFAULT_MAX_USER_MARKS );
1942
1953
1943
1954
BUILD_BUG_ON (FANOTIFY_INIT_FLAGS & FANOTIFY_INTERNAL_GROUP_FLAGS );
1944
- BUILD_BUG_ON (HWEIGHT32 (FANOTIFY_INIT_FLAGS ) != 12 );
1955
+ BUILD_BUG_ON (HWEIGHT32 (FANOTIFY_INIT_FLAGS ) != 13 );
1945
1956
BUILD_BUG_ON (HWEIGHT32 (FANOTIFY_MARK_FLAGS ) != 11 );
1946
1957
1947
1958
fanotify_mark_cache = KMEM_CACHE (fanotify_mark ,
0 commit comments