Add another flags argument to vn_open_cred. Use it to specify that some

vn_open_cred invocations shall not audit namei path.

In particular, specify VN_OPEN_NOAUDIT for dotdot lookup performed by
default implementation of vop_vptocnp, and for the open done for core
file. vn_fullpath is called from the audit code, and vn_open there need
to disable audit to avoid infinite recursion. Core file is created on
return to user mode, that, in particular, happens during syscall return.
The creation of the core file is audited by direct calls, and we do not
want to overwrite audit information for syscall.

Reported, reviewed and tested by: rwatson
This commit is contained in:
Konstantin Belousov 2009-06-21 13:41:32 +00:00
parent c61860f8a6
commit e0c161b89c
8 changed files with 22 additions and 16 deletions

View File

@ -85,7 +85,8 @@ kobj_open_file_vnode(const char *file)
flags = FREAD;
NDINIT(&nd, LOOKUP, MPSAFE, UIO_SYSSPACE, file, td);
error = vn_open_cred(&nd, &flags, O_NOFOLLOW, curthread->td_ucred, NULL);
error = vn_open_cred(&nd, &flags, O_NOFOLLOW, 0, curthread->td_ucred,
NULL);
NDFREE(&nd, NDF_ONLY_PNBUF);
if (error != 0)
return (NULL);

View File

