aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2025-01-11 04:55:39 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2025-01-11 04:55:39 +0000
commit0fda4ffd69054217096dd1a40355d97be9a8ab94 (patch)
treec8b43e8dec4397332bf2b0dc50cf13b21fcba677
parent40d7ba08773751ff7d0df1a3f112b32d1d04e5ec (diff)
netlink: augment group writer with priv(9) argument
This will allow to broadcast messages visible only to priveleged subscribers. Reviewed by: melifaro Differential Revision: https://reviews.freebsd.org/D48307
-rw-r--r--sys/netlink/netlink_domain.c8
-rw-r--r--sys/netlink/netlink_generic.c2
-rw-r--r--sys/netlink/netlink_glue.c7
-rw-r--r--sys/netlink/netlink_message_writer.c3
-rw-r--r--sys/netlink/netlink_message_writer.h10
-rw-r--r--sys/netlink/netlink_sysevent.c2
-rw-r--r--sys/netlink/netlink_var.h2
-rw-r--r--sys/netlink/route/iface.c5
-rw-r--r--sys/netlink/route/neigh.c2
-rw-r--r--sys/netlink/route/nexthop.c4
-rw-r--r--sys/netlink/route/rt.c5
11 files changed, 29 insertions, 21 deletions
diff --git a/sys/netlink/netlink_domain.c b/sys/netlink/netlink_domain.c
index 922da32bfb6d..45d427f43166 100644
--- a/sys/netlink/netlink_domain.c
+++ b/sys/netlink/netlink_domain.c
@@ -47,7 +47,7 @@
#include <sys/socketvar.h>
#include <sys/sysent.h>
#include <sys/syslog.h>
-#include <sys/priv.h> /* priv_check */
+#include <sys/priv.h>
#include <sys/uio.h>
#include <netlink/netlink.h>
@@ -225,8 +225,10 @@ nl_send_group(struct nl_writer *nw)
NLCTL_RLOCK(ctl);
CK_LIST_FOREACH(nlp, &ctl->ctl_pcb_head, nl_next) {
- if (nl_isset_group_locked(nlp, nw->group.id) &&
- nlp->nl_proto == nw->group.proto) {
+ if ((nw->group.priv == 0 || priv_check_cred(
+ nlp->nl_socket->so_cred, nw->group.priv) == 0) &&
+ nlp->nl_proto == nw->group.proto &&
+ nl_isset_group_locked(nlp, nw->group.id)) {
if (nlp_last != NULL) {
struct nl_buf *copy;
diff --git a/sys/netlink/netlink_generic.c b/sys/netlink/netlink_generic.c
index 0f960d79f477..623531492173 100644
--- a/sys/netlink/netlink_generic.c
+++ b/sys/netlink/netlink_generic.c
@@ -259,7 +259,7 @@ nlctrl_notify(void *arg __unused, const struct genl_family *gf, int cmd)
struct nl_writer nw;
if (!nl_writer_group(&nw, NLMSG_SMALL, NETLINK_GENERIC, ctrl_group_id,
- false)) {
+ 0, false)) {
NL_LOG(LOG_DEBUG, "error allocating group writer");
return;
}
diff --git a/sys/netlink/netlink_glue.c b/sys/netlink/netlink_glue.c
index e550a6013654..0e8fdc0b054c 100644
--- a/sys/netlink/netlink_glue.c
+++ b/sys/netlink/netlink_glue.c
@@ -118,7 +118,7 @@ nl_writer_unicast_stub(struct nl_writer *nw, size_t size, struct nlpcb *nlp,
static bool
nl_writer_group_stub(struct nl_writer *nw, size_t size, uint16_t protocol,
- uint16_t group_id, bool waitok)
+ uint16_t group_id, int priv, bool waitok)
{
return (get_stub_writer(nw));
}
@@ -221,9 +221,10 @@ nl_writer_unicast(struct nl_writer *nw, size_t size, struct nlpcb *nlp,
bool
nl_writer_group(struct nl_writer *nw, size_t size, uint16_t protocol,
- uint16_t group_id, bool waitok)
+ uint16_t group_id, int priv, bool waitok)
{
- return (_nl->nl_writer_group(nw, size, protocol, group_id, waitok));
+ return (_nl->nl_writer_group(nw, size, protocol, group_id, priv,
+ waitok));
}
bool
diff --git a/sys/netlink/netlink_message_writer.c b/sys/netlink/netlink_message_writer.c
index 1aebc4690c2d..8c5b3ec14058 100644
--- a/sys/netlink/netlink_message_writer.c
+++ b/sys/netlink/netlink_message_writer.c
@@ -86,11 +86,12 @@ _nl_writer_unicast(struct nl_writer *nw, size_t size, struct nlpcb *nlp,
bool
_nl_writer_group(struct nl_writer *nw, size_t size, uint16_t protocol,
- uint16_t group_id, bool waitok)
+ uint16_t group_id, int priv, bool waitok)
{
*nw = (struct nl_writer){
.group.proto = protocol,
.group.id = group_id,
+ .group.priv = priv,
.cb = nl_send_group,
};
diff --git a/sys/netlink/netlink_message_writer.h b/sys/netlink/netlink_message_writer.h
index 1655acb53fef..83f925e8d93d 100644
--- a/sys/netlink/netlink_message_writer.h
+++ b/sys/netlink/netlink_message_writer.h
@@ -50,6 +50,7 @@ struct nl_writer {
struct {
uint16_t proto;
uint16_t id;
+ int priv;
} group;
};
u_int num_messages; /* Number of messages in the buffer */
@@ -67,7 +68,8 @@ struct nl_writer {
/* Provide optimized calls to the functions inside the same linking unit */
bool _nl_writer_unicast(struct nl_writer *, size_t, struct nlpcb *nlp, bool);
-bool _nl_writer_group(struct nl_writer *, size_t, uint16_t, uint16_t, bool);
+bool _nl_writer_group(struct nl_writer *, size_t, uint16_t, uint16_t, int,
+ bool);
bool _nlmsg_flush(struct nl_writer *nw);
void _nlmsg_ignore_limit(struct nl_writer *nw);
@@ -89,9 +91,9 @@ nl_writer_unicast(struct nl_writer *nw, size_t size, struct nlpcb *nlp,
static inline bool
nl_writer_group(struct nl_writer *nw, size_t size, uint16_t proto,
- uint16_t group_id, bool waitok)
+ uint16_t group_id, int priv, bool waitok)
{
- return (_nl_writer_group(nw, size, proto, group_id, waitok));
+ return (_nl_writer_group(nw, size, proto, group_id, priv, waitok));
}
static inline bool
@@ -141,7 +143,7 @@ nlmsg_end_dump(struct nl_writer *nw, int error, struct nlmsghdr *hdr)
/* Provide access to the functions via netlink_glue.c */
bool nl_writer_unicast(struct nl_writer *, size_t, struct nlpcb *, bool waitok);
-bool nl_writer_group(struct nl_writer *, size_t, uint16_t, uint16_t,
+bool nl_writer_group(struct nl_writer *, size_t, uint16_t, uint16_t, int,
bool waitok);
bool nlmsg_flush(struct nl_writer *nw);
void nlmsg_ignore_limit(struct nl_writer *nw);
diff --git a/sys/netlink/netlink_sysevent.c b/sys/netlink/netlink_sysevent.c
index 3359c77fa303..c955ce2e8b45 100644
--- a/sys/netlink/netlink_sysevent.c
+++ b/sys/netlink/netlink_sysevent.c
@@ -82,7 +82,7 @@ sysevent_write(struct sysevent_group *se, const char *subsystem, const char *typ
{
struct nl_writer nw;
- if (!nl_writer_group(&nw, NLMSG_LARGE, NETLINK_GENERIC, se->id,
+ if (!nl_writer_group(&nw, NLMSG_LARGE, NETLINK_GENERIC, se->id, 0,
false)) {
NL_LOG(LOG_DEBUG, "error allocating group writer");
return;
diff --git a/sys/netlink/netlink_var.h b/sys/netlink/netlink_var.h
index 8efe84e935c3..34cba0b28d27 100644
--- a/sys/netlink/netlink_var.h
+++ b/sys/netlink/netlink_var.h
@@ -187,7 +187,7 @@ struct nl_function_wrapper {
bool (*nl_writer_unicast)(struct nl_writer *nw, size_t size,
struct nlpcb *nlp, bool waitok);
bool (*nl_writer_group)(struct nl_writer *nw, size_t size,
- uint16_t protocol, uint16_t group_id, bool waitok);
+ uint16_t protocol, uint16_t group_id, int priv, bool waitok);
bool (*nlmsg_end_dump)(struct nl_writer *nw, int error, struct nlmsghdr *hdr);
int (*nl_modify_ifp_generic)(struct ifnet *ifp, struct nl_parsed_link *lattrs,
const struct nlattr_bmask *bm, struct nl_pstate *npt);
diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c
index 86b1f8f1b1bc..d856498b975f 100644
--- a/sys/netlink/route/iface.c
+++ b/sys/netlink/route/iface.c
@@ -1386,7 +1386,8 @@ rtnl_handle_ifaddr(void *arg __unused, struct ifaddr *ifa, int cmd)
if (!nl_has_listeners(NETLINK_ROUTE, group))
return;
- if (!nl_writer_group(&nw, NLMSG_LARGE, NETLINK_ROUTE, group, false)) {
+ if (!nl_writer_group(&nw, NLMSG_LARGE, NETLINK_ROUTE, group, 0,
+ false)) {
NL_LOG(LOG_DEBUG, "error allocating group writer");
return;
}
@@ -1406,7 +1407,7 @@ rtnl_handle_ifevent(if_t ifp, int nlmsg_type, int if_flags_mask)
if (!nl_has_listeners(NETLINK_ROUTE, RTNLGRP_LINK))
return;
- if (!nl_writer_group(&nw, NLMSG_LARGE, NETLINK_ROUTE, RTNLGRP_LINK,
+ if (!nl_writer_group(&nw, NLMSG_LARGE, NETLINK_ROUTE, RTNLGRP_LINK, 0,
false)) {
NL_LOG(LOG_DEBUG, "error allocating group writer");
return;
diff --git a/sys/netlink/route/neigh.c b/sys/netlink/route/neigh.c
index ec58c6140db8..9eaaae263254 100644
--- a/sys/netlink/route/neigh.c
+++ b/sys/netlink/route/neigh.c
@@ -566,7 +566,7 @@ rtnl_lle_event(void *arg __unused, struct llentry *lle, int evt)
int nlmsgs_type = evt == LLENTRY_RESOLVED ? NL_RTM_NEWNEIGH : NL_RTM_DELNEIGH;
- if (!nl_writer_group(&nw, NLMSG_SMALL, NETLINK_ROUTE, RTNLGRP_NEIGH,
+ if (!nl_writer_group(&nw, NLMSG_SMALL, NETLINK_ROUTE, RTNLGRP_NEIGH, 0,
false)) {
NL_LOG(LOG_DEBUG, "error allocating group writer");
return;
diff --git a/sys/netlink/route/nexthop.c b/sys/netlink/route/nexthop.c
index 03f1a57fd1e4..30aa3dd72534 100644
--- a/sys/netlink/route/nexthop.c
+++ b/sys/netlink/route/nexthop.c
@@ -554,7 +554,7 @@ delete_unhop(struct unhop_ctl *ctl, struct nlmsghdr *hdr, uint32_t uidx)
};
if (!nl_writer_group(&nw, NLMSG_SMALL, NETLINK_ROUTE, RTNLGRP_NEXTHOP,
- false)) {
+ 0, false)) {
NL_LOG(LOG_DEBUG, "error allocating message writer");
return (ENOMEM);
}
@@ -949,7 +949,7 @@ rtnl_handle_newnhop(struct nlmsghdr *hdr, struct nlpcb *nlp,
};
if (!nl_writer_group(&nw, NLMSG_SMALL, NETLINK_ROUTE, RTNLGRP_NEXTHOP,
- false)) {
+ 0, false)) {
NL_LOG(LOG_DEBUG, "error allocating message writer");
return (ENOMEM);
}
diff --git a/sys/netlink/route/rt.c b/sys/netlink/route/rt.c
index 14bd73d33411..e90debee46da 100644
--- a/sys/netlink/route/rt.c
+++ b/sys/netlink/route/rt.c
@@ -353,7 +353,8 @@ report_operation(uint32_t fibnum, struct rib_cmd_info *rc,
struct nl_writer nw;
uint32_t group_id = family_to_group(rt_get_family(rc->rc_rt));
- if (nl_writer_group(&nw, NLMSG_SMALL, NETLINK_ROUTE, group_id, false)) {
+ if (nl_writer_group(&nw, NLMSG_SMALL, NETLINK_ROUTE, group_id, 0,
+ false)) {
struct route_nhop_data rnd = {
.rnd_nhop = rc_get_nhop(rc),
.rnd_weight = rc->rc_nh_weight,
@@ -1082,7 +1083,7 @@ rtnl_handle_route_event(uint32_t fibnum, const struct rib_cmd_info *rc)
};
uint32_t group_id = family_to_group(family);
- if (!nl_writer_group(&nw, NLMSG_SMALL, NETLINK_ROUTE, group_id,
+ if (!nl_writer_group(&nw, NLMSG_SMALL, NETLINK_ROUTE, group_id, 0,
false)) {
NL_LOG(LOG_DEBUG, "error allocating event buffer");
return;