diff options
author | kib <kib@FreeBSD.org> | 2016-01-13 14:02:07 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2016-01-13 14:02:07 +0000 |
commit | e884cfc968387de3c1ff83079d0ce44782846404 (patch) | |
tree | f43449bc298355cacbdb5481e953b4bb355d4a86 /sys/security/audit | |
parent | 0f1ad490766ad165a63459482430d90902e54839 (diff) | |
download | FreeBSD-src-e884cfc968387de3c1ff83079d0ce44782846404.zip FreeBSD-src-e884cfc968387de3c1ff83079d0ce44782846404.tar.gz |
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
Diffstat (limited to 'sys/security/audit')
-rw-r--r-- | sys/security/audit/audit_pipe.c | 29 |
1 files changed, 4 insertions, 25 deletions
diff --git a/sys/security/audit/audit_pipe.c b/sys/security/audit/audit_pipe.c index f9c63d2..b53cfaa 100644 --- a/sys/security/audit/audit_pipe.c +++ b/sys/security/audit/audit_pipe.c @@ -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 oflags, int devtype, struct thread *td) 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); } /* |