Skip to content

Commit 50c962d

Browse files
committed
krpc/clnt_nl: filter RPC replies on vnet
RPC calls are filtered by the Netlink system itself, but the RPC replies are not. With legitimate use the chance of a xid collision is zero, since global clients use global atomically updated 32-bit counter for that. However, a malicious jail may blindly inject replies guessing the xid, where guessing is trivial. Protect against that checking the vnet, too.
1 parent 96104ca commit 50c962d

File tree

2 files changed

+16
-2
lines changed

2 files changed

+16
-2
lines changed

sys/rpc/clnt_nl.c

+12-1
Original file line numberDiff line numberDiff line change
@@ -269,10 +269,15 @@ clnt_nl_call(CLIENT *cl, struct rpc_callextra *ext, rpcproc_t proc,
269269
u_int retries = 0;
270270
bool rv __diagused;
271271

272+
CURVNET_ASSERT_SET();
273+
272274
cr = malloc(sizeof(struct ct_request), M_RPC, M_WAITOK);
273275
*cr = (struct ct_request){
274276
.cr_xid = atomic_fetchadd_32(&nl->nl_xid, 1),
275277
.cr_error = ETIMEDOUT,
278+
#ifdef VIMAGE
279+
.cr_vnet = curvnet,
280+
#endif
276281
};
277282

278283
if (ext) {
@@ -394,6 +399,8 @@ clnt_nl_reply(struct nlmsghdr *hdr, struct nl_pstate *npt)
394399
struct mchain mc;
395400
int error;
396401

402+
CURVNET_ASSERT_SET();
403+
397404
if ((error = nl_parse_nlmsg(hdr, &rpcnl_parser, npt, &attrs)) != 0)
398405
return (error);
399406
if (attrs.data == NULL)
@@ -415,7 +422,11 @@ clnt_nl_reply(struct nlmsghdr *hdr, struct nl_pstate *npt)
415422
rw_runlock(&rpcnl_global_lock);
416423

417424
TAILQ_FOREACH(cr, &nl->nl_pending, cr_link)
418-
if (cr->cr_xid == hdr->nlmsg_seq)
425+
if (cr->cr_xid == hdr->nlmsg_seq
426+
#ifdef VIMAGE
427+
&& cr->cr_vnet == curvnet
428+
#endif
429+
)
419430
break;
420431
if (cr == NULL) {
421432
mtx_unlock(&nl->nl_lock);

sys/rpc/krpc.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,11 @@ struct mbuf *_rpc_copym_into_ext_pgs(struct mbuf *, int);
4949
*/
5050
struct ct_request {
5151
TAILQ_ENTRY(ct_request) cr_link;
52-
uint32_t cr_xid; /* XID of request */
5352
struct mbuf *cr_mrep; /* reply received by upcall */
53+
#ifdef VIMAGE
54+
struct vnet *cr_vnet;
55+
#endif
56+
uint32_t cr_xid; /* XID of request */
5457
int cr_error; /* any error from upcall */
5558
char cr_verf[MAX_AUTH_BYTES]; /* reply verf */
5659
};

0 commit comments

Comments
 (0)