Page MenuHomeFreeBSD

D39206.id119249.diff
No OneTemporary

D39206.id119249.diff

diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -3440,6 +3440,7 @@
#endif
case AF_LOCAL:
case AF_ROUTE:
+ case AF_NETLINK:
break;
default:
if (!(pr->pr_allow & PR_ALLOW_SOCKET_AF))
diff --git a/sys/netinet/ip_carp.c b/sys/netinet/ip_carp.c
--- a/sys/netinet/ip_carp.c
+++ b/sys/netinet/ip_carp.c
@@ -2338,6 +2338,9 @@
if_t ifp;
int error;
+ if (!nlp_unconstrained_vnet(npt->nlp))
+ return (EPERM);
+
error = nl_parse_nlmsg(hdr, &carp_parser, npt, &attrs);
if (error != 0)
return (error);
@@ -2380,6 +2383,9 @@
if_t ifp;
int error;
+ if (!nlp_unconstrained_vnet(npt->nlp))
+ return (EPERM);
+
error = nl_parse_nlmsg(hdr, &carp_parser, npt, &attrs);
if (error != 0)
return (error);
diff --git a/sys/netlink/netlink_ctl.h b/sys/netlink/netlink_ctl.h
--- a/sys/netlink/netlink_ctl.h
+++ b/sys/netlink/netlink_ctl.h
@@ -81,6 +81,7 @@
bool nl_has_listeners(int netlink_family, uint32_t groups_mask);
bool nlp_has_priv(struct nlpcb *nlp, int priv);
struct ucred *nlp_get_cred(struct nlpcb *nlp);
+bool nlp_unconstrained_vnet(const struct nlpcb *nlp);
/* netlink_generic.c */
struct genl_cmd {
diff --git a/sys/netlink/netlink_domain.c b/sys/netlink/netlink_domain.c
--- a/sys/netlink/netlink_domain.c
+++ b/sys/netlink/netlink_domain.c
@@ -36,6 +36,7 @@
#include <sys/lock.h>
#include <sys/rmlock.h>
#include <sys/domain.h>
+#include <sys/jail.h>
#include <sys/mbuf.h>
#include <sys/protosw.h>
#include <sys/proc.h>
@@ -111,6 +112,10 @@
MPASS(group_id <= NLP_MAX_GROUPS);
--group_id;
+ /* TODO: add family handler callback */
+ if (!nlp_unconstrained_vnet(nlp))
+ return;
+
nlp->nl_groups[group_id / 64] |= (uint64_t)1 << (group_id % 64);
}
@@ -212,6 +217,12 @@
return (priv_check_cred(nlp->nl_cred, priv) == 0);
}
+bool
+nlp_unconstrained_vnet(const struct nlpcb *nlp)
+{
+ return (nlp->nl_unconstrained_vnet);
+}
+
struct ucred *
nlp_get_cred(struct nlpcb *nlp)
{
@@ -308,6 +319,7 @@
nlp->nl_process_id = curproc->p_pid;
nlp->nl_linux = is_linux;
nlp->nl_active = true;
+ nlp->nl_unconstrained_vnet = !jailed_without_vnet(so->so_cred);
NLP_LOCK_INIT(nlp);
refcount_init(&nlp->nl_refcount, 1);
nl_init_io(nlp);
diff --git a/sys/netlink/netlink_generic.c b/sys/netlink/netlink_generic.c
--- a/sys/netlink/netlink_generic.c
+++ b/sys/netlink/netlink_generic.c
@@ -31,6 +31,7 @@
#include <sys/ck.h>
#include <sys/epoch.h>
#include <sys/kernel.h>
+#include <sys/jail.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/priv.h>
diff --git a/sys/netlink/netlink_route.c b/sys/netlink/netlink_route.c
--- a/sys/netlink/netlink_route.c
+++ b/sys/netlink/netlink_route.c
@@ -93,6 +93,11 @@
} else if (cmd->priv != 0)
NLP_LOG(LOG_DEBUG3, nlp, "priv %d check passed for msg %s", cmd->priv, cmd->name);
+ if (!nlp_unconstrained_vnet(nlp) && (cmd->flags & RTNL_F_ALLOW_NONVNET_JAIL) == 0) {
+ NLP_LOG(LOG_DEBUG2, nlp, "jail check failed for msg %s", cmd->name);
+ return (EPERM);
+ }
+
bool need_epoch = !(cmd->flags & RTNL_F_NOEPOCH);
if (need_epoch)
diff --git a/sys/netlink/netlink_var.h b/sys/netlink/netlink_var.h
--- a/sys/netlink/netlink_var.h
+++ b/sys/netlink/netlink_var.h
@@ -61,6 +61,7 @@
bool nl_task_pending;
bool nl_tx_blocked; /* No new requests accepted */
bool nl_linux; /* true if running under compat */
+ bool nl_unconstrained_vnet; /* true if running under VNET jail (or without jail) */
struct nl_io_queue rx_queue;
struct nl_io_queue tx_queue;
struct taskqueue *nl_taskqueue;
diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c
--- a/sys/netlink/route/iface.c
+++ b/sys/netlink/route/iface.c
@@ -32,6 +32,7 @@
#include <sys/types.h>
#include <sys/eventhandler.h>
#include <sys/kernel.h>
+#include <sys/jail.h>
#include <sys/malloc.h>
#include <sys/socket.h>
#include <sys/sockio.h>
@@ -61,6 +62,7 @@
struct nl_writer *nw;
struct nlmsghdr hdr;
struct nlpcb *so;
+ struct ucred *cred;
uint32_t fibnum;
int family;
int error;
@@ -833,6 +835,8 @@
continue;
if (ifa->ifa_addr->sa_family == AF_LINK)
continue;
+ if (prison_if(wa->cred, ifa->ifa_addr) != 0)
+ continue;
wa->count++;
if (!dump_iface_addr(wa->nw, ifp, ifa, &wa->hdr))
return (ENOMEM);
@@ -856,6 +860,7 @@
struct netlink_walkargs wa = {
.so = nlp,
.nw = npt->nw,
+ .cred = nlp_get_cred(nlp),
.family = attrs.ifa_family,
.hdr.nlmsg_pid = hdr->nlmsg_pid,
.hdr.nlmsg_seq = hdr->nlmsg_seq,
@@ -977,7 +982,7 @@
.cmd = NL_RTM_GETLINK,
.name = "RTM_GETLINK",
.cb = &rtnl_handle_getlink,
- .flags = RTNL_F_NOEPOCH,
+ .flags = RTNL_F_NOEPOCH | RTNL_F_ALLOW_NONVNET_JAIL,
},
{
.cmd = NL_RTM_DELLINK,
@@ -997,6 +1002,7 @@
.cmd = NL_RTM_GETADDR,
.name = "RTM_GETADDR",
.cb = &rtnl_handle_getaddr,
+ .flags = RTNL_F_ALLOW_NONVNET_JAIL,
},
{
.cmd = NL_RTM_NEWADDR,
diff --git a/sys/netlink/route/route_var.h b/sys/netlink/route/route_var.h
--- a/sys/netlink/route/route_var.h
+++ b/sys/netlink/route/route_var.h
@@ -48,7 +48,8 @@
int flags;
};
-#define RTNL_F_NOEPOCH 0x01
+#define RTNL_F_NOEPOCH 0x01 /* Do not enter epoch when handling command */
+#define RTNL_F_ALLOW_NONVNET_JAIL 0x02 /* Allow command execution inside non-VNET jail */
bool rtnl_register_messages(const struct rtnl_cmd_handler *handlers, int count);
diff --git a/sys/netlink/route/rt.c b/sys/netlink/route/rt.c
--- a/sys/netlink/route/rt.c
+++ b/sys/netlink/route/rt.c
@@ -513,6 +513,8 @@
wa->count++;
if (wa->error != 0)
return (0);
+ if (!rt_is_exportable(rt, nlp_get_cred(wa->nlp)))
+ return (0);
wa->dumped++;
rt_get_rnd(rt, &wa->rnd);
@@ -606,6 +608,9 @@
RIB_RUNLOCK(rnh);
+ if (!rt_is_exportable(rt, nlp_get_cred(nlp)))
+ return (ESRCH);
+
IF_DEBUG_LEVEL(LOG_DEBUG2) {
char rtbuf[NHOP_PRINT_BUFSIZE] __unused, nhbuf[NHOP_PRINT_BUFSIZE] __unused;
FIB_LOG(LOG_DEBUG2, fibnum, family, "getroute completed: got %s for %s",
@@ -1026,6 +1031,7 @@
.cmd = NL_RTM_GETROUTE,
.name = "RTM_GETROUTE",
.cb = &rtnl_handle_getroute,
+ .flags = RTNL_F_ALLOW_NONVNET_JAIL,
},
{
.cmd = NL_RTM_DELROUTE,

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 7, 7:27 AM (14 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31018591
Default Alt Text
D39206.id119249.diff (6 KB)

Event Timeline