In order to better support flexible and extensible access control,

make a series of modifications to the credential arguments relating
to file read and write operations to cliarfy which credential is
used for what:

- Change fo_read() and fo_write() to accept "active_cred" instead of
  "cred", and change the semantics of consumers of fo_read() and
  fo_write() to pass the active credential of the thread requesting
  an operation rather than the cached file cred.  The cached file
  cred is still available in fo_read() and fo_write() consumers
  via fp->f_cred.  These changes largely in sys_generic.c.

For each implementation of fo_read() and fo_write(), update cred
usage to reflect this change and maintain current semantics:

- badfo_readwrite() unchanged
- kqueue_read/write() unchanged
  pipe_read/write() now authorize MAC using active_cred rather
  than td->td_ucred
- soo_read/write() unchanged
- vn_read/write() now authorize MAC using active_cred but
  VOP_READ/WRITE() with fp->f_cred

Modify vn_rdwr() to accept two credential arguments instead of a
single credential: active_cred and file_cred.  Use active_cred
for MAC authorization, and select a credential for use in
VOP_READ/WRITE() based on whether file_cred is NULL or not.  If
file_cred is provided, authorize the VOP using that cred,
otherwise the active credential, matching current semantics.

Modify current vn_rdwr() consumers to pass a file_cred if used
in the context of a struct file, and to always pass active_cred.
When vn_rdwr() is used without a file_cred, pass NOCRED.

These changes should maintain current semantics for read/write,
but avoid a redundant passing of fp->f_cred, as well as making
it more clear what the origin of each credential is in file
descriptor read/write operations.

Follow-up commits will make similar changes to other file descriptor
operations, and modify the MAC framework to pass both credentials
to MAC policy modules so they can implement either semantic for
revocation.

Obtained from:	TrustedBSD Project
Sponsored by:	DARPA, NAI Labs
This commit is contained in:
Robert Watson 2002-08-15 20:55:08 +00:00
parent e2a5fdf911
commit 9ca435893b
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=101941
31 changed files with 145 additions and 106 deletions

View File

@ -408,12 +408,12 @@ cpu_coredump(td, vp, cred)
/* XXXKSE this is totally bogus! (and insecure) */
error = vn_rdwr(UIO_WRITE, vp, (caddr_t) td->td_proc->p_uarea,
ctob(UAREA_PAGES), (off_t)0,
UIO_SYSSPACE, IO_UNIT, cred, (int *)NULL, td);
UIO_SYSSPACE, IO_UNIT, cred, NOCRED, (int *)NULL, td);
if (error)
return error;
error = vn_rdwr(UIO_WRITE, vp, (caddr_t) td->td_kstack,
ctob(KSTACK_PAGES), (off_t)ctob(UAREA_PAGES),
UIO_SYSSPACE, IO_UNIT, cred, (int *)NULL, td);
UIO_SYSSPACE, IO_UNIT, cred, NOCRED, (int *)NULL, td);
return error;
}

View File

@ -470,7 +470,8 @@ cpu_coredump(td, vp, cred)
error = vn_rdwr(UIO_WRITE, vp, (caddr_t) tempuser,
ctob(UAREA_PAGES + KSTACK_PAGES),
(off_t)0, UIO_SYSSPACE, IO_UNIT, cred, (int *)NULL, td);
(off_t)0, UIO_SYSSPACE, IO_UNIT, cred, NOCRED,
(int *)NULL, td);
free(tempuser, M_TEMP);

View File

@ -192,14 +192,14 @@ pecoff_coredump(register struct thread * td, register struct vnode * vp,
error = vn_rdwr_inchunks(UIO_WRITE, vp, vm->vm_daddr,
(int)ctob(vm->vm_dsize),
(off_t)ctob((UAREA_PAGES+KSTACK_PAGES)),
UIO_USERSPACE, IO_UNIT, cred, (int *)NULL, td);
UIO_USERSPACE, IO_UNIT, cred, NOCRED, (int *)NULL, td);
if (error == 0)
error = vn_rdwr_inchunks(UIO_WRITE, vp,
(caddr_t)trunc_page(USRSTACK - ctob(vm->vm_ssize)),
round_page(ctob(vm->vm_ssize)),
(off_t)ctob((UAREA_PAGES+KSTACK_PAGES)) +
ctob(vm->vm_dsize),
UIO_USERSPACE, IO_UNIT, cred, (int *)NULL, td);
UIO_USERSPACE, IO_UNIT, cred, NOCRED, (int *)NULL, td);
return (error);
}
@ -608,7 +608,7 @@ pecoff_read_from(td, vp, pos, buf, siz)
size_t resid;
error = vn_rdwr(UIO_READ, vp, buf, siz, pos,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
&resid, td);
if (error)
return error;

View File

