Skip to content

Commit 2a34c40

Browse files
committed
sys: Replace SOPT_SET/GETCAP with sooptcopyincap
This requires smaller changes in socket option consumers avoiding the need to store the original direction after calling sooptcopyin. While here, change the in-kernel copies for sooptcopyin and sooptcopyout to clear tags via bcopynocap() instead of bcopy().
1 parent 3461b5b commit 2a34c40

File tree

3 files changed

+38
-64
lines changed

3 files changed

+38
-64
lines changed

sys/kern/uipc_socket.c

Lines changed: 29 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3017,19 +3017,32 @@ sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen)
30173017
if (valsize > len)
30183018
sopt->sopt_valsize = valsize = len;
30193019

3020-
if (sopt->sopt_td != NULL) {
3020+
if (sopt->sopt_td != NULL)
3021+
return (copyin(sopt->sopt_val, buf, valsize));
3022+
3023+
bcopynocap((__cheri_fromcap void *)sopt->sopt_val, buf, valsize);
3024+
return (0);
3025+
}
3026+
30213027
#if __has_feature(capabilities)
3022-
if (sopt->sopt_dir == SOPT_SETCAP ||
3023-
sopt->sopt_dir == SOPT_GETCAP)
3024-
return (copyincap(sopt->sopt_val, buf, valsize));
3025-
else
3026-
#endif
3027-
return (copyin(sopt->sopt_val, buf, valsize));
3028-
}
3028+
/* Version of sooptcopyin that preserves tags. */
3029+
int
3030+
sooptcopyincap(struct sockopt *sopt, void *buf, size_t len, size_t minlen)
3031+
{
3032+
size_t valsize;
3033+
3034+
if ((valsize = sopt->sopt_valsize) < minlen)
3035+
return EINVAL;
3036+
if (valsize > len)
3037+
sopt->sopt_valsize = valsize = len;
3038+
3039+
if (sopt->sopt_td != NULL)
3040+
return (copyincap(sopt->sopt_val, buf, valsize));
30293041

30303042
bcopy((__cheri_fromcap void *)sopt->sopt_val, buf, valsize);
30313043
return (0);
30323044
}
3045+
#endif
30333046

