Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Feb 2020 01:40:49 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r358191 - head/sys/security/audit
Message-ID:  <202002210140.01L1enQ3060179@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjg
Date: Fri Feb 21 01:40:49 2020
New Revision: 358191
URL: https://svnweb.freebsd.org/changeset/base/358191

Log:
  audit: provide audit_canon_path variant which accepts vnodes

Modified:
  head/sys/security/audit/audit.h
  head/sys/security/audit/audit_arg.c
  head/sys/security/audit/audit_bsm_klib.c
  head/sys/security/audit/audit_private.h

Modified: head/sys/security/audit/audit.h
==============================================================================
--- head/sys/security/audit/audit.h	Fri Feb 21 01:40:20 2020	(r358190)
+++ head/sys/security/audit/audit.h	Fri Feb 21 01:40:49 2020	(r358191)
@@ -120,6 +120,10 @@ void	 audit_arg_upath1(struct thread *td, int dirfd, c
 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)

Modified: head/sys/security/audit/audit_arg.c
==============================================================================
--- head/sys/security/audit/audit_arg.c	Fri Feb 21 01:40:20 2020	(r358190)
+++ head/sys/security/audit/audit_arg.c	Fri Feb 21 01:40:49 2020	(r358191)
@@ -767,6 +767,44 @@ audit_arg_upath2(struct thread *td, int dirfd, char *u
 	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,

Modified: head/sys/security/audit/audit_bsm_klib.c
==============================================================================
--- head/sys/security/audit/audit_bsm_klib.c	Fri Feb 21 01:40:20 2020	(r358190)
+++ head/sys/security/audit/audit_bsm_klib.c	Fri Feb 21 01:40:49 2020	(r358191)
@@ -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 *p
 	 * in the future.
 	 */
 	error = vn_fullpath_global(td, vp, &rbuf, &fbuf);
-	vrele(vp);
 	if (error) {
 		cpath[0] = '\0';
 		return;
@@ -503,4 +487,44 @@ audit_canon_path(struct thread *td, int dirfd, char *p
 		return;
 	}
 	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);
 }

Modified: head/sys/security/audit/audit_private.h
==============================================================================
--- head/sys/security/audit/audit_private.h	Fri Feb 21 01:40:20 2020	(r358190)
+++ head/sys/security/audit/audit_private.h	Fri Feb 21 01:40:49 2020	(r358191)
@@ -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);
 
 /*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202002210140.01L1enQ3060179>