@ -1011,7 +1011,7 @@ ext2_dirempty(ip, parentino, cred)
for (off = 0; off < ip->i_size; off += dp->rec_len) {
error = vn_rdwr(UIO_READ, ITOV(ip), (caddr_t)dp, MINDIRSIZ,
off, UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK, cred,
&count, (struct thread *)0);
NOCRED, &count, (struct thread *)0);
/*
* Since we read MINDIRSIZ, residual must
* be 0 unless we're at end of file.
@ -1075,7 +1075,7 @@ ext2_checkpath(source, target, cred)
}
error = vn_rdwr(UIO_READ, vp, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0, UIO_SYSSPACE,
IO_NODELOCKED | IO_NOMACCHECK, cred, (int *)0,
IO_NODELOCKED | IO_NOMACCHECK, cred, NOCRED, (int *)0,
(struct thread *)0);
if (error != 0)
break;

View File

@ -1224,7 +1224,8 @@ ext2_rename(ap)
error = vn_rdwr(UIO_READ, fvp, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0,
UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK,
tcnp->cn_cred, (int *)0, (struct thread *)0);
tcnp->cn_cred, NOCRED, (int *)0,
(struct thread *)0);
if (error == 0) {
/* Like ufs little-endian: */
namlen = dirbuf.dotdot_type;
@ -1241,7 +1242,8 @@ ext2_rename(ap)
(off_t)0, UIO_SYSSPACE,
IO_NODELOCKED | IO_SYNC |
IO_NOMACCHECK, tcnp->cn_cred,
(int *)0, (struct thread *)0);
NOCRED, (int *)0,
(struct thread *)0);
cache_purge(fdvp);
}
}
@ -1376,8 +1378,8 @@ ext2_mkdir(ap)
dirtemplate.dotdot_reclen = DIRBLKSIZ - 12;
error = vn_rdwr(UIO_WRITE, tvp, (caddr_t)&dirtemplate,
sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE,
IO_NODELOCKED | IO_SYNC | IO_NOMACCHECK, cnp->cn_cred, (int *)0,
(struct thread *)0);
IO_NODELOCKED | IO_SYNC | IO_NOMACCHECK, cnp->cn_cred, NOCRED,
(int *)0, (struct thread *)0);
if (error) {
dp->i_nlink--;
dp->i_flag |= IN_CHANGE;
@ -1514,7 +1516,7 @@ ext2_symlink(ap)
} else
error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK,
ap->a_cnp->cn_cred, (int *)0, (struct thread *)0);
ap->a_cnp->cn_cred, NOCRED, (int *)0, (struct thread *)0);
if (error)
vput(vp);
return (error);

View File

@ -1011,7 +1011,7 @@ ext2_dirempty(ip, parentino, cred)
for (off = 0; off < ip->i_size; off += dp->rec_len) {
error = vn_rdwr(UIO_READ, ITOV(ip), (caddr_t)dp, MINDIRSIZ,
off, UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK, cred,
&count, (struct thread *)0);
NOCRED, &count, (struct thread *)0);
/*
* Since we read MINDIRSIZ, residual must
* be 0 unless we're at end of file.
@ -1075,7 +1075,7 @@ ext2_checkpath(source, target, cred)
}
error = vn_rdwr(UIO_READ, vp, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0, UIO_SYSSPACE,
IO_NODELOCKED | IO_NOMACCHECK, cred, (int *)0,
IO_NODELOCKED | IO_NOMACCHECK, cred, NOCRED, (int *)0,
(struct thread *)0);
if (error != 0)
break;

View File

@ -1224,7 +1224,8 @@ ext2_rename(ap)
error = vn_rdwr(UIO_READ, fvp, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0,
UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK,
tcnp->cn_cred, (int *)0, (struct thread *)0);
tcnp->cn_cred, NOCRED, (int *)0,
(struct thread *)0);
if (error == 0) {
/* Like ufs little-endian: */
namlen = dirbuf.dotdot_type;
@ -1241,7 +1242,8 @@ ext2_rename(ap)
(off_t)0, UIO_SYSSPACE,
IO_NODELOCKED | IO_SYNC |
IO_NOMACCHECK, tcnp->cn_cred,
(int *)0, (struct thread *)0);
NOCRED, (int *)0,
(struct thread *)0);
cache_purge(fdvp);
}
}
@ -1376,8 +1378,8 @@ ext2_mkdir(ap)
dirtemplate.dotdot_reclen = DIRBLKSIZ - 12;
error = vn_rdwr(UIO_WRITE, tvp, (caddr_t)&dirtemplate,
sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE,
IO_NODELOCKED | IO_SYNC | IO_NOMACCHECK, cnp->cn_cred, (int *)0,
(struct thread *)0);
IO_NODELOCKED | IO_SYNC | IO_NOMACCHECK, cnp->cn_cred, NOCRED,
(int *)0, (struct thread *)0);
if (error) {
dp->i_nlink--;
dp->i_flag |= IN_CHANGE;
@ -1514,7 +1516,7 @@ ext2_symlink(ap)
} else
error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK,
ap->a_cnp->cn_cred, (int *)0, (struct thread *)0);
ap->a_cnp->cn_cred, NOCRED, (int *)0, (struct thread *)0);
if (error)
vput(vp);
return (error);

