Re: [PATCH v8 1/2] seccomp: add a return code to trap to userspace
From: Oleg Nesterov <oleg@redhat.com>
Date: 2018-11-01 13:56:41
Also in:
lkml
On 10/29, Tycho Andersen wrote:
+static int seccomp_notify_release(struct inode *inode, struct file *file)
+{
+ struct seccomp_filter *filter = file->private_data;
+ struct seccomp_knotif *knotif;
+
+ mutex_lock(&filter->notify_lock);
+
+ /*
+ * If this file is being closed because e.g. the task who owned it
+ * died, let's wake everyone up who was waiting on us.
+ */
+ list_for_each_entry(knotif, &filter->notif->notifications, list) {
+ if (knotif->state == SECCOMP_NOTIFY_REPLIED)
+ continue;
+
+ knotif->state = SECCOMP_NOTIFY_REPLIED;
+ knotif->error = -ENOSYS;
+ knotif->val = 0;
+
+ complete(&knotif->ready);
+ }
+
+ wake_up_all(&filter->notif->wqh);Why? __fput() is not possible if there is another user of this file sleeping in seccomp_notify_poll().
+ kfree(filter->notif);
Hmm, this looks wrong... we can't kfree ->notif if its ->notifications list is not empty, otherwise seccomp_do_user_notification()->list_del(&n.list) can write to the freed memory. I think _release() should do list_for_each_entry_safe() + list_del_init() and seccomp_do_user_notification() should use list_del_init() too. Or, simpler, seccomp_do_user_notification() should do if (!match->notif) goto out; instead of "goto remove_list". Oleg.