summaryrefslogtreecommitdiff
path: root/sys/security/audit
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2020-02-21 01:40:49 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2020-02-21 01:40:49 +0000
commit7de6c5ebbddfec6c6ccd8e00c6e53336f046be5d (patch)
treebe13614f90d7688667762ec4e10cfa2a2ad22dd7 /sys/security/audit
parent9e826d32e8b97a8c33ce22f0e88e88c0aaf3c268 (diff)
Notes
Diffstat (limited to 'sys/security/audit')
-rw-r--r--sys/security/audit/audit.h16
-rw-r--r--sys/security/audit/audit_arg.c38
-rw-r--r--sys/security/audit/audit_bsm_klib.c70
-rw-r--r--sys/security/audit/audit_private.h2
4 files changed, 103 insertions, 23 deletions
diff --git a/sys/security/audit/audit.h b/sys/security/audit/audit.h
index a7600d5c1f90..7e13806a0171 100644
--- a/sys/security/audit/audit.h
+++ b/sys/security/audit/audit.h
@@ -120,6 +120,10 @@ void audit_arg_upath1(struct thread *td, int dirfd, char *upath);
void audit_arg_upath1_canon(char *upath);
void audit_arg_upath2(struct thread *td, int dirfd, char *upath);
void audit_arg_upath2_canon(char *upath);
+void audit_arg_upath1_vp(struct thread *td, struct vnode *rdir,
+ struct vnode *cdir, char *upath);
+void audit_arg_upath2_vp(struct thread *td, struct vnode *rdir,
+ struct vnode *cdir, char *upath);
void audit_arg_vnode1(struct vnode *vp);
void audit_arg_vnode2(struct vnode *vp);
void audit_arg_text(const char *text);
@@ -362,6 +366,16 @@ void audit_thread_free(struct thread *td);
audit_arg_upath2_canon((upath)); \
} while (0)
+#define AUDIT_ARG_UPATH1_VP(td, rdir, cdir, upath) do { \
+ if (AUDITING_TD(curthread)) \
+ audit_arg_upath1_vp((td), (rdir), (cdir), (upath)); \
+} while (0)
+
+#define AUDIT_ARG_UPATH2_VP(td, rdir, cdir, upath) do { \
+ if (AUDITING_TD(curthread)) \
+ audit_arg_upath2_vp((td), (rdir), (cdir), (upath)); \
+} while (0)
+
#define AUDIT_ARG_VALUE(value) do { \
if (AUDITING_TD(curthread)) \
audit_arg_value((value)); \
@@ -448,6 +462,8 @@ void audit_thread_free(struct thread *td);
#define AUDIT_ARG_UPATH1_CANON(upath)
#define AUDIT_ARG_UPATH2(td, dirfd, upath)
#define AUDIT_ARG_UPATH2_CANON(upath)
+#define AUDIT_ARG_UPATH1_VP(td, rdir, cdir, upath)
+#define AUDIT_ARG_UPATH2_VP(td, rdir, cdir, upath)
#define AUDIT_ARG_VALUE(value)
#define AUDIT_ARG_VNODE1(vp)
#define AUDIT_ARG_VNODE2(vp)
diff --git a/sys/security/audit/audit_arg.c b/sys/security/audit/audit_arg.c
index f50d77281095..fc5318750e3e 100644
--- a/sys/security/audit/audit_arg.c
+++ b/sys/security/audit/audit_arg.c
@@ -767,6 +767,44 @@ audit_arg_upath2(struct thread *td, int dirfd, char *upath)
ARG_SET_VALID(ar, ARG_UPATH2);
}
+static void
+audit_arg_upath_vp(struct thread *td, struct vnode *rdir, struct vnode *cdir,
+ char *upath, char **pathp)
+{
+
+ if (*pathp == NULL)
+ *pathp = malloc(MAXPATHLEN, M_AUDITPATH, M_WAITOK);
+ audit_canon_path_vp(td, rdir, cdir, upath, *pathp);
+}
+
+void
+audit_arg_upath1_vp(struct thread *td, struct vnode *rdir, struct vnode *cdir,
+ char *upath)
+{
+ struct kaudit_record *ar;
+
+ ar = currecord();
+ if (ar == NULL)
+ return;
+
+ audit_arg_upath_vp(td, rdir, cdir, upath, &ar->k_ar.ar_arg_upath1);
+ ARG_SET_VALID(ar, ARG_UPATH1);
+}
+
+void
+audit_arg_upath2_vp(struct thread *td, struct vnode *rdir, struct vnode *cdir,
+ char *upath)
+{
+ struct kaudit_record *ar;
+
+ ar = currecord();
+ if (ar == NULL)
+ return;
+
+ audit_arg_upath_vp(td, rdir, cdir, upath, &ar->k_ar.ar_arg_upath2);
+ ARG_SET_VALID(ar, ARG_UPATH2);
+}
+
/*
* Variants on path auditing that do not canonicalise the path passed in;
* these are for use with filesystem-like subsystems that employ string names,
diff --git a/sys/security/audit/audit_bsm_klib.c b/sys/security/audit/audit_bsm_klib.c
index 14dd28e309da..b10722a4e0e4 100644
--- a/sys/security/audit/audit_bsm_klib.c
+++ b/sys/security/audit/audit_bsm_klib.c
@@ -421,38 +421,23 @@ auditon_command_event(int cmd)
* leave the filename starting with '/' in the audit log in this case.
*/
void
-audit_canon_path(struct thread *td, int dirfd, char *path, char *cpath)
+audit_canon_path_vp(struct thread *td, struct vnode *rdir, struct vnode *cdir,
+ char *path, char *cpath)
{
struct vnode *vp;
char *rbuf, *fbuf, *copy;
- struct filedesc *fdp;
struct sbuf sbf;
- cap_rights_t rights;
int error;
WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "%s: at %s:%d",
__func__, __FILE__, __LINE__);
copy = path;
- fdp = td->td_proc->p_fd;
- FILEDESC_SLOCK(fdp);
- if (*path == '/') {
- vp = fdp->fd_rdir;
- vrefact(vp);
- } else {
- if (dirfd == AT_FDCWD) {
- vp = fdp->fd_cdir;
- vrefact(vp);
- } else {
- error = fgetvp(td, dirfd, cap_rights_init(&rights), &vp);
- if (error != 0) {
- FILEDESC_SUNLOCK(fdp);
- cpath[0] = '\0';
- return;
- }
- }
- }
- FILEDESC_SUNLOCK(fdp);
+ if (*path == '/')
+ vp = rdir;
+ else
+ vp = cdir;
+ MPASS(vp != NULL);
/*
* NB: We require that the supplied array be at least MAXPATHLEN bytes
* long. If this is not the case, then we can run into serious trouble.
@@ -474,7 +459,6 @@ audit_canon_path(struct thread *td, int dirfd, char *path, char *cpath)
* in the future.
*/
error = vn_fullpath_global(td, vp, &rbuf, &fbuf);
- vrele(vp);
if (error) {
cpath[0] = '\0';
return;
@@ -504,3 +488,43 @@ audit_canon_path(struct thread *td, int dirfd, char *path, char *cpath)
}
sbuf_finish(&sbf);
}
+
+void
+audit_canon_path(struct thread *td, int dirfd, char *path, char *cpath)
+{
+ struct vnode *cdir, *rdir;
+ struct filedesc *fdp;
+ cap_rights_t rights;
+ int error;
+
+ WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "%s: at %s:%d",
+ __func__, __FILE__, __LINE__);
+
+ rdir = cdir = NULL;
+ fdp = td->td_proc->p_fd;
+ FILEDESC_SLOCK(fdp);
+ if (*path == '/') {
+ rdir = fdp->fd_rdir;
+ vrefact(rdir);
+ } else {
+ if (dirfd == AT_FDCWD) {
+ cdir = fdp->fd_cdir;
+ vrefact(cdir);
+ } else {
+ error = fgetvp(td, dirfd, cap_rights_init(&rights), &cdir);
+ if (error != 0) {
+ FILEDESC_SUNLOCK(fdp);
+ cpath[0] = '\0';
+ return;
+ }
+ }
+ }
+ FILEDESC_SUNLOCK(fdp);
+
+ audit_canon_path_vp(td, rdir, cdir, path, cpath);
+
+ if (rdir != NULL)
+ vrele(rdir);
+ if (cdir != NULL)
+ vrele(cdir);
+}
diff --git a/sys/security/audit/audit_private.h b/sys/security/audit/audit_private.h
index 4aa811bc1516..890473722552 100644
--- a/sys/security/audit/audit_private.h
+++ b/sys/security/audit/audit_private.h
@@ -472,6 +472,8 @@ au_event_t audit_semsys_to_event(int which);
au_event_t audit_shmsys_to_event(int which);
void audit_canon_path(struct thread *td, int dirfd, char *path,
char *cpath);
+void audit_canon_path_vp(struct thread *td, struct vnode *rdir,
+ struct vnode *cdir, char *path, char *cpath);
au_event_t auditon_command_event(int cmd);
/*