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 @@ -47,7 +47,7 @@ #include #include #include -#include /* priv_check */ +#include #include #include @@ -225,8 +225,10 @@ 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 --- a/sys/netlink/netlink_generic.c +++ b/sys/netlink/netlink_generic.c @@ -259,7 +259,7 @@ 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 --- a/sys/netlink/netlink_glue.c +++ b/sys/netlink/netlink_glue.c @@ -118,7 +118,7 @@ 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 @@ 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.h b/sys/netlink/netlink_message_writer.h --- a/sys/netlink/netlink_message_writer.h +++ b/sys/netlink/netlink_message_writer.h @@ -50,6 +50,7 @@ struct { uint16_t proto; uint16_t id; + int priv; } group; }; u_int num_messages; /* Number of messages in the buffer */ @@ -67,7 +68,8 @@ /* 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 @@ 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 @@ /* 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_message_writer.c b/sys/netlink/netlink_message_writer.c --- a/sys/netlink/netlink_message_writer.c +++ b/sys/netlink/netlink_message_writer.c @@ -86,11 +86,12 @@ 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_sysevent.c b/sys/netlink/netlink_sysevent.c --- a/sys/netlink/netlink_sysevent.c +++ b/sys/netlink/netlink_sysevent.c @@ -82,7 +82,7 @@ { 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 --- a/sys/netlink/netlink_var.h +++ b/sys/netlink/netlink_var.h @@ -187,7 +187,7 @@ 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 --- a/sys/netlink/route/iface.c +++ b/sys/netlink/route/iface.c @@ -1386,7 +1386,8 @@ 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 @@ 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 --- a/sys/netlink/route/neigh.c +++ b/sys/netlink/route/neigh.c @@ -566,7 +566,7 @@ 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 --- a/sys/netlink/route/nexthop.c +++ b/sys/netlink/route/nexthop.c @@ -554,7 +554,7 @@ }; 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 @@ }; 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 --- a/sys/netlink/route/rt.c +++ b/sys/netlink/route/rt.c @@ -353,7 +353,8 @@ 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 @@ }; 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;