| @@ -265,13 +265,6 @@ static int create_fd(struct fsnotify_group *group, const struct path *path, · 264 unmodified lines |
| 265 | group->fanotify_data.f_flags | __FMODE_NONOTIFY, | 265 | group->fanotify_data.f_flags | __FMODE_NONOTIFY, |
| 266 | current_cred()); | 266 | current_cred()); |
| 267 | if (IS_ERR(new_file)) { | 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 | put_unused_fd(client_fd); | 268 | put_unused_fd(client_fd); |
| 276 | client_fd = PTR_ERR(new_file); | 269 | client_fd = PTR_ERR(new_file); |
| 277 | } else { | 270 | } else { |
| @@ -662,7 +655,7 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, · 384 unmodified lines |
| 662 | unsigned int info_mode = FAN_GROUP_FLAG(group, FANOTIFY_INFO_MODES); | 655 | unsigned int info_mode = FAN_GROUP_FLAG(group, FANOTIFY_INFO_MODES); |
| 663 | unsigned int pidfd_mode = info_mode & FAN_REPORT_PIDFD; | 656 | unsigned int pidfd_mode = info_mode & FAN_REPORT_PIDFD; |
| 664 | struct file *f = NULL, *pidfd_file = NULL; | 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 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); | 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 | if (!FAN_GROUP_FLAG(group, FANOTIFY_UNPRIV) && | 683 | if (!FAN_GROUP_FLAG(group, FANOTIFY_UNPRIV) && |
| 691 | path && path->mnt && path->dentry) { | 684 | path && path->mnt && path->dentry) { |
| 692 | fd = create_fd(group, path, &f); | 685 | fd = create_fd(group, path, &f); |
| 693 | if (fd < 0) | 686 | /* |
| 694 | return fd; | 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 | if (pidfd_mode) { | 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 | * The PIDTYPE_TGID check for an event->pid is performed | 730 | * The PIDTYPE_TGID check for an event->pid is performed |
| 709 | * preemptively in an attempt to catch out cases where the event | 731 | * preemptively in an attempt to catch out cases where the event |
| 710 | * listener reads events after the event generating process has | 732 | * listener reads events after the event generating process has |
| 711 | * already terminated. Report FAN_NOPIDFD to the event listener | 733 | * already terminated. Depending on flag FAN_REPORT_FD_ERROR, |
| 712 | * in those cases, with all other pidfd creation errors being | 734 | * report either -ESRCH or FAN_NOPIDFD to the event listener in |
| 713 | * reported as FAN_EPIDFD. | 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 || | 738 | if (metadata.pid && pid_has_task(event->pid, PIDTYPE_TGID)) |
| 716 | !pid_has_task(event->pid, PIDTYPE_TGID)) { | | |
| 717 | pidfd = FAN_NOPIDFD; | | |
| 718 | } else { | | |
| 719 | pidfd = pidfd_prepare(event->pid, 0, &pidfd_file); | 739 | pidfd = pidfd_prepare(event->pid, 0, &pidfd_file); |
| 720 | if (pidfd < 0) | 740 | |
| 721 | pidfd = FAN_EPIDFD; | 741 | if (!FAN_GROUP_FLAG(group, FAN_REPORT_FD_ERROR) && pidfd < 0) |
| 722 | } | 742 | pidfd = pidfd == -ESRCH ? FAN_NOPIDFD : FAN_EPIDFD; |
| 723 | } | 743 | } |
| 724 | | 744 | |
| 725 | ret = -EFAULT; | 745 | ret = -EFAULT; |
| @@ -736,9 +756,6 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, · 10 unmodified lines |
| 736 | buf += FAN_EVENT_METADATA_LEN; | 756 | buf += FAN_EVENT_METADATA_LEN; |
| 737 | count -= FAN_EVENT_METADATA_LEN; | 757 | count -= FAN_EVENT_METADATA_LEN; |
| 738 | | 758 | |
| 739 | if (fanotify_is_perm_event(event->mask)) | | |
| 740 | FANOTIFY_PERM(event)->fd = fd; | | |
| 741 | | | |
| 742 | if (info_mode) { | 759 | if (info_mode) { |
| 743 | ret = copy_info_records_to_user(event, info, info_mode, pidfd, | 760 | ret = copy_info_records_to_user(event, info, info_mode, pidfd, |
| 744 | buf, count); | 761 | buf, count); |
| @@ -752,15 +769,18 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, · 7 unmodified lines |
| 752 | if (pidfd_file) | 769 | if (pidfd_file) |
| 753 | fd_install(pidfd, pidfd_file); | 770 | fd_install(pidfd, pidfd_file); |
| 754 | | 771 | |
| | 772 | if (fanotify_is_perm_event(event->mask)) |
| | 773 | FANOTIFY_PERM(event)->fd = fd; |
| | 774 | |
| 755 | return metadata.event_len; | 775 | return metadata.event_len; |
| 756 | | 776 | |
| 757 | out_close_fd: | 777 | out_close_fd: |
| 758 | if (fd != FAN_NOFD) { | 778 | if (f) { |
| 759 | put_unused_fd(fd); | 779 | put_unused_fd(fd); |
| 760 | fput(f); | 780 | fput(f); |
| 761 | } | 781 | } |
| 762 | | 782 | |
| 763 | if (pidfd >= 0) { | 783 | if (pidfd_file) { |
| 764 | put_unused_fd(pidfd); | 784 | put_unused_fd(pidfd); |
| 765 | fput(pidfd_file); | 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 | ret = copy_event_to_user(group, event, buf, count); | 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 | * Permission events get queued to wait for response. Other | 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 | if (!fanotify_is_perm_event(event->mask)) { | 855 | if (!fanotify_is_perm_event(event->mask)) { |
| 845 | fsnotify_destroy_event(group, &event->fse); | 856 | fsnotify_destroy_event(group, &event->fse); |
| 846 | } else { | 857 | } else { |
| 847 | if (ret <= 0) { | 858 | if (ret <= 0 || FANOTIFY_PERM(event)->fd < 0) { |
| 848 | spin_lock(&group->notification_lock); | 859 | spin_lock(&group->notification_lock); |
| 849 | finish_permission_event(group, | 860 | finish_permission_event(group, |
| 850 | FANOTIFY_PERM(event), FAN_DENY, NULL); | 861 | FANOTIFY_PERM(event), FAN_DENY, NULL); |
| @@ -1941,7 +1952,7 @@ static int __init fanotify_user_setup(void) · 1090 unmodified lines |
| 1941 | FANOTIFY_DEFAULT_MAX_USER_MARKS); | 1952 | FANOTIFY_DEFAULT_MAX_USER_MARKS); |
| 1942 | | 1953 | |
| 1943 | BUILD_BUG_ON(FANOTIFY_INIT_FLAGS & FANOTIFY_INTERNAL_GROUP_FLAGS); | 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 | BUILD_BUG_ON(HWEIGHT32(FANOTIFY_MARK_FLAGS) != 11); | 1956 | BUILD_BUG_ON(HWEIGHT32(FANOTIFY_MARK_FLAGS) != 11); |
| 1946 | | 1957 | |
| 1947 | fanotify_mark_cache = KMEM_CACHE(fanotify_mark, | 1958 | fanotify_mark_cache = KMEM_CACHE(fanotify_mark, |