Date: Mon, 29 Jun 2026 13:01:39 +0000
From: Brooks Davis <brooks@FreeBSD.org>
To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject: git: b517edb8deed - main - CHERI: declare copy{in,out}ptr{,_nofault}
Message-ID: <6a426cb3.21ca8.6f79461f@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by brooks: URL: https://cgit.FreeBSD.org/src/commit/?id=b517edb8deed23b8c616f0ad4453e4dee7b0ac0f commit b517edb8deed23b8c616f0ad4453e4dee7b0ac0f Author: Brooks Davis <brooks@FreeBSD.org> AuthorDate: 2026-06-29 12:58:52 +0000 Commit: Brooks Davis <brooks@FreeBSD.org> CommitDate: 2026-06-29 12:59:29 +0000 CHERI: declare copy{in,out}ptr{,_nofault} These provenance-preserving functions are to be used when copying objects that are expected to contain pointers. Data buffers which do not contain pointers should be copied by the traditional copyin/copyout functions which *do not* preserve pointer provenance (on CHERI they clear validity tags). NOTE: Going forward, this requires changes when adding new syscalls or ioctl that take pointers to objects containing pointers. Fortunately, the vast majority (>90%) of copyin and copyout statements do not copy pointers and require no change. Failure to make the chance will have no effect on non-CHERI architectures. Reviewed by: kib, markj Effort: CHERI upstreaming Sponsored by: DARPA, AFRL, Innovate UK Differential Revision: https://reviews.freebsd.org/D57663 --- share/man/man9/copy.9 | 49 ++++++++++++++++++++++++++++++++++++++++++++----- sys/kern/subr_uio.c | 24 ++++++++++++++++++++++++ sys/sys/systm.h | 18 ++++++++++++++++++ 3 files changed, 86 insertions(+), 5 deletions(-) diff --git a/share/man/man9/copy.9 b/share/man/man9/copy.9 index fe51bbd12704..a1aa75e2c84f 100644 --- a/share/man/man9/copy.9 +++ b/share/man/man9/copy.9 @@ -32,15 +32,19 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 11, 2020 +.Dd June 29, 2026 .Dt COPY 9 .Os .Sh NAME .Nm copy , .Nm copyin , .Nm copyin_nofault , +.Nm copyinptr , +.Nm copyinptr_nofault , .Nm copyout , .Nm copyout_nofault , +.Nm copyoutptr , +.Nm copyoutptr_nofault , .Nm copystr , .Nm copyinstr .Nd heterogeneous address space copy functions @@ -52,9 +56,17 @@ .Ft int .Fn copyin_nofault "const void *uaddr" "void *kaddr" "size_t len" .Ft int +.Fn copyinptr "const void *uaddr" "void *kaddr" "size_t len" +.Ft int +.Fn copyinptr_nofault "const void *uaddr" "void *kaddr" "size_t len" +.Ft int .Fn copyout "const void *kaddr" "void *uaddr" "size_t len" .Ft int .Fn copyout_nofault "const void *kaddr" "void *uaddr" "size_t len" +.Ft int +.Fn copyoutptr "const void *kaddr" "void *uaddr" "size_t len" +.Ft int +.Fn copyoutptr_nofault "const void *kaddr" "void *uaddr" "size_t len" .Ft int __deprecated .Fn copystr "const void *kfaddr" "void *kdaddr" "size_t len" "size_t *done" .Ft int @@ -81,7 +93,15 @@ functions copy bytes of data from the user-space address .Fa uaddr to the kernel-space address -.Fa kaddr . +.Fa kaddr +without preserving the provenance of pointers in the copied object +.Pq see Xr memory_model 7 for further information . +The +.Fn copyinptr +and +.Fn copyinptr_nofault +functions do the same, +but preserves the provenance of copied pointers to user-space. .Pp The .Fn copyout @@ -92,12 +112,21 @@ functions copy bytes of data from the kernel-space address .Fa kaddr to the user-space address -.Fa uaddr . +.Fa uaddr +without preserving the provenance of pointers in the copied object. +The +.Fn copyoutptr +and +.Fn copyoutptr_nofault +functions do the same, +but preserves the provenance of copied pointers to user-space. .Pp The -.Fn copyin_nofault +.Fn copyin_nofault , +.Fn copyinptr_nofault , +.Fn copyout_nofault , and -.Fn copyout_nofault +.Fn copyoutptr_nofault functions require that the kernel-space and user-space data be accessible without incurring a page fault. The source and destination addresses must be physically mapped for @@ -105,6 +134,16 @@ read and write access, respectively, and neither the source nor destination addresses may be pageable. .Pp The +.Fn copyinptr , +.Fn copyinptr_nofault , +.Fn copyoutptr , +and +.Fn copyoutptr_nofault +functions must be used when copying data which may contain pointers, +but they should only be used when necessary to limit the number of +code paths that could leak pointers between address spaces. +.Pp +The .Fn copystr function copies a NUL-terminated string, at most .Fa len diff --git a/sys/kern/subr_uio.c b/sys/kern/subr_uio.c index e2059d3813d4..ea75c6abc539 100644 --- a/sys/kern/subr_uio.c +++ b/sys/kern/subr_uio.c @@ -88,6 +88,30 @@ copyout_nofault(const void *kaddr, void *udaddr, size_t len) return (error); } +#ifdef __CHERI__ +int +copyinptr_nofault(const void *udaddr, void *kaddr, size_t len) +{ + int error, save; + + save = vm_fault_disable_pagefaults(); + error = copyinptr(udaddr, kaddr, len); + vm_fault_enable_pagefaults(save); + return (error); +} + +int +copyoutptr_nofault(const void *kaddr, void *udaddr, size_t len) +{ + int error, save; + + save = vm_fault_disable_pagefaults(); + error = copyoutptr(kaddr, udaddr, len); + vm_fault_enable_pagefaults(save); + return (error); +} +#endif + #define PHYS_PAGE_COUNT(len) (howmany(len, PAGE_SIZE) + 1) int diff --git a/sys/sys/systm.h b/sys/sys/systm.h index e50b02bfb7cf..f2c5051ac03d 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -313,6 +313,24 @@ __nodiscard int copyout_nofault( const void * _Nonnull __restrict kaddr, void * __restrict udaddr, size_t len); +#ifdef __CHERI__ +__nodiscard int copyinptr(const void * __restrict udaddr, + void * _Nonnull __restrict kaddr, size_t len); +__nodiscard int copyinptr_nofault(const void * __restrict udaddr, + void * _Nonnull __restrict kaddr, size_t len); +__nodiscard int copyoutptr( + const void * _Nonnull __restrict kaddr, void * __restrict udaddr, + size_t len); +__nodiscard int copyoutptr_nofault( + const void * _Nonnull __restrict kaddr, void * __restrict udaddr, + size_t len); +#else +#define copyinptr copyin +#define copyinptr_nofault copyin_nofault +#define copyoutptr copyout +#define copyoutptr_nofault copyout_nofault +#endif + #ifdef SAN_NEEDS_INTERCEPTORS int SAN_INTERCEPTOR(copyin)(const void *, void *, size_t); int SAN_INTERCEPTOR(copyinstr)(const void *, void *, size_t, size_t *);home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a426cb3.21ca8.6f79461f>