View File

@ -470,7 +470,8 @@ cpu_coredump(td, vp, cred)
error = vn_rdwr(UIO_WRITE, vp, (caddr_t) tempuser,
ctob(UAREA_PAGES + KSTACK_PAGES),
(off_t)0, UIO_SYSSPACE, IO_UNIT, cred, (int *)NULL, td);
(off_t)0, UIO_SYSSPACE, IO_UNIT, cred, NOCRED,
(int *)NULL, td);
free(tempuser, M_TEMP);

View File

@ -375,12 +375,12 @@ cpu_coredump(td, vp, cred)
error = vn_rdwr(UIO_WRITE, vp, (caddr_t) td->td_proc->p_uarea,
ctob(UAREA_PAGES), (off_t)0,
UIO_SYSSPACE, IO_UNIT, cred, (int *)NULL, td);
UIO_SYSSPACE, IO_UNIT, cred, NOCRED, (int *)NULL, td);
if (error)
return error;
error = vn_rdwr(UIO_WRITE, vp, (caddr_t) td->td_kstack,
ctob(KSTACK_PAGES), (off_t)0,
UIO_SYSSPACE, IO_UNIT, cred, (int *)NULL, td);
UIO_SYSSPACE, IO_UNIT, cred, NOCRED,(int *)NULL, td);
return error;
}

View File

@ -268,14 +268,14 @@ aout_coredump(td, vp, limit)
error = vn_rdwr(UIO_WRITE, vp, vm->vm_daddr,
(int)ctob(vm->vm_dsize),
(off_t)ctob(UAREA_PAGES + KSTACK_PAGES), UIO_USERSPACE,
IO_UNIT | IO_DIRECT, cred, (int *) NULL, td);
IO_UNIT | IO_DIRECT, cred, NOCRED, (int *) NULL, td);
if (error == 0)
error = vn_rdwr_inchunks(UIO_WRITE, vp,
(caddr_t) trunc_page(USRSTACK - ctob(vm->vm_ssize)),
round_page(ctob(vm->vm_ssize)),
(off_t)ctob(UAREA_PAGES + KSTACK_PAGES) +
ctob(vm->vm_dsize), UIO_USERSPACE,
IO_UNIT | IO_DIRECT, cred, (int *) NULL, td);
IO_UNIT | IO_DIRECT, cred, NOCRED, (int *) NULL, td);
return (error);
}

View File

@ -967,7 +967,8 @@ __elfN(coredump)(td, vp, limit)
error = vn_rdwr_inchunks(UIO_WRITE, vp,
(caddr_t)(uintptr_t)php->p_vaddr,
php->p_filesz, offset, UIO_USERSPACE,
IO_UNIT | IO_DIRECT, cred, (int *)NULL, curthread); /* XXXKSE */
IO_UNIT | IO_DIRECT, cred, NOCRED, (int *)NULL,
curthread); /* XXXKSE */
if (error != 0)
break;
offset += php->p_filesz;
@ -1131,7 +1132,8 @@ __elfN(corehdr)(td, vp, cred, numsegs, hdr, hdrsize)
/* Write it to the core file. */
return vn_rdwr_inchunks(UIO_WRITE, vp, hdr, hdrsize, (off_t)0,
UIO_SYSSPACE, IO_UNIT | IO_DIRECT, cred, NULL, td); /* XXXKSE */
UIO_SYSSPACE, IO_UNIT | IO_DIRECT, cred, NOCRED, NULL,
td); /* XXXKSE */
}
static void

View File

@ -267,7 +267,7 @@ acct_process(td)
*/
VOP_LEASE(vp, td, acctcred, LEASE_WRITE);
return (vn_rdwr(UIO_WRITE, vp, (caddr_t)&acct, sizeof (acct),
(off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, acctcred,
(off_t)0, UIO_SYSSPACE, IO_APPEND|IO_UNIT, acctcred, NOCRED,
(int *)0, td));
}

View File

