git: 50c962d77370 - main - krpc/clnt_nl: filter RPC replies on vnet
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 01 Feb 2025 19:33:55 UTC
The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=50c962d773705f60d32c29f8e4bb2743ab55733b commit 50c962d773705f60d32c29f8e4bb2743ab55733b Author: Gleb Smirnoff <glebius@FreeBSD.org> AuthorDate: 2025-02-01 19:27:22 +0000 Commit: Gleb Smirnoff <glebius@FreeBSD.org> CommitDate: 2025-02-01 19:27:22 +0000 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. --- sys/rpc/clnt_nl.c | 13 ++++++++++++- sys/rpc/krpc.h | 5 ++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/sys/rpc/clnt_nl.c b/sys/rpc/clnt_nl.c index 8f841e4240d7..177566232cb5 100644 --- a/sys/rpc/clnt_nl.c +++ b/sys/rpc/clnt_nl.c @@ -269,10 +269,15 @@ clnt_nl_call(CLIENT *cl, struct rpc_callextra *ext, rpcproc_t proc, u_int retries = 0; bool rv __diagused; + CURVNET_ASSERT_SET(); + cr = malloc(sizeof(struct ct_request), M_RPC, M_WAITOK); *cr = (struct ct_request){ .cr_xid = atomic_fetchadd_32(&nl->nl_xid, 1), .cr_error = ETIMEDOUT, +#ifdef VIMAGE + .cr_vnet = curvnet, +#endif }; if (ext) { @@ -394,6 +399,8 @@ clnt_nl_reply(struct nlmsghdr *hdr, struct nl_pstate *npt) struct mchain mc; int error; + CURVNET_ASSERT_SET(); + if ((error = nl_parse_nlmsg(hdr, &rpcnl_parser, npt, &attrs)) != 0) return (error); if (attrs.data == NULL) @@ -415,7 +422,11 @@ clnt_nl_reply(struct nlmsghdr *hdr, struct nl_pstate *npt) rw_runlock(&rpcnl_global_lock); TAILQ_FOREACH(cr, &nl->nl_pending, cr_link) - if (cr->cr_xid == hdr->nlmsg_seq) + if (cr->cr_xid == hdr->nlmsg_seq +#ifdef VIMAGE + && cr->cr_vnet == curvnet +#endif + ) break; if (cr == NULL) { mtx_unlock(&nl->nl_lock); diff --git a/sys/rpc/krpc.h b/sys/rpc/krpc.h index 06aa14eeb91f..f77e2d2d7428 100644 --- a/sys/rpc/krpc.h +++ b/sys/rpc/krpc.h @@ -49,8 +49,11 @@ struct mbuf *_rpc_copym_into_ext_pgs(struct mbuf *, int); */ struct ct_request { TAILQ_ENTRY(ct_request) cr_link; - uint32_t cr_xid; /* XID of request */ struct mbuf *cr_mrep; /* reply received by upcall */ +#ifdef VIMAGE + struct vnet *cr_vnet; +#endif + uint32_t cr_xid; /* XID of request */ int cr_error; /* any error from upcall */ char cr_verf[MAX_AUTH_BYTES]; /* reply verf */ };