| @@ -265,13 +265,6 @@ static int create_fd(struct fsnotify_group *group, const struct path *path, · 264 unmodified lines |
| 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, · 384 unmodified lines |
| 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, · 21 unmodified lines |
| 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, · 8 unmodified lines |
| 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, · 10 unmodified lines |
| 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, · 7 unmodified lines |
| 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, · 60 unmodified lines |
| 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, · 2 unmodified lines |
| 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) · 1090 unmodified lines |
| 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, |