@ -96,9 +96,10 @@ static struct cdevsw fildesc_cdevsw = {
/* flags */ 0,
};
static int do_dup(struct filedesc *fdp, int old, int new, register_t *retval, struct thread *td);
static int do_dup(struct filedesc *fdp, int old, int new, register_t *retval,
struct thread *td);
static int badfo_readwrite(struct file *fp, struct uio *uio,
struct ucred *cred, int flags, struct thread *td);
struct ucred *active_cred, int flags, struct thread *td);
static int badfo_ioctl(struct file *fp, u_long com, void *data,
struct thread *td);
static int badfo_poll(struct file *fp, int events,
@ -2145,10 +2146,10 @@ struct fileops badfileops = {
};
static int
badfo_readwrite(fp, uio, cred, flags, td)
badfo_readwrite(fp, uio, active_cred, flags, td)
struct file *fp;
struct uio *uio;
struct ucred *cred;
struct ucred *active_cred;
struct thread *td;
int flags;
{

View File

@ -57,9 +57,9 @@ static int kqueue_scan(struct file *fp, int maxevents,
struct kevent *ulistp, const struct timespec *timeout,
struct thread *td);
static int kqueue_read(struct file *fp, struct uio *uio,
struct ucred *cred, int flags, struct thread *td);
struct ucred *active_cred, int flags, struct thread *td);
static int kqueue_write(struct file *fp, struct uio *uio,
struct ucred *cred, int flags, struct thread *td);
struct ucred *active_cred, int flags, struct thread *td);
static int kqueue_ioctl(struct file *fp, u_long com, void *data,
struct thread *td);
static int kqueue_poll(struct file *fp, int events, struct ucred *cred,
@ -777,7 +777,7 @@ kqueue_scan(struct file *fp, int maxevents, struct kevent *ulistp,
*/
/*ARGSUSED*/
static int
kqueue_read(struct file *fp, struct uio *uio, struct ucred *cred,
kqueue_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
int flags, struct thread *td)
{
return (ENXIO);
@ -785,7 +785,7 @@ kqueue_read(struct file *fp, struct uio *uio, struct ucred *cred,
/*ARGSUSED*/
static int
kqueue_write(struct file *fp, struct uio *uio, struct ucred *cred,
kqueue_write(struct file *fp, struct uio *uio, struct ucred *active_cred,
int flags, struct thread *td)
{
return (ENXIO);

View File

@ -1464,7 +1464,7 @@ linker_hints_lookup(const char *path, int pathlen, const char *modname,
if (hints == NULL)
goto bad;
error = vn_rdwr(UIO_READ, nd.ni_vp, (caddr_t)hints, vattr.va_size, 0,
UIO_SYSSPACE, IO_NODELOCKED, cred, &reclen, td);
UIO_SYSSPACE, IO_NODELOCKED, cred, NOCRED, &reclen, td);
if (error)
goto bad;
VOP_UNLOCK(nd.ni_vp, 0, td);

View File

@ -211,7 +211,8 @@ link_aout_load_file(linker_class_t lc, const char* filename, linker_file_t* resu
* Read the a.out header from the file.
*/
error = vn_rdwr(UIO_READ, nd.ni_vp, (void*) &header, sizeof header, 0,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, &resid, td);
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
&resid, td);
if (error)
goto out;
@ -236,7 +237,8 @@ link_aout_load_file(linker_class_t lc, const char* filename, linker_file_t* resu
*/
error = vn_rdwr(UIO_READ, nd.ni_vp, (void*) af->address,
header.a_text + header.a_data, 0,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, &resid, td);
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
&resid, td);
if (error)
goto out;
bzero(af->address + header.a_text + header.a_data, header.a_bss);

View File

@ -570,7 +570,8 @@ link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* resu
}
hdr = (Elf_Ehdr *)firstpage;
error = vn_rdwr(UIO_READ, nd.ni_vp, firstpage, PAGE_SIZE, 0,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, &resid, td);
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
&resid, td);
nbytes = PAGE_SIZE - resid;
if (error)
goto out;
@ -709,7 +710,8 @@ link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* resu
caddr_t segbase = mapbase + segs[i]->p_vaddr - base_vaddr;
error = vn_rdwr(UIO_READ, nd.ni_vp,
segbase, segs[i]->p_filesz, segs[i]->p_offset,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, &resid, td);
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
&resid, td);
if (error) {
goto out;
}
@ -769,7 +771,8 @@ link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* resu
}
error = vn_rdwr(UIO_READ, nd.ni_vp,
(caddr_t)shdr, nbytes, hdr->e_shoff,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, &resid, td);
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
&resid, td);
if (error)
goto out;
symtabindex = -1;
@ -794,12 +797,14 @@ link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* resu
}
error = vn_rdwr(UIO_READ, nd.ni_vp,
ef->symbase, symcnt, shdr[symtabindex].sh_offset,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, &resid, td);
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
&resid, td);
if (error)
goto out;
error = vn_rdwr(UIO_READ, nd.ni_vp,
ef->strbase, strcnt, shdr[symstrindex].sh_offset,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, &resid, td);
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
&resid, td);
if (error)
goto out;

View File

