Author: kib
Date: Wed Jan 13 14:02:07 2016
New Revision: 293826
URL: https://svnweb.freebsd.org/changeset/base/293826

Log:
  Move the funsetown(9) call from audit_pipe_close() to cdevpriv
  destructor.  As result, close method becomes trivial and removed.
  Final cdevsw close method might be called without file
  context (e.g. in vn_open_vnode() if the vnode is reclaimed meantime),
  which leaves ap_sigio registered for notification, despite cdevpriv
  destructor frees the memory later.
  
  Call destructor instead of doing a cleanup inline, for
  devfs_set_cdevpriv() failure in open.  This adds missed funsetown(9)
  call and locks ap to satisfy audit_pipe_free() invariants.
  
  Reported and tested by:       pho (previous version)
  Sponsored by: The FreeBSD Foundation
  MFC after:    1 week

Modified:
  head/sys/security/audit/audit_pipe.c

Modified: head/sys/security/audit/audit_pipe.c
==============================================================================
--- head/sys/security/audit/audit_pipe.c        Wed Jan 13 12:01:28 2016        
(r293825)
+++ head/sys/security/audit/audit_pipe.c        Wed Jan 13 14:02:07 2016        
(r293826)
@@ -223,7 +223,6 @@ static struct cdev  *audit_pipe_dev;
  * Special device methods and definition.
  */
 static d_open_t                audit_pipe_open;
-static d_close_t       audit_pipe_close;
 static d_read_t                audit_pipe_read;
 static d_ioctl_t       audit_pipe_ioctl;
 static d_poll_t                audit_pipe_poll;
@@ -232,7 +231,6 @@ static d_kqfilter_t audit_pipe_kqfilter;
 static struct cdevsw   audit_pipe_cdevsw = {
        .d_version =    D_VERSION,
        .d_open =       audit_pipe_open,
-       .d_close =      audit_pipe_close,
        .d_read =       audit_pipe_read,
        .d_ioctl =      audit_pipe_ioctl,
        .d_poll =       audit_pipe_poll,
@@ -658,6 +656,7 @@ audit_pipe_dtor(void *arg)
        struct audit_pipe *ap;
 
        ap = arg;
+       funsetown(&ap->ap_sigio);
        AUDIT_PIPE_LIST_WLOCK();
        AUDIT_PIPE_LOCK(ap);
        audit_pipe_free(ap);
@@ -676,33 +675,13 @@ audit_pipe_open(struct cdev *dev, int of
        int error;
 
        ap = audit_pipe_alloc();
-       if (ap == NULL) {
+       if (ap == NULL)
                return (ENOMEM);
-       }
        fsetown(td->td_proc->p_pid, &ap->ap_sigio);
        error = devfs_set_cdevpriv(ap, audit_pipe_dtor);
-       if (error != 0) {
-               AUDIT_PIPE_LIST_WLOCK();
-               audit_pipe_free(ap);
-               AUDIT_PIPE_LIST_WUNLOCK();
-       }
-       return (0);
-}
-
-/*
- * Close audit pipe, tear down all records, etc.
- */
-static int
-audit_pipe_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
-{
-       struct audit_pipe *ap;
-       int error;
-
-       error = devfs_get_cdevpriv((void **)&ap);
        if (error != 0)
-               return (error);
-       funsetown(&ap->ap_sigio);
-       return (0);
+               audit_pipe_dtor(ap);
+       return (error);
 }
 
 /*
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "[email protected]"

Reply via email to