diff options
author | rwatson <rwatson@FreeBSD.org> | 2009-07-28 21:52:24 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2009-07-28 21:52:24 +0000 |
commit | fac30ba8b4fd00a95fd7fb49c4e4dc1bcdf4003c (patch) | |
tree | 988681253e24923a9605bb54cb8a7c6531f1e9f9 /sys/security | |
parent | 21e3bcee4378f043e902dc1bab9ac2915235f40a (diff) | |
download | FreeBSD-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.h | 15 | ||||
-rw-r--r-- | sys/security/audit/audit_arg.c | 66 | ||||
-rw-r--r-- | sys/security/audit/audit_private.h | 3 |
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. |