summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2016-01-13 14:02:07 +0000
committerkib <kib@FreeBSD.org>2016-01-13 14:02:07 +0000
commite884cfc968387de3c1ff83079d0ce44782846404 (patch)
treef43449bc298355cacbdb5481e953b4bb355d4a86
parent0f1ad490766ad165a63459482430d90902e54839 (diff)
downloadFreeBSD-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
-rw-r--r--sys/security/audit/audit_pipe.c29
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);
}
/*
OpenPOWER on IntegriCloud