aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/linux32/linux32_machdep.c2
-rw-r--r--sys/cddl/compat/opensolaris/kern/opensolaris_uio.c2
-rw-r--r--sys/compat/freebsd32/freebsd32_misc.c29
-rw-r--r--sys/compat/linux/linux_file.c6
-rw-r--r--sys/kern/kern_jail.c6
-rw-r--r--sys/kern/kern_ktrace.c4
-rw-r--r--sys/kern/kern_sendfile.c4
-rw-r--r--sys/kern/subr_prf.c2
-rw-r--r--sys/kern/subr_uio.c38
-rw-r--r--sys/kern/sys_generic.c8
-rw-r--r--sys/kern/vfs_aio.c4
-rw-r--r--sys/kern/vfs_mount.c2
-rw-r--r--sys/kern/vfs_vnops.c2
-rw-r--r--sys/sys/uio.h2
14 files changed, 66 insertions, 45 deletions
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
index ba4dcc61af76..7f1c85cee201 100644
--- a/sys/amd64/linux32/linux32_machdep.c
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -106,7 +106,7 @@ linux_readv(struct thread *td, struct linux_readv_args *uap)
if (error)
return (error);
error = kern_readv(td, uap->fd, auio);
- free(auio, M_IOV);
+ freeuio(auio);
return (error);
}
diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_uio.c b/sys/cddl/compat/opensolaris/kern/opensolaris_uio.c
index e1cc8f802762..b2a08a55bba4 100644
--- a/sys/cddl/compat/opensolaris/kern/opensolaris_uio.c
+++ b/sys/cddl/compat/opensolaris/kern/opensolaris_uio.c
@@ -68,7 +68,7 @@ uiocopy(void *p, size_t n, enum uio_rw rw, struct uio *uio, size_t *cbytes)
error = vn_io_fault_uiomove(p, n, uio_clone);
*cbytes = uio->uio_resid - uio_clone->uio_resid;
if (uio_clone != &small_uio_clone)
- free(uio_clone, M_IOV);
+ freeuio(uio_clone);
return (error);
}
diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index f2d66cf74b2b..facbf00a4c51 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -1196,32 +1196,29 @@ freebsd32_copyinuio(struct iovec32 *iovp, u_int iovcnt, struct uio **uiop)
struct iovec32 iov32;
struct iovec *iov;
struct uio *uio;
- u_int iovlen;
int error, i;
*uiop = NULL;
if (iovcnt > UIO_MAXIOV)
return (EINVAL);
- iovlen = iovcnt * sizeof(struct iovec);
- uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK);
- iov = (struct iovec *)(uio + 1);
+ uio = allocuio(iovcnt);
+ iov = uio->uio_iov;
for (i = 0; i < iovcnt; i++) {
error = copyin(&iovp[i], &iov32, sizeof(struct iovec32));
if (error) {
- free(uio, M_IOV);
+ freeuio(uio);
return (error);
}
iov[i].iov_base = PTRIN(iov32.iov_base);
iov[i].iov_len = iov32.iov_len;
}
- uio->uio_iov = iov;
uio->uio_iovcnt = iovcnt;
uio->uio_segflg = UIO_USERSPACE;
uio->uio_offset = -1;
uio->uio_resid = 0;
for (i = 0; i < iovcnt; i++) {
if (iov->iov_len > INT_MAX - uio->uio_resid) {
- free(uio, M_IOV);
+ freeuio(uio);
return (EINVAL);
}
uio->uio_resid += iov->iov_len;
@@ -1241,7 +1238,7 @@ freebsd32_readv(struct thread *td, struct freebsd32_readv_args *uap)
if (error)
return (error);
error = kern_readv(td, uap->fd, auio);
- free(auio, M_IOV);
+ freeuio(auio);
return (error);
}
@@ -1255,7 +1252,7 @@ freebsd32_writev(struct thread *td, struct freebsd32_writev_args *uap)
if (error)
return (error);
error = kern_writev(td, uap->fd, auio);
- free(auio, M_IOV);
+ freeuio(auio);
return (error);
}
@@ -1269,7 +1266,7 @@ freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
if (error)
return (error);
error = kern_preadv(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
- free(auio, M_IOV);
+ freeuio(auio);
return (error);
}
@@ -1283,7 +1280,7 @@ freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
if (error)
return (error);
error = kern_pwritev(td, uap->fd, auio, PAIR32TO64(off_t,uap->offset));
- free(auio, M_IOV);
+ freeuio(auio);
return (error);
}
@@ -2199,9 +2196,9 @@ freebsd32_do_sendfile(struct thread *td,
out:
if (hdr_uio)
- free(hdr_uio, M_IOV);
+ freeuio(hdr_uio);
if (trl_uio)
- free(trl_uio, M_IOV);
+ freeuio(trl_uio);
return (error);
}
@@ -2780,7 +2777,7 @@ freebsd32_jail_set(struct thread *td, struct freebsd32_jail_set_args *uap)
if (error)
return (error);
error = kern_jail_set(td, auio, uap->flags);
- free(auio, M_IOV);
+ freeuio(auio);
return (error);
}
@@ -2807,7 +2804,7 @@ freebsd32_jail_get(struct thread *td, struct freebsd32_jail_get_args *uap)
if (error != 0)
break;
}
- free(auio, M_IOV);
+ freeuio(auio);
return (error);
}
@@ -3540,7 +3537,7 @@ freebsd32_nmount(struct thread *td,
return (error);
error = vfs_donmount(td, flags, auio);
- free(auio, M_IOV);
+ freeuio(auio);
return error;
}
diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c
index 6eab8980a5c5..1279490ae8be 100644
--- a/sys/compat/linux/linux_file.c
+++ b/sys/compat/linux/linux_file.c
@@ -1038,7 +1038,7 @@ linux_preadv(struct thread *td, struct linux_preadv_args *uap)
if (error != 0)
return (error);
error = kern_preadv(td, uap->fd, auio, offset);
- free(auio, M_IOV);
+ freeuio(auio);
return (error);
}
@@ -1065,7 +1065,7 @@ linux_pwritev(struct thread *td, struct linux_pwritev_args *uap)
if (error != 0)
return (error);
error = kern_pwritev(td, uap->fd, auio, offset);
- free(auio, M_IOV);
+ freeuio(auio);
return (linux_enobufs2eagain(td, uap->fd, error));
}
@@ -1872,6 +1872,6 @@ linux_writev(struct thread *td, struct linux_writev_args *args)
if (error != 0)
return (error);
error = kern_writev(td, args->fd, auio);
- free(auio, M_IOV);
+ freeuio(auio);
return (linux_enobufs2eagain(td, args->fd, error));
}
diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index fb674b991a73..90a043394792 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -537,7 +537,7 @@ sys_jail_set(struct thread *td, struct jail_set_args *uap)
if (error)
return (error);
error = kern_jail_set(td, auio, uap->flags);
- free(auio, M_IOV);
+ freeuio(auio);
return (error);
}
@@ -2296,8 +2296,8 @@ sys_jail_get(struct thread *td, struct jail_get_args *uap)
error = kern_jail_get(td, auio, uap->flags);
if (error == 0)
error = copyout(auio->uio_iov, uap->iovp,
- uap->iovcnt * sizeof (struct iovec));
- free(auio, M_IOV);
+ uap->iovcnt * sizeof(struct iovec));
+ freeuio(auio);
return (error);
}
diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c
index eb14d60433dd..877a25ffa4cd 100644
--- a/sys/kern/kern_ktrace.c
+++ b/sys/kern/kern_ktrace.c
@@ -768,7 +768,7 @@ ktrgenio(int fd, enum uio_rw rw, struct uio *uio, int error)
char *buf;
if (error) {
- free(uio, M_IOV);
+ freeuio(uio);
return;
}
uio->uio_offset = 0;
@@ -776,7 +776,7 @@ ktrgenio(int fd, enum uio_rw rw, struct uio *uio, int error)
datalen = MIN(uio->uio_resid, ktr_geniosize);
buf = malloc(datalen, M_KTRACE, M_WAITOK);
error = uiomove(buf, datalen, uio);
- free(uio, M_IOV);
+ freeuio(uio);
if (error) {
free(buf, M_KTRACE);
return;
diff --git a/sys/kern/kern_sendfile.c b/sys/kern/kern_sendfile.c
index f6f6b57adfc7..323e7fcde07b 100644
--- a/sys/kern/kern_sendfile.c
+++ b/sys/kern/kern_sendfile.c
@@ -1331,8 +1331,8 @@ sendfile(struct thread *td, struct sendfile_args *uap, int compat)
(void)copyout(&sbytes, uap->sbytes, sizeof(off_t));
out:
- free(hdr_uio, M_IOV);
- free(trl_uio, M_IOV);
+ freeuio(hdr_uio);
+ freeuio(trl_uio);
return (error);
}
diff --git a/sys/kern/subr_prf.c b/sys/kern/subr_prf.c
index 57ca158c6315..e291a1fa00a6 100644
--- a/sys/kern/subr_prf.c
+++ b/sys/kern/subr_prf.c
@@ -386,7 +386,7 @@ log_console(struct uio *uio)
msglogstr(consbuffer, pri, /*filter_cr*/ 1);
}
msgbuftrigger = 1;
- free(uio, M_IOV);
+ freeuio(uio);
free(consbuffer, M_TEMP);
}
diff --git a/sys/kern/subr_uio.c b/sys/kern/subr_uio.c
index e7c7de406d47..cbc4b0c0ed8e 100644
--- a/sys/kern/subr_uio.c
+++ b/sys/kern/subr_uio.c
@@ -373,21 +373,20 @@ copyinuio(const struct iovec *iovp, u_int iovcnt, struct uio **uiop)
if (iovcnt > UIO_MAXIOV)
return (EINVAL);
iovlen = iovcnt * sizeof(struct iovec);
- uio = malloc(iovlen + sizeof(*uio), M_IOV, M_WAITOK);
- iov = (struct iovec *)(uio + 1);
+ uio = allocuio(iovcnt);
+ iov = uio->uio_iov;
error = copyin(iovp, iov, iovlen);
- if (error) {
- free(uio, M_IOV);
+ if (error != 0) {
+ freeuio(uio);
return (error);
}
- uio->uio_iov = iov;
uio->uio_iovcnt = iovcnt;
uio->uio_segflg = UIO_USERSPACE;
uio->uio_offset = -1;
uio->uio_resid = 0;
for (i = 0; i < iovcnt; i++) {
if (iov->iov_len > IOSIZE_MAX - uio->uio_resid) {
- free(uio, M_IOV);
+ freeuio(uio);
return (EINVAL);
}
uio->uio_resid += iov->iov_len;
@@ -398,15 +397,38 @@ copyinuio(const struct iovec *iovp, u_int iovcnt, struct uio **uiop)
}
struct uio *
+allocuio(u_int iovcnt)
+{
+ struct uio *uio;
+ int iovlen;
+
+ KASSERT(iovcnt <= UIO_MAXIOV,
+ ("Requested %u iovecs exceed UIO_MAXIOV", iovcnt));
+ iovlen = iovcnt * sizeof(struct iovec);
+ uio = malloc(iovlen + sizeof(*uio), M_IOV, M_WAITOK);
+ uio->uio_iov = (struct iovec *)(uio + 1);
+
+ return (uio);
+}
+
+void
+freeuio(struct uio *uio)
+{
+ free(uio, M_IOV);
+}
+
+struct uio *
cloneuio(struct uio *uiop)
{
+ struct iovec *iov;
struct uio *uio;
int iovlen;
iovlen = uiop->uio_iovcnt * sizeof(struct iovec);
- uio = malloc(iovlen + sizeof(*uio), M_IOV, M_WAITOK);
+ uio = allocuio(uiop->uio_iovcnt);
+ iov = uio->uio_iov;
*uio = *uiop;
- uio->uio_iov = (struct iovec *)(uio + 1);
+ uio->uio_iov = iov;
bcopy(uiop->uio_iov, uio->uio_iov, iovlen);
return (uio);
}
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index e185900b93be..9c0cb4e739e0 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -271,7 +271,7 @@ sys_readv(struct thread *td, struct readv_args *uap)
if (error)
return (error);
error = kern_readv(td, uap->fd, auio);
- free(auio, M_IOV);
+ freeuio(auio);
return (error);
}
@@ -310,7 +310,7 @@ sys_preadv(struct thread *td, struct preadv_args *uap)
if (error)
return (error);
error = kern_preadv(td, uap->fd, auio, uap->offset);
- free(auio, M_IOV);
+ freeuio(auio);
return (error);
}
@@ -473,7 +473,7 @@ sys_writev(struct thread *td, struct writev_args *uap)
if (error)
return (error);
error = kern_writev(td, uap->fd, auio);
- free(auio, M_IOV);
+ freeuio(auio);
return (error);
}
@@ -512,7 +512,7 @@ sys_pwritev(struct thread *td, struct pwritev_args *uap)
if (error)
return (error);
error = kern_pwritev(td, uap->fd, auio, uap->offset);
- free(auio, M_IOV);
+ freeuio(auio);
return (error);
}
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
index 13f99a71ef04..1195d92d54ab 100644
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -555,7 +555,7 @@ aio_free_entry(struct kaiocb *job)
fdrop(job->fd_file, curthread);
crfree(job->cred);
if (job->uiop != &job->uio)
- free(job->uiop, M_IOV);
+ freeuio(job->uiop);
uma_zfree(aiocb_zone, job);
AIO_LOCK(ki);
@@ -1728,7 +1728,7 @@ err3:
knlist_delete(&job->klist, curthread, 0);
err2:
if (job->uiop != &job->uio)
- free(job->uiop, M_IOV);
+ freeuio(job->uiop);
uma_zfree(aiocb_zone, job);
err1:
ops->store_error(ujob, error);
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 347ec7f70aaf..2b235d398332 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -473,7 +473,7 @@ sys_nmount(struct thread *td, struct nmount_args *uap)
}
error = vfs_donmount(td, flags, auio);
- free(auio, M_IOV);
+ freeuio(auio);
return (error);
}
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index dc2efee038bb..77e4dd21f276 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -1442,7 +1442,7 @@ vn_io_fault1(struct vnode *vp, struct uio *uio, struct vn_io_fault_args *args,
td->td_ma_cnt = prev_td_ma_cnt;
curthread_pflags_restore(saveheld);
out:
- free(uio_clone, M_IOV);
+ freeuio(uio_clone);
return (error);
}
diff --git a/sys/sys/uio.h b/sys/sys/uio.h
index e7bb74c908d8..42ab0cda8e38 100644
--- a/sys/sys/uio.h
+++ b/sys/sys/uio.h
@@ -76,6 +76,8 @@ struct vm_object;
struct vm_page;
struct bus_dma_segment;
+struct uio *allocuio(u_int iovcnt);
+void freeuio(struct uio *uio);
struct uio *cloneuio(struct uio *uiop);
int copyiniov(const struct iovec *iovp, u_int iovcnt, struct iovec **iov,
int error);