CHERI: add sooptcopyinptr to preserve pointer provenance

Most socket options don't involve pointers so make the default
sooptcopyin discard provenance and add a sooptcopyinptr that preserves.

Reviewed by:	markj, emaste
Effort:		CHERI upstreaming
Sponsored by:	DARPA, AFRL, Innovate UK
Differential Revision:	https://reviews.freebsd.org/D57665
This commit is contained in:
Brooks Davis committed 2026-07-01 12:48:10 +01:00
1 parent 7f55dbe6ae
commit f14bdfefa4
3 files changed
+46 -7

No files matched your search

+12 -1
View File
@@ -24,7 +24,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd September 6, 2022
.Dd July 1, 2026
.Dt SOCKET 9
.Os
.Sh NAME
@@ -146,6 +146,8 @@
.Ft int
.Fn sooptcopyin "struct sockopt *sopt" "void *buf" "size_t len" "size_t minlen"
.Ft int
.Fn sooptcopyinptr "struct sockopt *sopt" "void *buf" "size_t len" "size_t minlen"
.Ft int
.Fn sooptcopyout "struct sockopt *sopt" "const void *buf" "size_t len"
.Sh DESCRIPTION
The kernel
@@ -577,6 +579,15 @@ and
are useful for transferring
.Vt struct sockopt
data between user and kernel code.
They do not preserve the provenance of pointers in copied objects
.Pq see Xr memory_model 7 for further information .
If the object to be copied contains pointers, the
.Fn sooptcopyinptr
function must be used to preserve the provenance of those pointers.
There is no corresponding
.Fn sooptcopyoutptr
as the kernel does not typically return pointers to userspace objects
and instead would update objects previously passed via sooptcopyinptr.
.Sh SEE ALSO
.Xr bind 2 ,
.Xr close 2 ,
+28 -6
View File
@@ -3808,8 +3808,9 @@ hhook_run_socket(struct socket *so, void *hctx, int32_t h_id)
* here, these functions are also called by the protocol-level pr_ctloutput()
* routines.
*/
int
sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen)
static int
_sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen,
bool copycaps)
{
size_t valsize;
@@ -3824,13 +3825,34 @@ sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen)
if (valsize > len)
sopt->sopt_valsize = valsize = len;
if (sopt->sopt_td != NULL)
return (copyin(sopt->sopt_val, buf, valsize));
if (sopt->sopt_td != NULL) {
if (copycaps)
return (copyinptr(sopt->sopt_val, buf, valsize));
else
return (copyin(sopt->sopt_val, buf, valsize));
}
memcpy(buf, sopt->sopt_val, valsize);
if (copycaps)
memcpy(buf, sopt->sopt_val, valsize);
else
memcpy_data(buf, sopt->sopt_val, valsize);
return (0);
}
int
sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen)
{
return (_sooptcopyin(sopt, buf, len, minlen, false));
}
#ifdef __CHERI__
int
sooptcopyinptr(struct sockopt *sopt, void *buf, size_t len, size_t minlen)
{
return (_sooptcopyin(sopt, buf, len, minlen, true));
}
#endif
/*
* Kernel version of setsockopt(2).
*
@@ -4118,7 +4140,7 @@ sooptcopyout(struct sockopt *sopt, const void *buf, size_t len)
if (sopt->sopt_td != NULL)
error = copyout(buf, sopt->sopt_val, valsize);
else
memcpy(sopt->sopt_val, buf, valsize);
memcpy_data(sopt->sopt_val, buf, valsize);
}
return (error);
}
+6
View File
@@ -59,6 +59,12 @@ int sosetopt(struct socket *so, struct sockopt *sopt);
int sogetopt(struct socket *so, struct sockopt *sopt);
int __result_use_check sooptcopyin(struct sockopt *sopt, void *buf, size_t len,
size_t minlen);
#ifdef __CHERI__
int __result_use_check sooptcopyinptr(struct sockopt *sopt, void *buf,
size_t len, size_t minlen);
#else
#define sooptcopyinptr sooptcopyin
#endif
int __result_use_check sooptcopyout(struct sockopt *sopt, const void *buf,
size_t len);
int soopt_getm(struct sockopt *sopt, struct mbuf **mp);