git: 2cda6a2fb0d9 - main - 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, 26 Mar 2023 08:38:33 UTC
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)) {