30343047
/*
30353048
* Kernel version of setsockopt(2).
@@ -3211,16 +3224,8 @@ sosetopt(struct socket *so, struct sockopt *sopt)
32113224
tmpmac.m_buflen);
32123225
} else
32133226
#endif
3214-
{
3215-
#if __has_feature(capabilities)
3216-
sopt->sopt_dir = SOPT_SETCAP;
3217-
#endif
3218-
error = sooptcopyin(sopt, &extmac,
3227+
error = sooptcopyincap(sopt, &extmac,
32193228
sizeof extmac, sizeof extmac);
3220-
#if __has_feature(capabilities)
3221-
sopt->sopt_dir = SOPT_SET;
3222-
#endif
3223-
}
32243229
if (error)
32253230
goto bad;
32263231
error = mac_setsockopt_label(sopt->sopt_td->td_ucred,
@@ -3288,15 +3293,10 @@ sooptcopyout(struct sockopt *sopt, const void *buf, size_t len)
32883293
valsize = min(len, sopt->sopt_valsize);
32893294
sopt->sopt_valsize = valsize;
32903295
if (sopt->sopt_val != NULL) {
3291-
if (sopt->sopt_td != NULL) {
3292-
#if __has_feature(capabilities)
3293-
KASSERT(sopt->sopt_dir != SOPT_GETCAP &&
3294-
sopt->sopt_dir != SOPT_SETCAP,
3295-
("exporting capabilities not supproted"));
3296-
#endif
3296+
if (sopt->sopt_td != NULL)
32973297
error = copyout(buf, sopt->sopt_val, valsize);
3298-
} else
3299-
bcopy(buf, (__cheri_fromcap void *)sopt->sopt_val,
3298+
else
3299+
bcopynocap(buf, (__cheri_fromcap void *)sopt->sopt_val,
33003300
valsize);
33013301
}
33023302
return (error);
@@ -3438,16 +3438,8 @@ sogetopt(struct socket *so, struct sockopt *sopt)
34383438
tmpmac.m_buflen);
34393439
} else
34403440
#endif
3441-
{
3442-
#if __has_feature(capabilities)
3443-
sopt->sopt_dir = SOPT_GETCAP;
3444-
#endif
3445-
error = sooptcopyin(sopt, &extmac,
3446-
sizeof extmac, sizeof extmac);
3447-
#if __has_feature(capabilities)
3448-
sopt->sopt_dir = SOPT_GET;
3449-
#endif
3450-
}
3441+
error = sooptcopyincap(sopt, &extmac,
3442+
sizeof(extmac), sizeof(extmac));
34513443
if (error)
34523444
goto bad;
34533445
error = mac_getsockopt_label(sopt->sopt_td->td_ucred,
@@ -3477,16 +3469,8 @@ sogetopt(struct socket *so, struct sockopt *sopt)
34773469
tmpmac.m_buflen);
34783470
} else
34793471
#endif
3480-
{
3481-
#if __has_feature(capabilities)
3482-
sopt->sopt_dir = SOPT_GETCAP;
3483-
#endif
3484-
error = sooptcopyin(sopt, &extmac,
3485-
sizeof extmac, sizeof extmac);
3486-
#if __has_feature(capabilities)
3487-
sopt->sopt_dir = SOPT_GET;
3488-
#endif
3489-
}
3472+
error = sooptcopyincap(sopt, &extmac,
3473+
sizeof(extmac), sizeof(extmac));
34903474
if (error)
34913475
goto bad;
34923476
error = mac_getsockopt_peerlabel(

sys/netinet/tcp_usrreq.c

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1918,7 +1918,7 @@ copyin_tls_enable(struct sockopt *sopt, struct tls_enable *tls)
19181918
int error;
19191919

19201920
if (sopt->sopt_valsize == sizeof(tls_v0)) {
1921-
error = sooptcopyin(sopt, &tls_v0, sizeof(tls_v0),
1921+
error = sooptcopyincap(sopt, &tls_v0, sizeof(tls_v0),
19221922
sizeof(tls_v0));
19231923
if (error)
19241924
return (error);
@@ -1937,7 +1937,7 @@ copyin_tls_enable(struct sockopt *sopt, struct tls_enable *tls)
19371937
return (0);
19381938
}
19391939

1940-
return (sooptcopyin(sopt, tls, sizeof(*tls), sizeof(*tls)));
1940+
return (sooptcopyincap(sopt, tls, sizeof(*tls), sizeof(*tls)));
19411941
}
19421942
#endif
19431943

@@ -2288,13 +2288,7 @@ tcp_default_ctloutput(struct tcpcb *tp, struct sockopt *sopt)
22882288
#ifdef KERN_TLS
22892289
case TCP_TXTLS_ENABLE:
22902290
INP_WUNLOCK(inp);
2291-
#if __has_feature(capabilities)
2292-
sopt->sopt_dir = SOPT_SETCAP;
2293-
#endif
22942291
error = copyin_tls_enable(sopt, &tls);
2295-
#if __has_feature(capabilities)
2296-
sopt->sopt_dir = SOPT_SET;
2297-
#endif
22982292
if (error)
22992293
break;
23002294
error = ktls_enable_tx(so, &tls);
@@ -2311,14 +2305,8 @@ tcp_default_ctloutput(struct tcpcb *tp, struct sockopt *sopt)
23112305
break;
23122306
case TCP_RXTLS_ENABLE:
23132307
INP_WUNLOCK(inp);
2314-
#if __has_feature(capabilities)
2315-
sopt->sopt_dir = SOPT_SETCAP;
2316-
#endif
2317-
error = sooptcopyin(sopt, &tls, sizeof(tls),
2308+
error = sooptcopyincap(sopt, &tls, sizeof(tls),
23182309
sizeof(tls));
2319-
#if __has_feature(capabilities)
2320-
sopt->sopt_dir = SOPT_SET;
2321-
#endif
23222310
if (error)
23232311
break;
23242312
error = ktls_enable_rx(so, &tls);

sys/sys/sockopt.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@ struct socket;
4545
enum sopt_dir {
4646
SOPT_GET,
4747
SOPT_SET,
48-
#if __has_feature(capabilities)
49-
SOPT_GETCAP,
50-
SOPT_SETCAP,
51-
#endif
5248
};
5349

5450
struct sockopt {
@@ -63,6 +59,12 @@ struct sockopt {
6359
int sosetopt(struct socket *so, struct sockopt *sopt);
6460
int sogetopt(struct socket *so, struct sockopt *sopt);
6561
int sooptcopyin(struct sockopt *sopt, void *buf, size_t len, size_t minlen);
62+
#if __has_feature(capabilities)
63+
int sooptcopyincap(struct sockopt *sopt, void *buf, size_t len,
64+
size_t minlen);
65+
#else
66+
#define sooptcopyincap sooptcopyin
67+
#endif
6668
int sooptcopyout(struct sockopt *sopt, const void *buf, size_t len);
6769
int soopt_getm(struct sockopt *sopt, struct mbuf **mp);
6870
int soopt_mcopyin(struct sockopt *sopt, struct mbuf *m);

0 commit comments

Comments
 (0)