diff options
author | Alexander V. Chernikov <melifaro@FreeBSD.org> | 2023-03-26 08:19:56 +0000 |
---|---|---|
committer | Alexander V. Chernikov <melifaro@FreeBSD.org> | 2023-04-09 13:52:55 +0000 |
commit | 2ccf6388ba60ab8f1acc697a1112d8891102f36f (patch) | |
tree | cd5066be9b79c92e37488a335182264cc4e1eab1 | |
parent | 2e3c94b70d31a7e62a69d345510ac00c787eb875 (diff) | |
download | src-2ccf6388ba60ab8f1acc697a1112d8891102f36f.tar.gz src-2ccf6388ba60ab8f1acc697a1112d8891102f36f.zip |
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)
-rw-r--r-- | sys/net/route/route_ctl.h | 2 | ||||
-rw-r--r-- | sys/net/route/route_rtentry.c | 24 | ||||
-rw-r--r-- | 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: @@ -2274,23 +2269,6 @@ rt_dispatch(struct mbuf *m, sa_family_t saf) } /* - * 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(). */ static int @@ -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)) { |