summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormjg <mjg@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>2020-12-17 18:52:04 +0000
committermjg <mjg@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>2020-12-17 18:52:04 +0000
commitd4a011cdffb457381e974fb0ed0f8b968fe2532a (patch)
treeaf298d49b78d39de871842ed194b47a7ff20dfca
parent83ecdd94634a5fac9c4fe16cc8296faf2d89b643 (diff)
downloadfreebsd-d4a011cdffb457381e974fb0ed0f8b968fe2532a.tar.gz
freebsd-d4a011cdffb457381e974fb0ed0f8b968fe2532a.tar.bz2
audit: rework AUDIT_SYSCLOSE
This in particular avoids spurious lookups on close. git-svn-id: http://svn.freebsd.org/base/head@368731 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
-rw-r--r--sys/kern/kern_descrip.c27
-rw-r--r--sys/security/audit/audit.h2
-rw-r--r--sys/security/audit/audit_arg.c10
3 files changed, 19 insertions, 20 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 618271a6e82..4cbc565c2db 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -107,7 +107,7 @@ __read_mostly uma_zone_t pwd_zone;
VFS_SMR_DECLARE;
static int closefp(struct filedesc *fdp, int fd, struct file *fp,
- struct thread *td, bool holdleaders);
+ struct thread *td, bool holdleaders, bool audit);
static int fd_first_free(struct filedesc *fdp, int low, int size);
static void fdgrowtable(struct filedesc *fdp, int nfd);
static void fdgrowtable_exp(struct filedesc *fdp, int nfd);
@@ -998,7 +998,7 @@ kern_dup(struct thread *td, u_int mode, int flags, int old, int new)
error = 0;
if (delfp != NULL) {
- (void) closefp(fdp, new, delfp, td, true);
+ (void) closefp(fdp, new, delfp, td, true, false);
FILEDESC_UNLOCK_ASSERT(fdp);
} else {
unlock:
@@ -1240,7 +1240,8 @@ fgetown(struct sigio **sigiop)
}
static int
-closefp_impl(struct filedesc *fdp, int fd, struct file *fp, struct thread *td)
+closefp_impl(struct filedesc *fdp, int fd, struct file *fp, struct thread *td,
+ bool audit)
{
int error;
@@ -1262,6 +1263,10 @@ closefp_impl(struct filedesc *fdp, int fd, struct file *fp, struct thread *td)
mq_fdclose(td, fd, fp);
FILEDESC_XUNLOCK(fdp);
+#ifdef AUDIT
+ if (AUDITING_TD(td) && audit)
+ audit_sysclose(td, fd, fp);
+#endif
error = closef(fp, td);
/*
@@ -1277,7 +1282,7 @@ closefp_impl(struct filedesc *fdp, int fd, struct file *fp, struct thread *td)
static int
closefp_hl(struct filedesc *fdp, int fd, struct file *fp, struct thread *td,
- bool holdleaders)
+ bool holdleaders, bool audit)
{
int error;
@@ -1295,7 +1300,7 @@ closefp_hl(struct filedesc *fdp, int fd, struct file *fp, struct thread *td,
}
}
- error = closefp_impl(fdp, fd, fp, td);
+ error = closefp_impl(fdp, fd, fp, td, audit);
if (holdleaders) {
FILEDESC_XLOCK(fdp);
fdp->fd_holdleaderscount--;
@@ -1311,15 +1316,15 @@ closefp_hl(struct filedesc *fdp, int fd, struct file *fp, struct thread *td,
static int
closefp(struct filedesc *fdp, int fd, struct file *fp, struct thread *td,
- bool holdleaders)
+ bool holdleaders, bool audit)
{
FILEDESC_XLOCK_ASSERT(fdp);
if (__predict_false(td->td_proc->p_fdtol != NULL)) {
- return (closefp_hl(fdp, fd, fp, td, holdleaders));
+ return (closefp_hl(fdp, fd, fp, td, holdleaders, audit));
} else {
- return (closefp_impl(fdp, fd, fp, td));
+ return (closefp_impl(fdp, fd, fp, td, audit));
}
}
@@ -1347,8 +1352,6 @@ kern_close(struct thread *td, int fd)
fdp = td->td_proc->p_fd;
- AUDIT_SYSCLOSE(td, fd);
-
FILEDESC_XLOCK(fdp);
if ((fp = fget_locked(fdp, fd)) == NULL) {
FILEDESC_XUNLOCK(fdp);
@@ -1357,7 +1360,7 @@ kern_close(struct thread *td, int fd)
fdfree(fdp, fd);
/* closefp() drops the FILEDESC lock for us. */
- return (closefp(fdp, fd, fp, td, true));
+ return (closefp(fdp, fd, fp, td, true, true));
}
int
@@ -2671,7 +2674,7 @@ fdcloseexec(struct thread *td)
(fde->fde_flags & UF_EXCLOSE))) {
FILEDESC_XLOCK(fdp);
fdfree(fdp, i);
- (void) closefp(fdp, i, fp, td, false);
+ (void) closefp(fdp, i, fp, td, false, false);
FILEDESC_UNLOCK_ASSERT(fdp);
}
}
diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h
index 30393febfd3..376d8e1990f 100644
--- a/sys/security/audit/audit.h
+++ b/sys/security/audit/audit.h
@@ -140,7 +140,7 @@ void audit_arg_argv(char *argv, int argc, int length);
void audit_arg_envv(char *envv, int envc, int length);
void audit_arg_rights(cap_rights_t *rightsp);
void audit_arg_fcntl_rights(uint32_t fcntlrights);
-void audit_sysclose(struct thread *td, int fd);
+void audit_sysclose(struct thread *td, int fd, struct file *fp);
void audit_cred_copy(struct ucred *src, struct ucred *dest);
void audit_cred_destroy(struct ucred *cred);
void audit_cred_init(struct ucred *cred);
diff --git a/sys/security/audit/audit_arg.c b/sys/security/audit/audit_arg.c
index 44b17e36c8e..a917b5b6e29 100644
--- a/sys/security/audit/audit_arg.c
+++ b/sys/security/audit/audit_arg.c
@@ -995,12 +995,10 @@ audit_arg_fcntl_rights(uint32_t fcntlrights)
* call itself.
*/
void
-audit_sysclose(struct thread *td, int fd)
+audit_sysclose(struct thread *td, int fd, struct file *fp)
{
- cap_rights_t rights;
struct kaudit_record *ar;
struct vnode *vp;
- struct file *fp;
KASSERT(td != NULL, ("audit_sysclose: td == NULL"));
@@ -1010,12 +1008,10 @@ audit_sysclose(struct thread *td, int fd)
audit_arg_fd(fd);
- if (getvnode(td, fd, cap_rights_init(&rights), &fp) != 0)
- return;
-
vp = fp->f_vnode;
+ if (vp == NULL)
+ return;
vn_lock(vp, LK_SHARED | LK_RETRY);
audit_arg_vnode1(vp);
VOP_UNLOCK(vp);
- fdrop(fp, td);
}