@ -182,7 +182,7 @@ vn_openat(char *pnamep, enum uio_seg seg, int filemode, int createmode,
vref(startvp);
NDINIT_ATVP(&nd, operation, MPSAFE, UIO_SYSSPACE, pnamep, startvp, td);
filemode |= O_NOFOLLOW;
error = vn_open_cred(&nd, &filemode, createmode, td->td_ucred, NULL);
error = vn_open_cred(&nd, &filemode, createmode, 0, td->td_ucred, NULL);
NDFREE(&nd, NDF_ONLY_PNBUF);
if (error == 0) {
/* We just unlock so we hold a reference. */

View File

@ -4519,7 +4519,7 @@ vop_getextattr {
flags = FREAD;
NDINIT_ATVP(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_SYSSPACE, attrname,
xvp, td);
error = vn_open_cred(&nd, &flags, 0, ap->a_cred, NULL);
error = vn_open_cred(&nd, &flags, 0, 0, ap->a_cred, NULL);
vp = nd.ni_vp;
NDFREE(&nd, NDF_ONLY_PNBUF);
if (error != 0) {
@ -4640,7 +4640,7 @@ vop_setextattr {
flags = FFLAGS(O_WRONLY | O_CREAT);
NDINIT_ATVP(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_SYSSPACE, attrname,
xvp, td);
error = vn_open_cred(&nd, &flags, 0600, ap->a_cred, NULL);
error = vn_open_cred(&nd, &flags, 0600, 0, ap->a_cred, NULL);
vp = nd.ni_vp;
NDFREE(&nd, NDF_ONLY_PNBUF);
if (error != 0) {

View File

@ -351,7 +351,7 @@ alq_open(struct alq **alqp, const char *file, struct ucred *cred, int cmode,
NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_SYSSPACE, file, td);
flags = FWRITE | O_NOFOLLOW | O_CREAT;
error = vn_open_cred(&nd, &flags, cmode, cred, NULL);
error = vn_open_cred(&nd, &flags, cmode, 0, cred, NULL);
if (error)
return (error);

View File

@ -2940,7 +2940,8 @@ coredump(struct thread *td)
restart:
NDINIT(&nd, LOOKUP, NOFOLLOW | MPSAFE, UIO_SYSSPACE, name, td);
flags = O_CREAT | FWRITE | O_NOFOLLOW;
error = vn_open(&nd, &flags, S_IRUSR | S_IWUSR, NULL);
error = vn_open_cred(&nd, &flags, S_IRUSR | S_IWUSR, VN_OPEN_NOAUDIT,
NULL, NULL);
if (error) {
#ifdef AUDIT
audit_proc_coredump(td, name, error);

View File

@ -723,7 +723,7 @@ vop_stdvptocnp(struct vop_vptocnp_args *ap)
NDINIT_ATVP(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE,
"..", vp, td);
flags = FREAD;
error = vn_open(&nd, &flags, 0, NULL);
error = vn_open_cred(&nd, &flags, 0, VN_OPEN_NOAUDIT, NULL, NULL);
if (error) {
vn_lock(vp, locked | LK_RETRY);
return (error);

View File

@ -91,7 +91,7 @@ vn_open(ndp, flagp, cmode, fp)
{
struct thread *td = ndp->ni_cnd.cn_thread;
return (vn_open_cred(ndp, flagp, cmode, td->td_ucred, fp));
return (vn_open_cred(ndp, flagp, cmode, 0, td->td_ucred, fp));
}
/*
@ -102,11 +102,8 @@ vn_open(ndp, flagp, cmode, fp)
* due to the NDINIT being done elsewhere.
*/
int
vn_open_cred(ndp, flagp, cmode, cred, fp)
struct nameidata *ndp;
int *flagp, cmode;
struct ucred *cred;
struct file *fp;
vn_open_cred(struct nameidata *ndp, int *flagp, int cmode, u_int vn_open_flags,
struct ucred *cred, struct file *fp)
{
struct vnode *vp;
struct mount *mp;
@ -124,9 +121,11 @@ vn_open_cred(ndp, flagp, cmode, cred, fp)
if (fmode & O_CREAT) {
ndp->ni_cnd.cn_nameiop = CREATE;
ndp->ni_cnd.cn_flags = ISOPEN | LOCKPARENT | LOCKLEAF |
MPSAFE | AUDITVNODE1;
MPSAFE;
if ((fmode & O_EXCL) == 0 && (fmode & O_NOFOLLOW) == 0)
ndp->ni_cnd.cn_flags |= FOLLOW;
if (!(vn_open_flags & VN_OPEN_NOAUDIT))
ndp->ni_cnd.cn_flags |= AUDITVNODE1;
bwillwrite();
if ((error = namei(ndp)) != 0)
return (error);
@ -181,9 +180,11 @@ vn_open_cred(ndp, flagp, cmode, cred, fp)
ndp->ni_cnd.cn_nameiop = LOOKUP;
ndp->ni_cnd.cn_flags = ISOPEN |
((fmode & O_NOFOLLOW) ? NOFOLLOW : FOLLOW) |
LOCKLEAF | MPSAFE | AUDITVNODE1;
LOCKLEAF | MPSAFE;
if (!(fmode & FWRITE))
ndp->ni_cnd.cn_flags |= LOCKSHARED;
if (!(vn_open_flags & VN_OPEN_NOAUDIT))
ndp->ni_cnd.cn_flags |= AUDITVNODE1;
if ((error = namei(ndp)) != 0)
return (error);
if (!mpsafe)

View File

@ -562,6 +562,9 @@ vn_canvmio(struct vnode *vp)
*/
#include "vnode_if.h"
/* vn_open_flags */
#define VN_OPEN_NOAUDIT 0x00000001
/*
* Public vnode manipulation functions.
*/
@ -637,7 +640,7 @@ int _vn_lock(struct vnode *vp, int flags, char *file, int line);
#define vn_lock(vp, flags) _vn_lock(vp, flags, __FILE__, __LINE__)
int vn_open(struct nameidata *ndp, int *flagp, int cmode, struct file *fp);
int vn_open_cred(struct nameidata *ndp, int *flagp, int cmode,
struct ucred *cred, struct file *fp);
u_int vn_open_flags, struct ucred *cred, struct file *fp);
int vn_pollrecord(struct vnode *vp, struct thread *p, int events);
int vn_rdwr(enum uio_rw rw, struct vnode *vp, void *base,
int len, off_t offset, enum uio_seg segflg, int ioflg,