audit: provide audit_canon_path variant which accepts vnodes

This commit is contained in:
Mateusz Guzik 2020-02-21 01:40:49 +00:00
parent 9e826d32e8
commit 7de6c5ebbd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=358191
4 changed files with 103 additions and 23 deletions

View File

@ -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)

View File

@ -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,

View File

@ -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);
}

View File

@ -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);
/*