diff options
Diffstat (limited to 'sys/compat/freebsd32/freebsd32_misc.c')
-rw-r--r-- | sys/compat/freebsd32/freebsd32_misc.c | 26 |
1 files changed, 16 insertions, 10 deletions
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 4899e03..51175aa 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/bus.h> +#include <sys/capability.h> #include <sys/clock.h> #include <sys/exec.h> #include <sys/fcntl.h> @@ -1653,22 +1654,19 @@ static int freebsd32_do_sendfile(struct thread *td, struct freebsd32_sendfile_args *uap, int compat) { - struct sendfile_args ap; struct sf_hdtr32 hdtr32; struct sf_hdtr hdtr; struct uio *hdr_uio, *trl_uio; struct iovec32 *iov32; + struct file *fp; + off_t offset; int error; - hdr_uio = trl_uio = NULL; + offset = PAIR32TO64(off_t, uap->offset); + if (offset < 0) + return (EINVAL); - ap.fd = uap->fd; - ap.s = uap->s; - ap.offset = PAIR32TO64(off_t,uap->offset); - ap.nbytes = uap->nbytes; - ap.hdtr = (struct sf_hdtr *)uap->hdtr; /* XXX not used */ - ap.sbytes = uap->sbytes; - ap.flags = uap->flags; + hdr_uio = trl_uio = NULL; if (uap->hdtr != NULL) { error = copyin(uap->hdtr, &hdtr32, sizeof(hdtr32)); @@ -1695,7 +1693,15 @@ freebsd32_do_sendfile(struct thread *td, } } - error = kern_sendfile(td, &ap, hdr_uio, trl_uio, compat); + AUDIT_ARG_FD(uap->fd); + + if ((error = fget_read(td, uap->fd, CAP_PREAD, &fp)) != 0) + goto out; + + error = fo_sendfile(fp, uap->s, hdr_uio, trl_uio, offset, + uap->nbytes, uap->sbytes, uap->flags, compat ? SFK_COMPAT : 0, td); + fdrop(fp, td); + out: if (hdr_uio) free(hdr_uio, M_IOV); |