diff options
author | Roger A. Faulkner <Roger.Faulkner@Oracle.COM> | 2010-07-07 17:36:17 -0700 |
---|---|---|
committer | Roger A. Faulkner <Roger.Faulkner@Oracle.COM> | 2010-07-07 17:36:17 -0700 |
commit | 794f0adb050e571bbfde4d2a19b9f88b852079dd (patch) | |
tree | c1735b3eda175e9096f5b062a73614e73aa5cd9a /usr/src/uts/common/c2 | |
parent | 07925104db56e5c3eacc4865b918bd16af5cec59 (diff) | |
download | illumos-gate-794f0adb050e571bbfde4d2a19b9f88b852079dd.tar.gz |
PSARC 2010/235 POSIX 1003.1-2008 *at(2) syscalls
6910251 need support for all POSIX.1-2008 *at(2) syscalls
6964835 mknod(2) auditing omits the pathname for invalid arguments
Diffstat (limited to 'usr/src/uts/common/c2')
-rw-r--r-- | usr/src/uts/common/c2/audit.c | 7 | ||||
-rw-r--r-- | usr/src/uts/common/c2/audit_event.c | 196 | ||||
-rw-r--r-- | usr/src/uts/common/c2/audit_kevents.h | 4 |
3 files changed, 185 insertions, 22 deletions
diff --git a/usr/src/uts/common/c2/audit.c b/usr/src/uts/common/c2/audit.c index aa3fd4e1b9..bbaf783668 100644 --- a/usr/src/uts/common/c2/audit.c +++ b/usr/src/uts/common/c2/audit.c @@ -18,6 +18,7 @@ * * CDDL HEADER END */ + /* * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. */ @@ -1026,20 +1027,26 @@ audit_setfsat_path(int argnum) switch (tad->tad_scid) { case SYS_faccessat: + case SYS_fchmodat: case SYS_fchownat: case SYS_fstatat: case SYS_fstatat64: + case SYS_mkdirat: + case SYS_mknodat: case SYS_openat: case SYS_openat64: + case SYS_readlinkat: case SYS_unlinkat: fd = uap->arg1; break; + case SYS_linkat: case SYS_renameat: if (argnum == 3) fd = uap->arg3; else fd = uap->arg1; break; + case SYS_symlinkat: case SYS_utimesys: fd = uap->arg2; break; diff --git a/usr/src/uts/common/c2/audit_event.c b/usr/src/uts/common/c2/audit_event.c index 270fa59c96..69464b2b32 100644 --- a/usr/src/uts/common/c2/audit_event.c +++ b/usr/src/uts/common/c2/audit_event.c @@ -18,6 +18,7 @@ * * CDDL HEADER END */ + /* * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved. */ @@ -80,6 +81,7 @@ char _depends_on[] = "fs/sockfs"; static au_event_t aui_fchownat(au_event_t); +static au_event_t aui_fchmodat(au_event_t); static au_event_t aui_open(au_event_t); static au_event_t aui_openat(au_event_t); static au_event_t aui_unlinkat(au_event_t); @@ -114,9 +116,12 @@ static void aus_fchownat(struct t_audit_data *); static void aus_chmod(struct t_audit_data *); static void aus_facl(struct t_audit_data *); static void aus_fchmod(struct t_audit_data *); +static void aus_fchmodat(struct t_audit_data *); static void aus_fcntl(struct t_audit_data *); static void aus_mkdir(struct t_audit_data *); +static void aus_mkdirat(struct t_audit_data *); static void aus_mknod(struct t_audit_data *); +static void aus_mknodat(struct t_audit_data *); static void aus_mount(struct t_audit_data *); static void aus_umount2(struct t_audit_data *); static void aus_msgsys(struct t_audit_data *); @@ -149,6 +154,7 @@ static void aus_setreuid(struct t_audit_data *); static void aus_labelsys(struct t_audit_data *); static void auf_mknod(struct t_audit_data *, int, rval_t *); +static void auf_mknodat(struct t_audit_data *, int, rval_t *); static void auf_msgsys(struct t_audit_data *, int, rval_t *); static void auf_semsys(struct t_audit_data *, int, rval_t *); static void auf_shmsys(struct t_audit_data *, int, rval_t *); @@ -210,7 +216,7 @@ aui_open, AUE_OPEN, aus_open, /* 5 open */ auf_null, S2E_SP, aui_null, AUE_CLOSE, aus_close, /* 6 close */ auf_null, 0, -aui_null, AUE_NULL, aus_null, /* 7 (loadable) was wait */ +aui_null, AUE_LINK, aus_null, /* 7 linkat */ auf_null, 0, aui_null, AUE_NULL, aus_null, /* 8 (loadable) was creat */ auf_null, 0, @@ -218,14 +224,14 @@ aui_null, AUE_LINK, aus_null, /* 9 link */ auf_null, 0, aui_null, AUE_UNLINK, aus_null, /* 10 unlink */ auf_null, 0, -aui_null, AUE_NULL, aus_null, /* 11 (loadable) was exec */ +aui_null, AUE_SYMLINK, aus_null, /* 11 symlinkat */ auf_null, 0, aui_null, AUE_CHDIR, aus_null, /* 12 chdir */ auf_null, S2E_SP, aui_null, AUE_NULL, aus_null, /* 13 time */ auf_null, 0, aui_null, AUE_MKNOD, aus_mknod, /* 14 mknod */ - auf_mknod, 0, + auf_mknod, S2E_MLD, aui_null, AUE_CHMOD, aus_chmod, /* 15 chmod */ auf_null, 0, aui_null, AUE_CHOWN, aus_chown, /* 16 chown */ @@ -240,8 +246,8 @@ aui_null, AUE_NULL, aus_null, /* 20 getpid */ auf_null, 0, aui_null, AUE_MOUNT, aus_mount, /* 21 mount */ auf_null, S2E_MLD, -aui_null, AUE_NULL, aus_null, /* 22 (loadable) was umount */ - auf_null, 0, +aui_null, AUE_READLINK, aus_null, /* 22 readlinkat */ + auf_null, S2E_PUB, aui_null, AUE_SETUID, aus_setuid, /* 23 setuid */ auf_null, 0, aui_null, AUE_NULL, aus_null, /* 24 getuid */ @@ -292,8 +298,8 @@ aui_null, AUE_SETGID, aus_setgid, /* 46 setgid */ auf_null, 0, aui_null, AUE_NULL, aus_null, /* 47 getgid */ auf_null, 0, -aui_null, AUE_NULL, aus_null, /* 48 (loadable) was ssig */ - auf_null, 0, +aui_null, AUE_MKNOD, aus_mknodat, /* 48 mknodat */ + auf_mknodat, S2E_MLD, aui_msgsys, AUE_MSGSYS, aus_msgsys, /* 49 (loadable) msgsys */ auf_msgsys, 0, #if defined(__x86) @@ -403,9 +409,9 @@ aui_null, AUE_NULL, aus_null, /* 99 sigpending */ auf_null, 0, aui_null, AUE_NULL, aus_null, /* 100 setcontext */ auf_null, 0, -aui_null, AUE_NULL, aus_null, /* 101 (loadable) */ +aui_fchmodat, AUE_NULL, aus_fchmodat, /* 101 fchmodat */ auf_null, 0, -aui_null, AUE_NULL, aus_null, /* 102 (loadable) */ +aui_null, AUE_MKDIR, aus_mkdirat, /* 102 mkdirat */ auf_null, 0, aui_null, AUE_STATVFS, aus_null, /* 103 statvfs */ auf_null, S2E_PUB, @@ -890,7 +896,6 @@ aus_fchownat(struct t_audit_data *tad) au_uwrite(au_to_arg32(4, "new file gid", gid)); } -/* chmod start function */ /*ARGSUSED*/ static void aus_chmod(struct t_audit_data *tad) @@ -908,7 +913,6 @@ aus_chmod(struct t_audit_data *tad) au_uwrite(au_to_arg32(2, "new file mode", fmode&07777)); } -/* chmod start function */ /*ARGSUSED*/ static void aus_fchmod(struct t_audit_data *tad) @@ -929,14 +933,82 @@ aus_fchmod(struct t_audit_data *tad) au_uwrite(au_to_arg32(2, "new file mode", fmode&07777)); - /* - * convert file pointer to file descriptor - * Note: fd ref count incremented here. - */ + /* + * convert file pointer to file descriptor + * Note: fd ref count incremented here. + */ if ((fp = getf(fd)) == NULL) return; - /* get path from file struct here */ + /* get path from file struct here */ + fad = F2A(fp); + if (fad->fad_aupath != NULL) { + au_uwrite(au_to_path(fad->fad_aupath)); + } else { + au_uwrite(au_to_arg32(1, "no path: fd", fd)); + } + + vp = fp->f_vnode; + audit_attributes(vp); + + /* decrement file descriptor reference count */ + releasef(fd); +} + +static au_event_t +aui_fchmodat(au_event_t e) +{ + klwp_t *clwp = ttolwp(curthread); + + struct a { + long fd; + long fname; /* char * */ + long fmode; + long flag; + } *uap = (struct a *)clwp->lwp_ap; + + if (uap->fname == NULL) + e = AUE_FCHMOD; + else + e = AUE_CHMOD; + + return (e); +} + +/*ARGSUSED*/ +static void +aus_fchmodat(struct t_audit_data *tad) +{ + klwp_t *clwp = ttolwp(curthread); + uint32_t fmode; + uint32_t fd; + struct file *fp; + struct vnode *vp; + struct f_audit_data *fad; + + struct a { + long fd; + long fname; /* char * */ + long fmode; + long flag; + } *uap = (struct a *)clwp->lwp_ap; + + fd = (uint32_t)uap->fd; + fmode = (uint32_t)uap->fmode; + + au_uwrite(au_to_arg32(2, "new file mode", fmode&07777)); + + if (fd == AT_FDCWD || uap->fname != NULL) /* same as chmod() */ + return; + + /* + * convert file pointer to file descriptor + * Note: fd ref count incremented here. + */ + if ((fp = getf(fd)) == NULL) + return; + + /* get path from file struct here */ fad = F2A(fp); if (fad->fad_aupath != NULL) { au_uwrite(au_to_path(fad->fad_aupath)); @@ -959,7 +1031,7 @@ open_event(uint_t fm) { au_event_t e; - switch (fm & (O_RDONLY|O_WRONLY|O_RDWR|O_CREAT|O_TRUNC)) { + switch (fm & (O_ACCMODE | O_CREAT | O_TRUNC)) { case O_RDONLY: e = AUE_OPEN_R; break; @@ -996,6 +1068,12 @@ open_event(uint_t fm) case O_RDWR | O_TRUNC | O_CREAT: e = AUE_OPEN_RWTC; break; + case O_SEARCH: + e = AUE_OPEN_S; + break; + case O_EXEC: + e = AUE_OPEN_E; + break; default: e = AUE_NULL; break; @@ -1502,6 +1580,24 @@ aus_mkdir(struct t_audit_data *tad) /*ARGSUSED*/ static void +aus_mkdirat(struct t_audit_data *tad) +{ + klwp_t *clwp = ttolwp(curthread); + uint32_t dmode; + + struct a { + long fd; + long dirnamep; /* char * */ + long dmode; + } *uap = (struct a *)clwp->lwp_ap; + + dmode = (uint32_t)uap->dmode; + + au_uwrite(au_to_arg32(2, "mode", dmode)); +} + +/*ARGSUSED*/ +static void aus_mknod(struct t_audit_data *tad) { klwp_t *clwp = ttolwp(curthread); @@ -1540,19 +1636,77 @@ auf_mknod(struct t_audit_data *tad, int error, rval_t *rval) } *uap = (struct a *)clwp->lwp_ap; /* no error, then already path token in audit record */ - if (error != EPERM) + if (error != EPERM && error != EINVAL) return; - /* not auditing this event, nothing then to do */ - if (tad->tad_flag == 0) + /* do the lookup to force generation of path token */ + pnamep = (caddr_t)uap->pnamep; + tad->tad_ctrl |= TAD_NOATTRB; + error = lookupname(pnamep, UIO_USERSPACE, NO_FOLLOW, &dvp, NULLVPP); + if (error == 0) + VN_RELE(dvp); +} + +/*ARGSUSED*/ +static void +aus_mknodat(struct t_audit_data *tad) +{ + klwp_t *clwp = ttolwp(curthread); + uint32_t fmode; + dev_t dev; + + struct a { + long fd; + long pnamep; /* char * */ + long fmode; + long dev; + } *uap = (struct a *)clwp->lwp_ap; + + fmode = (uint32_t)uap->fmode; + dev = (dev_t)uap->dev; + + au_uwrite(au_to_arg32(2, "mode", fmode)); +#ifdef _LP64 + au_uwrite(au_to_arg64(3, "dev", dev)); +#else + au_uwrite(au_to_arg32(3, "dev", dev)); +#endif +} + +/*ARGSUSED*/ +static void +auf_mknodat(struct t_audit_data *tad, int error, rval_t *rval) +{ + klwp_t *clwp = ttolwp(curthread); + vnode_t *startvp; + vnode_t *dvp; + caddr_t pnamep; + int fd; + + struct a { + long fd; + long pnamep; /* char * */ + long fmode; + long dev; + } *uap = (struct a *)clwp->lwp_ap; + + /* no error, then already path token in audit record */ + if (error != EPERM && error != EINVAL) return; /* do the lookup to force generation of path token */ + fd = (int)uap->fd; pnamep = (caddr_t)uap->pnamep; + if (pnamep == NULL || + fgetstartvp(fd, pnamep, &startvp) != 0) + return; tad->tad_ctrl |= TAD_NOATTRB; - error = lookupname(pnamep, UIO_USERSPACE, NO_FOLLOW, &dvp, NULLVPP); + error = lookupnameat(pnamep, UIO_USERSPACE, NO_FOLLOW, &dvp, NULLVPP, + startvp); if (error == 0) VN_RELE(dvp); + if (startvp != NULL) + VN_RELE(startvp); } /*ARGSUSED*/ diff --git a/usr/src/uts/common/c2/audit_kevents.h b/usr/src/uts/common/c2/audit_kevents.h index b106fdd3d6..758654dfcc 100644 --- a/usr/src/uts/common/c2/audit_kevents.h +++ b/usr/src/uts/common/c2/audit_kevents.h @@ -159,8 +159,10 @@ extern "C" { #define AUE_ASYNC_DAEMON_EXIT 114 /* =no async_daemon(2) exited */ #define AUE_NFSSVC_EXIT 115 /* =no nfssvc(2) exited */ #define AUE_PFEXEC 116 /* =ps,ex,ua,as execve(2) w/ pfexec */ +#define AUE_OPEN_S 117 /* =fr open(2): search */ +#define AUE_OPEN_E 118 /* =fr open(2): exec */ /* - * 117 - 129 are available for future growth (old SunOS_CMW events + * 119 - 129 are available for future growth (old SunOS_CMW events * that had no libbsm or praudit support or references) */ #define AUE_GETAUID 130 /* =aa getauid(2) */ |