git: 2ccf6388ba60 - stable/13 - routing: add public rt_is_exportable() version to check if the route can be exported to userland when jailed.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 09 Apr 2023 13:53:14 UTC
The branch stable/13 has been updated by melifaro: URL: https://cgit.FreeBSD.org/src/commit/?id=2ccf6388ba60ab8f1acc697a1112d8891102f36f commit 2ccf6388ba60ab8f1acc697a1112d8891102f36f Author: Alexander V. Chernikov <melifaro@FreeBSD.org> AuthorDate: 2023-03-26 08:19:56 +0000 Commit: Alexander V. Chernikov <melifaro@FreeBSD.org> CommitDate: 2023-04-09 13:52:55 +0000 routing: add public rt_is_exportable() version to check if the route can be exported to userland when jailed. Differential Revision: https://reviews.freebsd.org/D39204 MFC after: 2 weeks (cherry picked from commit 2cda6a2fb0d9473a53931dc2b0171af54dd79b04) --- sys/net/route/route_ctl.h | 2 ++ sys/net/route/route_rtentry.c | 24 ++++++++++++++++++++++++ sys/net/rtsock.c | 29 ++++------------------------- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/sys/net/route/route_ctl.h b/sys/net/route/route_ctl.h index e8560e681ddb..b65b64fcdaa0 100644 --- a/sys/net/route/route_ctl.h +++ b/sys/net/route/route_ctl.h @@ -121,6 +121,7 @@ void rib_foreach_table_walk_del(int family, rib_filter_f_t *filter_f, void *arg) struct nhop_object; struct nhgrp_object; +struct ucred; const struct rtentry *rib_lookup_prefix(uint32_t fibnum, int family, const struct sockaddr *dst, const struct sockaddr *netmask, @@ -133,6 +134,7 @@ bool rt_is_host(const struct rtentry *rt); sa_family_t rt_get_family(const struct rtentry *); struct nhop_object *rt_get_raw_nhop(const struct rtentry *rt); void rt_get_rnd(const struct rtentry *rt, struct route_nhop_data *rnd); +bool rt_is_exportable(const struct rtentry *rt, struct ucred *cred); #ifdef INET struct in_addr; void rt_get_inet_prefix_plen(const struct rtentry *rt, struct in_addr *paddr, diff --git a/sys/net/route/route_rtentry.c b/sys/net/route/route_rtentry.c index 64900ae3ae39..7bf624f01540 100644 --- a/sys/net/route/route_rtentry.c +++ b/sys/net/route/route_rtentry.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include <sys/systm.h> #include <sys/malloc.h> #include <sys/socket.h> +#include <sys/jail.h> #include <sys/kernel.h> #include <sys/lock.h> #include <sys/rmlock.h> @@ -198,6 +199,29 @@ rt_get_rnd(const struct rtentry *rt, struct route_nhop_data *rnd) rnd->rnd_weight = rt->rt_weight; } +/* + * If the process in in jail w/o VNET, export only host routes for the + * addresses assigned to the jail. + * Otherwise, allow exporting the entire table. + */ +bool +rt_is_exportable(const struct rtentry *rt, struct ucred *cred) +{ + if (!rt_is_host(rt)) { + /* + * Performance optimisation: only host routes are allowed + * in the jail w/o vnet. + */ + if (jailed_without_vnet(cred)) + return (false); + } else { + if (prison_if(cred, rt_key_const(rt)) != 0) + return (false); + } + + return (true); +} + #ifdef INET /* * Stores IPv4 address and prefix length of @rt inside diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index fc9439602c13..0c6d856ed7ad 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -208,8 +208,6 @@ static int update_rtm_from_rc(struct rt_addrinfo *info, static void send_rtm_reply(struct socket *so, struct rt_msghdr *rtm, struct mbuf *m, sa_family_t saf, u_int fibnum, int rtm_errno); -static bool can_export_rte(struct ucred *td_ucred, bool rt_is_host, - const struct sockaddr *rt_dst); static void rtsock_notify_event(uint32_t fibnum, const struct rib_cmd_info *rc); static void rtsock_ifmsg(struct ifnet *ifp, int if_flags_mask); @@ -1229,11 +1227,8 @@ route_output(struct mbuf *m, struct socket *so, ...) senderr(error); nh = rc.rc_nh_new; - if (!can_export_rte(curthread->td_ucred, - info.rti_info[RTAX_NETMASK] == NULL, - info.rti_info[RTAX_DST])) { + if (!rt_is_exportable(rc.rc_rt, curthread->td_ucred)) senderr(ESRCH); - } break; default: @@ -2273,23 +2268,6 @@ rt_dispatch(struct mbuf *m, sa_family_t saf) netisr_queue(NETISR_ROUTE, m); /* mbuf is free'd on failure. */ } -/* - * Checks if rte can be exported w.r.t jails/vnets. - * - * Returns true if it can, false otherwise. - */ -static bool -can_export_rte(struct ucred *td_ucred, bool rt_is_host, - const struct sockaddr *rt_dst) -{ - - if ((!rt_is_host) ? jailed_without_vnet(td_ucred) - : prison_if(td_ucred, rt_dst) != 0) - return (false); - return (true); -} - - /* * This is used in dumping the kernel table via sysctl(). */ @@ -2301,9 +2279,10 @@ sysctl_dumpentry(struct rtentry *rt, void *vw) NET_EPOCH_ASSERT(); - export_rtaddrs(rt, w->dst, w->mask); - if (!can_export_rte(w->w_req->td->td_ucred, rt_is_host(rt), w->dst)) + if (!rt_is_exportable(rt, w->w_req->td->td_ucred)) return (0); + + export_rtaddrs(rt, w->dst, w->mask); nh = rt_get_raw_nhop(rt); #ifdef ROUTE_MPATH if (NH_IS_NHGRP(nh)) {