@ -570,7 +570,8 @@ link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* resu
}
hdr = (Elf_Ehdr *)firstpage;
error = vn_rdwr(UIO_READ, nd.ni_vp, firstpage, PAGE_SIZE, 0,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, &resid, td);
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
&resid, td);
nbytes = PAGE_SIZE - resid;
if (error)
goto out;
@ -709,7 +710,8 @@ link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* resu
caddr_t segbase = mapbase + segs[i]->p_vaddr - base_vaddr;
error = vn_rdwr(UIO_READ, nd.ni_vp,
segbase, segs[i]->p_filesz, segs[i]->p_offset,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, &resid, td);
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
&resid, td);
if (error) {
goto out;
}
@ -769,7 +771,8 @@ link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* resu
}
error = vn_rdwr(UIO_READ, nd.ni_vp,
(caddr_t)shdr, nbytes, hdr->e_shoff,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, &resid, td);
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
&resid, td);
if (error)
goto out;
symtabindex = -1;
@ -794,12 +797,14 @@ link_elf_load_file(linker_class_t cls, const char* filename, linker_file_t* resu
}
error = vn_rdwr(UIO_READ, nd.ni_vp,
ef->symbase, symcnt, shdr[symtabindex].sh_offset,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, &resid, td);
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
&resid, td);
if (error)
goto out;
error = vn_rdwr(UIO_READ, nd.ni_vp,
ef->strbase, strcnt, shdr[symstrindex].sh_offset,
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, &resid, td);
UIO_SYSSPACE, IO_NODELOCKED, td->td_ucred, NOCRED,
&resid, td);
if (error)
goto out;

View File

