sys/uio: add updateiov()

This function take a struct uio previously created by copyinuio and and
updates the lengths of the user-space iovec to match those in the uio.

To reduce the risks of pointer leakage and cross-ABI pointer confusion,
lengths are updated individually.

Reviewed by:	jamie, jhb
Effort:		CHERI upstreaming
Sponsored by:	DARPA, AFRL, Innovate UK
Differential Revision:	https://reviews.freebsd.org/D60025
This commit is contained in:
Brooks Davis committed 2026-09-29 19:14:06 +01:00
1 parent 52b2056849
commit afe41f1ab9
3 files changed
+26

No files matched your search

+18
View File
@@ -468,6 +468,24 @@ copyinuio(const void *iovp, u_int iovcnt, struct uio **uiop)
return (0);
}
/*
* Update the lengths of a userspace iovec to match those in a struct uio's
* iovec (previously created by copyinuio).
*/
int
updateiov(const struct uio *uiop, void *uiovp)
{
int i, error;
struct iovec *iovp = uiovp;
for (i = 0; i < uiop->uio_iovcnt; i++) {
error = suword(&iovp[i].iov_len, uiop->uio_iov[i].iov_len);
if (error != 0)
return (EFAULT);
}
return (0);
}
struct uio *
allocuio(u_int iovcnt)
{
+7
View File
@@ -96,6 +96,13 @@ typedef int (copyin_hdtr_t)(const void *hdtrp, struct sf_hdtr *hdtr);
typedef int (copyinuio_t)(const void *iovp, unsigned int iovcnt,
struct uio **iov);
/*
* A updateiov_t takes a pointer to a struct uio previously created with
* copyinuio_t and a pointer to the corresponding iovec in userspace.
* It updates all lengths in userspace to match those in the uio.
*/
typedef int(updateiov_t)(const struct uio *uiop, void *iovp);
uint64_t at2cnpflags(u_int at_flags, u_int mask);
int kern___getcwd(struct thread *td, char *buf, enum uio_seg bufseg,
size_t buflen, size_t path_max);
+1
View File
@@ -99,6 +99,7 @@ int uiomove_fromphys(struct vm_page *ma[], vm_offset_t offset, int n,
int uiomove_nofault(void *cp, int n, struct uio *uio);
int uiomove_object(struct vm_object *obj, off_t obj_size, struct uio *uio);
int uiomove_step(void *cp, void *base, size_t cnt, struct uio *uio);
int updateiov(const struct uio *uiop, void *iovp);
#else /* !_KERNEL */