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
This commit is contained in:
parent
328ebd4680
commit
2cda6a2fb0
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user