@ -192,7 +192,7 @@ dofileread(td, fp, fd, buf, nbyte, offset, flags)
#endif
cnt = nbyte;
if ((error = fo_read(fp, &auio, fp->f_cred, flags, td))) {
if ((error = fo_read(fp, &auio, td->td_ucred, flags, td))) {
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;
@ -282,7 +282,7 @@ readv(td, uap)
}
#endif
cnt = auio.uio_resid;
if ((error = fo_read(fp, &auio, fp->f_cred, 0, td))) {
if ((error = fo_read(fp, &auio, td->td_ucred, 0, td))) {
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;
@ -416,7 +416,7 @@ dofilewrite(td, fp, fd, buf, nbyte, offset, flags)
cnt = nbyte;
if (fp->f_type == DTYPE_VNODE)
bwillwrite();
if ((error = fo_write(fp, &auio, fp->f_cred, flags, td))) {
if ((error = fo_write(fp, &auio, td->td_ucred, flags, td))) {
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;
@ -518,7 +518,7 @@ writev(td, uap)
cnt = auio.uio_resid;
if (fp->f_type == DTYPE_VNODE)
bwillwrite();
if ((error = fo_write(fp, &auio, fp->f_cred, 0, td))) {
if ((error = fo_write(fp, &auio, td->td_ucred, 0, td))) {
if (auio.uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;

View File

@ -95,9 +95,9 @@
* interfaces to the outside world
*/
static int pipe_read(struct file *fp, struct uio *uio,
struct ucred *cred, int flags, struct thread *td);
struct ucred *active_cred, int flags, struct thread *td);
static int pipe_write(struct file *fp, struct uio *uio,
struct ucred *cred, int flags, struct thread *td);
struct ucred *active_cred, int flags, struct thread *td);
static int pipe_close(struct file *fp, struct thread *td);
static int pipe_poll(struct file *fp, int events, struct ucred *cred,
struct thread *td);
@ -449,10 +449,10 @@ pipeselwakeup(cpipe)
/* ARGSUSED */
static int
pipe_read(fp, uio, cred, flags, td)
pipe_read(fp, uio, active_cred, flags, td)
struct file *fp;
struct uio *uio;
struct ucred *cred;
struct ucred *active_cred;
struct thread *td;
int flags;
{
@ -468,7 +468,7 @@ pipe_read(fp, uio, cred, flags, td)
goto unlocked_error;
#ifdef MAC
error = mac_check_pipe_op(td->td_ucred, rpipe, MAC_OP_PIPE_READ);
error = mac_check_pipe_op(active_cred, rpipe, MAC_OP_PIPE_READ);
if (error)
goto locked_error;
#endif
@ -861,10 +861,10 @@ pipe_direct_write(wpipe, uio)
#endif
static int
pipe_write(fp, uio, cred, flags, td)
pipe_write(fp, uio, active_cred, flags, td)
struct file *fp;
struct uio *uio;
struct ucred *cred;
struct ucred *active_cred;
struct thread *td;
int flags;
{
@ -884,7 +884,7 @@ pipe_write(fp, uio, cred, flags, td)
return (EPIPE);
}
#ifdef MAC
error = mac_check_pipe_op(td->td_ucred, wpipe, MAC_OP_PIPE_WRITE);
error = mac_check_pipe_op(active_cred, wpipe, MAC_OP_PIPE_WRITE);
if (error) {
PIPE_UNLOCK(rpipe);
return (error);

View File

@ -57,10 +57,10 @@ struct fileops socketops = {
/* ARGSUSED */
int
soo_read(fp, uio, cred, flags, td)
soo_read(fp, uio, active_cred, flags, td)
struct file *fp;
struct uio *uio;
struct ucred *cred;
struct ucred *active_cred;
struct thread *td;
int flags;
{
@ -75,10 +75,10 @@ soo_read(fp, uio, cred, flags, td)
/* ARGSUSED */
int
soo_write(fp, uio, cred, flags, td)
soo_write(fp, uio, active_cred, flags, td)
struct file *fp;
struct uio *uio;
struct ucred *cred;
struct ucred *active_cred;
struct thread *td;
int flags;
{

View File

@ -1849,10 +1849,15 @@ do_sendfile(struct thread *td, struct sendfile_args *uap, int compat)
*/
bsize = vp->v_mount->mnt_stat.f_iosize;
vn_lock(vp, LK_SHARED | LK_NOPAUSE | LK_RETRY, td);
/*
* XXXMAC: Because we don't have fp->f_cred here,
* we pass in NOCRED. This is probably wrong, but
* is consistent with our original implementation.
*/
error = vn_rdwr(UIO_READ, vp, NULL, MAXBSIZE,
trunc_page(off), UIO_NOCOPY, IO_NODELOCKED |
IO_VMIO | ((MAXBSIZE / bsize) << 16),
td->td_ucred, &resid, td);
td->td_ucred, NOCRED, &resid, td);
VOP_UNLOCK(vp, 0, td);
vm_page_lock_queues();
vm_page_flag_clear(pg, PG_ZERO);

View File

@ -67,13 +67,13 @@ static int vn_closefile(struct file *fp, struct thread *td);
static int vn_ioctl(struct file *fp, u_long com, void *data,
struct thread *td);
static int vn_read(struct file *fp, struct uio *uio,
struct ucred *cred, int flags, struct thread *td);
struct ucred *active_cred, int flags, struct thread *td);
static int vn_poll(struct file *fp, int events, struct ucred *cred,
struct thread *td);
static int vn_kqfilter(struct file *fp, struct knote *kn);
static int vn_statfile(struct file *fp, struct stat *sb, struct thread *td);
static int vn_write(struct file *fp, struct uio *uio,
struct ucred *cred, int flags, struct thread *td);
struct ucred *active_cred, int flags, struct thread *td);
struct fileops vnops = {
vn_read, vn_write, vn_ioctl, vn_poll, vn_kqfilter,
@ -355,7 +355,8 @@ sequential_heuristic(struct uio *uio, struct file *fp)
* Package up an I/O request on a vnode into a uio and do it.
*/
int
vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, td)
vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, active_cred, file_cred,
aresid, td)
enum uio_rw rw;
struct vnode *vp;
caddr_t base;
@ -363,13 +364,15 @@ vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, td)
off_t offset;
enum uio_seg segflg;
int ioflg;
struct ucred *cred;
struct ucred *active_cred;
struct ucred *file_cred;
int *aresid;
struct thread *td;
{
struct uio auio;
struct iovec aiov;
struct mount *mp;
struct ucred *cred;
int error;
if ((ioflg & IO_NODELOCKED) == 0) {
@ -398,14 +401,18 @@ vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, td)
#ifdef MAC
if ((ioflg & IO_NOMACCHECK) == 0) {
if (rw == UIO_READ)
error = mac_check_vnode_op(cred, vp,
error = mac_check_vnode_op(active_cred, vp,
MAC_OP_VNODE_READ);
else
error = mac_check_vnode_op(cred, vp,
error = mac_check_vnode_op(active_cred, vp,
MAC_OP_VNODE_WRITE);
}
#endif
if (error == 0) {
if (file_cred)
cred = file_cred;
else
cred = active_cred;
if (rw == UIO_READ)
error = VOP_READ(vp, &auio, ioflg, cred);
else
@ -433,7 +440,8 @@ vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, td)
* core'ing the same binary, or unrelated processes scanning the directory).
*/
int
vn_rdwr_inchunks(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, td)
vn_rdwr_inchunks(rw, vp, base, len, offset, segflg, ioflg, active_cred,
file_cred, aresid, td)
enum uio_rw rw;
struct vnode *vp;
caddr_t base;
@ -441,7 +449,8 @@ vn_rdwr_inchunks(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, td)
off_t offset;
enum uio_seg segflg;
int ioflg;
struct ucred *cred;
struct ucred *active_cred;
struct ucred *file_cred;
int *aresid;
struct thread *td;
{
@ -453,7 +462,7 @@ vn_rdwr_inchunks(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, td)
if (rw != UIO_READ && vp->v_type == VREG)
bwillwrite();
error = vn_rdwr(rw, vp, base, chunk, offset, segflg,
ioflg, cred, aresid, td);
ioflg, active_cred, file_cred, aresid, td);
len -= chunk; /* aresid calc already includes length */
if (error)
break;
@ -470,10 +479,10 @@ vn_rdwr_inchunks(rw, vp, base, len, offset, segflg, ioflg, cred, aresid, td)
* File table vnode read routine.
*/
static int
vn_read(fp, uio, cred, flags, td)
vn_read(fp, uio, active_cred, flags, td)
struct file *fp;
struct uio *uio;
struct ucred *cred;
struct ucred *active_cred;
struct thread *td;
int flags;
{
@ -489,7 +498,7 @@ vn_read(fp, uio, cred, flags, td)
ioflag |= IO_NDELAY;
if (fp->f_flag & O_DIRECT)
ioflag |= IO_DIRECT;
VOP_LEASE(vp, td, cred, LEASE_READ);
VOP_LEASE(vp, td, fp->f_cred, LEASE_READ);
vn_lock(vp, LK_SHARED | LK_NOPAUSE | LK_RETRY, td);
if ((flags & FOF_OFFSET) == 0)
uio->uio_offset = fp->f_offset;
@ -497,10 +506,10 @@ vn_read(fp, uio, cred, flags, td)
ioflag |= sequential_heuristic(uio, fp);
#ifdef MAC
error = mac_check_vnode_op(cred, vp, MAC_OP_VNODE_READ);
error = mac_check_vnode_op(active_cred, vp, MAC_OP_VNODE_READ);
if (error == 0)
#endif
error = VOP_READ(vp, uio, ioflag, cred);
error = VOP_READ(vp, uio, ioflag, fp->f_cred);
if ((flags & FOF_OFFSET) == 0)
fp->f_offset = uio->uio_offset;
fp->f_nextoff = uio->uio_offset;
@ -513,10 +522,10 @@ vn_read(fp, uio, cred, flags, td)
* File table vnode write routine.
*/
static int
vn_write(fp, uio, cred, flags, td)
vn_write(fp, uio, active_cred, flags, td)
struct file *fp;
struct uio *uio;
struct ucred *cred;
struct ucred *active_cred;
struct thread *td;
int flags;
{
@ -546,16 +555,16 @@ vn_write(fp, uio, cred, flags, td)
mtx_unlock(&Giant);
return (error);
}
VOP_LEASE(vp, td, cred, LEASE_WRITE);
VOP_LEASE(vp, td, fp->f_cred, LEASE_WRITE);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
if ((flags & FOF_OFFSET) == 0)
uio->uio_offset = fp->f_offset;
ioflag |= sequential_heuristic(uio, fp);
#ifdef MAC
error = mac_check_vnode_op(cred, vp, MAC_OP_VNODE_WRITE);
error = mac_check_vnode_op(active_cred, vp, MAC_OP_VNODE_WRITE);
if (error == 0)
#endif
error = VOP_WRITE(vp, uio, ioflag, cred);
error = VOP_WRITE(vp, uio, ioflag, fp->f_cred);
if ((flags & FOF_OFFSET) == 0)
fp->f_offset = uio->uio_offset;
fp->f_nextoff = uio->uio_offset;

View File

@ -168,7 +168,7 @@ nfs_dolock(struct vop_advlock_args *ap)
VOP_LEASE(wvp, td, thread0.td_ucred, LEASE_WRITE);
error = vn_rdwr(UIO_WRITE, wvp, (caddr_t)&msg, sizeof(msg), 0,
UIO_SYSSPACE, ioflg, thread0.td_ucred, NULL, td);
UIO_SYSSPACE, ioflg, thread0.td_ucred, NOCRED, NULL, td);
if (error && (((ioflg & IO_NDELAY) == 0) || error != EAGAIN)) {
break;

View File

@ -240,7 +240,7 @@ cpu_coredump(td, vp, cred)
{
return (vn_rdwr(UIO_WRITE, vp, (caddr_t)td->td_proc->p_uarea,
ctob(UAREA_PAGES), (off_t)0, UIO_SYSSPACE, IO_UNIT, cred,
ctob(UAREA_PAGES), (off_t)0, UIO_SYSSPACE, IO_UNIT, cred, NOCRED,
(int *)NULL, td));
}

View File

@ -240,7 +240,7 @@ cpu_coredump(td, vp, cred)
{
return (vn_rdwr(UIO_WRITE, vp, (caddr_t)td->td_proc->p_uarea,
ctob(UAREA_PAGES), (off_t)0, UIO_SYSSPACE, IO_UNIT, cred,
ctob(UAREA_PAGES), (off_t)0, UIO_SYSSPACE, IO_UNIT, cred, NOCRED,
(int *)NULL, td));
}

View File

@ -81,9 +81,11 @@ struct file {
struct ucred *f_cred; /* credentials associated with descriptor */
struct fileops {
int (*fo_read)(struct file *fp, struct uio *uio,
struct ucred *cred, int flags, struct thread *td);
struct ucred *active_cred, int flags,
struct thread *td);
int (*fo_write)(struct file *fp, struct uio *uio,
struct ucred *cred, int flags, struct thread *td);
struct ucred *active_cred, int flags,
struct thread *td);
#define FOF_OFFSET 1
int (*fo_ioctl)(struct file *fp, u_long com, void *data,
struct thread *td);
@ -174,9 +176,9 @@ void fputsock(struct socket *sp);
} while (0)
static __inline int fo_read(struct file *fp, struct uio *uio,
struct ucred *cred, int flags, struct thread *td);
struct ucred *active_cred, int flags, struct thread *td);
static __inline int fo_write(struct file *fp, struct uio *uio,
struct ucred *cred, int flags, struct thread *td);
struct ucred *active_cred, int flags, struct thread *td);
static __inline int fo_ioctl(struct file *fp, u_long com, void *data,
struct thread *td);
static __inline int fo_poll(struct file *fp, int events,
@ -188,27 +190,27 @@ static __inline int fo_kqfilter(struct file *fp, struct knote *kn);
struct proc;
static __inline int
fo_read(fp, uio, cred, flags, td)
fo_read(fp, uio, active_cred, flags, td)
struct file *fp;
struct uio *uio;
struct ucred *cred;
struct ucred *active_cred;
struct thread *td;
int flags;
{
return ((*fp->f_ops->fo_read)(fp, uio, cred, flags, td));
return ((*fp->f_ops->fo_read)(fp, uio, active_cred, flags, td));
}
static __inline int
fo_write(fp, uio, cred, flags, td)
fo_write(fp, uio, active_cred, flags, td)
struct file *fp;
struct uio *uio;
struct ucred *cred;
struct ucred *active_cred;
struct thread *td;
int flags;
{
return ((*fp->f_ops->fo_write)(fp, uio, cred, flags, td));
return ((*fp->f_ops->fo_write)(fp, uio, active_cred, flags, td));
}
static __inline int

View File

@ -345,10 +345,10 @@ struct uio;
/*
* File operations on sockets.
*/
int soo_read(struct file *fp, struct uio *uio, struct ucred *cred,
int flags, struct thread *td);
int soo_write(struct file *fp, struct uio *uio, struct ucred *cred,
int soo_read(struct file *fp, struct uio *uio, struct ucred *active_cred,
int flags, struct thread *td);
int soo_write(struct file *fp, struct uio *uio,
struct ucred *active_cred, int flags, struct thread *td);
int soo_close(struct file *fp, struct thread *td);
int soo_ioctl(struct file *fp, u_long cmd, void *data,
struct thread *td);

View File

@ -719,10 +719,12 @@ void vn_pollgone(struct vnode *vp);
int vn_pollrecord(struct vnode *vp, struct thread *p, int events);
int vn_rdwr(enum uio_rw rw, struct vnode *vp, caddr_t base,
int len, off_t offset, enum uio_seg segflg, int ioflg,
struct ucred *cred, int *aresid, struct thread *td);
struct ucred *active_cred, struct ucred *file_cred, int *aresid,
struct thread *td);
int vn_rdwr_inchunks(enum uio_rw rw, struct vnode *vp, caddr_t base,
int len, off_t offset, enum uio_seg segflg, int ioflg,
struct ucred *cred, int *aresid, struct thread *td);
struct ucred *active_cred, struct ucred *file_cred, int *aresid,
struct thread *td);
int vn_stat(struct vnode *vp, struct stat *sb, struct thread *td);
int vn_start_write(struct vnode *vp, struct mount **mpp, int flags);
dev_t vn_todev(struct vnode *vp);

View File

@ -1153,7 +1153,7 @@ ufs_dirempty(ip, parentino, cred)
for (off = 0; off < ip->i_size; off += dp->d_reclen) {
error = vn_rdwr(UIO_READ, ITOV(ip), (caddr_t)dp, MINDIRSIZ,
off, UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK, cred,
&count, (struct thread *)0);
NOCRED, &count, (struct thread *)0);
/*
* Since we read MINDIRSIZ, residual must
* be 0 unless we're at end of file.
@ -1225,7 +1225,7 @@ ufs_checkpath(source, target, cred)
}
error = vn_rdwr(UIO_READ, vp, (caddr_t)&dirbuf,
sizeof (struct dirtemplate), (off_t)0, UIO_SYSSPACE,
IO_NODELOCKED | IO_NOMACCHECK, cred, (int *)0,
IO_NODELOCKED | IO_NOMACCHECK, cred, NOCRED, (int *)0,
(struct thread *)0);
if (error != 0)
break;

View File

@ -1822,7 +1822,7 @@ ufs_symlink(ap)
} else
error = vn_rdwr(UIO_WRITE, vp, ap->a_target, len, (off_t)0,
UIO_SYSSPACE, IO_NODELOCKED | IO_NOMACCHECK,
ap->a_cnp->cn_cred, (int *)0, (struct thread *)0);
ap->a_cnp->cn_cred, NOCRED, (int *)0, (struct thread *)0);
if (error)
vput(vp);
return (error);