summaryrefslogtreecommitdiffstats
path: root/sys/security
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2009-07-28 21:52:24 +0000
committerrwatson <rwatson@FreeBSD.org>2009-07-28 21:52:24 +0000
commitfac30ba8b4fd00a95fd7fb49c4e4dc1bcdf4003c (patch)
tree988681253e24923a9605bb54cb8a7c6531f1e9f9 /sys/security
parent21e3bcee4378f043e902dc1bab9ac2915235f40a (diff)
downloadFreeBSD-src-fac30ba8b4fd00a95fd7fb49c4e4dc1bcdf4003c.zip
FreeBSD-src-fac30ba8b4fd00a95fd7fb49c4e4dc1bcdf4003c.tar.gz
Rework vnode argument auditing to follow the same structure, in order
to avoid exposing ARG_ macros/flag values outside of the audit code in order to name which one of two possible vnodes will be audited for a system call. Approved by: re (kib) Obtained from: TrustedBSD Project MFC after: 1 month
Diffstat (limited to 'sys/security')
-rw-r--r--sys/security/audit/audit.h15
-rw-r--r--sys/security/audit/audit_arg.c66
-rw-r--r--sys/security/audit/audit_private.h3
3 files changed, 50 insertions, 34 deletions
diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h
index e8b3550..8121996 100644
--- a/sys/security/audit/audit.h
+++ b/sys/security/audit/audit.h
@@ -163,7 +163,8 @@ void audit_arg_auid(uid_t auid);
void audit_arg_auditinfo(struct auditinfo *au_info);
void audit_arg_auditinfo_addr(struct auditinfo_addr *au_info);
void audit_arg_upath(struct thread *td, char *upath, u_int64_t flags);
-void audit_arg_vnode(struct vnode *vp, u_int64_t flags);
+void audit_arg_vnode1(struct vnode *vp);
+void audit_arg_vnode2(struct vnode *vp);
void audit_arg_text(char *text);
void audit_arg_cmd(int cmd);
void audit_arg_svipc_cmd(int cmd);
@@ -341,9 +342,14 @@ void audit_thread_free(struct thread *td);
audit_arg_value((value)); \
} while (0)
-#define AUDIT_ARG_VNODE(vp, flags) do { \
+#define AUDIT_ARG_VNODE1(vp) do { \
if (AUDITING_TD(curthread)) \
- audit_arg_vnode((vp), (flags)); \
+ audit_arg_vnode1((vp)); \
+} while (0)
+
+#define AUDIT_ARG_VNODE2(vp) do { \
+ if (AUDITING_TD(curthread)) \
+ audit_arg_vnode2((vp)); \
} while (0)
#define AUDIT_SYSCALL_ENTER(code, td) do { \
@@ -402,7 +408,8 @@ void audit_thread_free(struct thread *td);
#define AUDIT_ARG_UID(uid)
#define AUDIT_ARG_UPATH(td, upath, flags)
#define AUDIT_ARG_VALUE(value)
-#define AUDIT_ARG_VNODE(vp, flags)
+#define AUDIT_ARG_VNODE1(vp)
+#define AUDIT_ARG_VNODE2(vp)
#define AUDIT_SYSCALL_ENTER(code, td)
#define AUDIT_SYSCALL_EXIT(error, td)
diff --git a/sys/security/audit/audit_arg.c b/sys/security/audit/audit_arg.c
index bf4cb0a..cd3abb2 100644
--- a/sys/security/audit/audit_arg.c
+++ b/sys/security/audit/audit_arg.c
@@ -667,7 +667,7 @@ audit_arg_file(struct proc *p, struct file *fp)
vp = fp->f_vnode;
vfslocked = VFS_LOCK_GIANT(vp->v_mount);
vn_lock(vp, LK_SHARED | LK_RETRY);
- audit_arg_vnode(vp, ARG_VNODE1);
+ audit_arg_vnode1(vp);
VOP_UNLOCK(vp, 0);
VFS_UNLOCK_GIANT(vfslocked);
break;
@@ -761,17 +761,11 @@ audit_arg_upath(struct thread *td, char *upath, u_int64_t flag)
*
* XXXAUDIT: Possibly KASSERT the path pointer is NULL?
*/
-void
-audit_arg_vnode(struct vnode *vp, u_int64_t flags)
+static int
+audit_arg_vnode(struct vnode *vp, struct vnode_au_info *vnp)
{
- struct kaudit_record *ar;
struct vattr vattr;
int error;
- struct vnode_au_info *vnp;
-
- KASSERT(vp != NULL, ("audit_arg_vnode: vp == NULL"));
- KASSERT((flags == ARG_VNODE1) || (flags == ARG_VNODE2),
- ("audit_arg_vnode: flags %jd", (intmax_t)flags));
/*
* Assume that if the caller is calling audit_arg_vnode() on a
@@ -780,27 +774,10 @@ audit_arg_vnode(struct vnode *vp, u_int64_t flags)
VFS_ASSERT_GIANT(vp->v_mount);
ASSERT_VOP_LOCKED(vp, "audit_arg_vnode");
- ar = currecord();
- if (ar == NULL)
- return;
-
- /*
- * XXXAUDIT: The below clears, and then resets the flags for valid
- * arguments. Ideally, either the new vnode is used, or the old one
- * would be.
- */
- if (flags & ARG_VNODE1) {
- ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE1);
- vnp = &ar->k_ar.ar_arg_vnode1;
- } else {
- ar->k_ar.ar_valid_arg &= (ARG_ALL ^ ARG_VNODE2);
- vnp = &ar->k_ar.ar_arg_vnode2;
- }
-
error = VOP_GETATTR(vp, &vattr, curthread->td_ucred);
if (error) {
/* XXX: How to handle this case? */
- return;
+ return (error);
}
vnp->vn_mode = vattr.va_mode;
@@ -810,9 +787,38 @@ audit_arg_vnode(struct vnode *vp, u_int64_t flags)
vnp->vn_fsid = vattr.va_fsid;
vnp->vn_fileid = vattr.va_fileid;
vnp->vn_gen = vattr.va_gen;
- if (flags & ARG_VNODE1)
+ return (0);
+}
+
+void
+audit_arg_vnode1(struct vnode *vp)
+{
+ struct kaudit_record *ar;
+ int error;
+
+ ar = currecord();
+ if (ar == NULL)
+ return;
+
+ ARG_CLEAR_VALID(ar, ARG_VNODE1);
+ error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode1);
+ if (error == 0)
ARG_SET_VALID(ar, ARG_VNODE1);
- else
+}
+
+void
+audit_arg_vnode2(struct vnode *vp)
+{
+ struct kaudit_record *ar;
+ int error;
+
+ ar = currecord();
+ if (ar == NULL)
+ return;
+
+ ARG_CLEAR_VALID(ar, ARG_VNODE2);
+ error = audit_arg_vnode(vp, &ar->k_ar.ar_arg_vnode2);
+ if (error == 0)
ARG_SET_VALID(ar, ARG_VNODE2);
}
@@ -885,7 +891,7 @@ audit_sysclose(struct thread *td, int fd)
vp = fp->f_vnode;
vfslocked = VFS_LOCK_GIANT(vp->v_mount);
vn_lock(vp, LK_SHARED | LK_RETRY);
- audit_arg_vnode(vp, ARG_VNODE1);
+ audit_arg_vnode1(vp);
VOP_UNLOCK(vp, 0);
VFS_UNLOCK_GIANT(vfslocked);
fdrop(fp, td);
diff --git a/sys/security/audit/audit_private.h b/sys/security/audit/audit_private.h
index 97433df..ab6c1f4 100644
--- a/sys/security/audit/audit_private.h
+++ b/sys/security/audit/audit_private.h
@@ -240,6 +240,9 @@ struct audit_record {
#define ARG_SET_VALID(kar, arg) do { \
(kar)->k_ar.ar_valid_arg |= (arg); \
} while (0)
+#define ARG_CLEAR_VALID(kar, arg) do { \
+ (kar)->k_ar.ar_valid_arg &= ~(arg); \
+} while (0)
/*
* In-kernel version of audit record; the basic record plus queue meta-data.
OpenPOWER on IntegriCloud