On Thu, Nov 01, 2018 at 02:56:34PM +0100, Oleg Nesterov wrote: > 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(). Yes, I was just trying to be extra defensive. But I can drop it. > > + 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". Yes, and we need another such check in this case after we re-acquire the lock from the signal send. Thanks for catching this! Tycho