Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Mar 2023 08:38:33 GMT
From:      "Alexander V. Chernikov" <melifaro@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 2cda6a2fb0d9 - main - routing: add public rt_is_exportable() version to check if  the route can be exported to userland when jailed.
Message-ID:  <202303260838.32Q8cXDH006073@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by melifaro:

URL: https://cgit.FreeBSD.org/src/commit/?id=2cda6a2fb0d9473a53931dc2b0171af54dd79b04

commit 2cda6a2fb0d9473a53931dc2b0171af54dd79b04
Author:     Alexander V. Chernikov <melifaro@FreeBSD.org>
AuthorDate: 2023-03-26 08:19:56 +0000
Commit:     Alexander V. Chernikov <melifaro@FreeBSD.org>
CommitDate: 2023-03-26 08:24:27 +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
---
 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 0c3c8ddd7361..d57b5db80b89 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>
@@ -197,6 +198,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 b77692d28588..548caf0ef23a 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -218,8 +218,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);
 
@@ -1168,11 +1166,8 @@ rts_send(struct socket *so, int flags, struct mbuf *m,
 			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:
@@ -2198,23 +2193,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().
  */
@@ -2226,9 +2204,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)) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202303260838.32Q8cXDH006073>