Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157849922
D56592.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D56592.diff
View Options
diff --git a/share/man/man4/mac_seeotheruids.4 b/share/man/man4/mac_seeotheruids.4
--- a/share/man/man4/mac_seeotheruids.4
+++ b/share/man/man4/mac_seeotheruids.4
@@ -28,7 +28,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd July 25, 2015
+.Dd Februrary 26, 2026
.Dt MAC_SEEOTHERUIDS 4
.Os
.Sh NAME
@@ -80,7 +80,7 @@
.Va security.mac.seeotheruids.specificgid_enabled
to 1, and
.Va security.mac.seeotheruids.specificgid
-to the group ID to be exempted.
+to the list of group IDs to be exempted.
.Ss Label Format
No labels are defined for
.Nm .
diff --git a/sys/security/mac_seeotheruids/mac_seeotheruids.c b/sys/security/mac_seeotheruids/mac_seeotheruids.c
--- a/sys/security/mac_seeotheruids/mac_seeotheruids.c
+++ b/sys/security/mac_seeotheruids/mac_seeotheruids.c
@@ -45,9 +45,12 @@
#include <sys/param.h>
#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/priv.h>
#include <sys/proc.h>
+#include <sys/rmlock.h>
#include <sys/systm.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
@@ -59,6 +62,9 @@
#include <security/mac/mac_policy.h>
+static MALLOC_DEFINE(M_SEEOTHERUIDS, "mac_seeotheruids",
+ "mac_seeotheruids(4) security module");
+
static SYSCTL_NODE(_security_mac, OID_AUTO, seeotheruids,
CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
"TrustedBSD mac_seeotheruids policy controls");
@@ -94,13 +100,116 @@
CTLFLAG_RW, &specificgid_enabled, 0, "Make an exception for credentials "
"with a specific gid as their real primary group id or group set");
-static gid_t specificgid = 0;
-SYSCTL_UINT(_security_mac_seeotheruids, OID_AUTO, specificgid, CTLFLAG_RW,
- &specificgid, 0, "Specific gid to be exempt from seeotheruids policy");
+static struct rmlock seeotheruids_rmlock;
+RM_SYSINIT_FLAGS(mac_seeotheruids_lock, &seeotheruids_rmlock,
+ "mac_seeotheruids_lock", RM_SLEEPABLE);
+
+static gid_t *specificgids;
+static size_t specificgidcnt;
+
+static int
+gidp_cmp(const void *p1, const void *p2)
+{
+ const gid_t g1 = *(const gid_t *)p1;
+ const gid_t g2 = *(const gid_t *)p2;
+
+ return ((g1 > g2) - (g1 < g2));
+}
+
+static void
+specificgid_normalize(gid_t *gidlist, size_t *ngidp)
+{
+ int ins_idx;
+ gid_t prev_g;
+
+ if (*ngidp < 2)
+ return;
+
+ qsort(gidlist, *ngidp, sizeof(*gidlist), gidp_cmp);
+
+ prev_g = gidlist[0];
+ ins_idx = 1;
+ for (int i = ins_idx; i < *ngidp; ++i) {
+ const gid_t g = gidlist[i];
+
+ if (g != prev_g) {
+ if (i != ins_idx)
+ gidlist[ins_idx] = g;
+ ++ins_idx;
+ prev_g = g;
+ }
+ }
+
+ *ngidp = ins_idx;
+}
+
+static int
+specificgid_sysctl(SYSCTL_HANDLER_ARGS)
+{
+ gid_t *newgids = NULL;
+ size_t ingidcnt, newgidcnt = 0;
+ int error;
+
+ /* Allocate our new gid array before we take our non-sleepable lock. */
+ if (req->newptr != NULL) {
+ if (req->newlen % sizeof(gid_t) != 0)
+ return (EINVAL);
+ ingidcnt = newgidcnt = howmany(req->newlen, sizeof(gid_t));
+ newgids = mallocarray(newgidcnt, sizeof(*newgids),
+ M_SEEOTHERUIDS, M_WAITOK);
+
+ error = SYSCTL_IN(req, newgids, newgidcnt * sizeof(*newgids));
+ if (error != 0) {
+ free(newgids, M_SEEOTHERUIDS);
+ return (error);
+ }
+
+ specificgid_normalize(newgids, &newgidcnt);
+
+ /*
+ * It might be debatable whether shrinking the allocation is
+ * worth it, but we'll do it in the off-chance that someone is
+ * generating specificgid entries from various configuration
+ * sources that won't de-duplicate.
+ */
+ if (newgidcnt < ingidcnt) {
+ newgids = realloc(newgids, newgidcnt * sizeof(*newgids),
+ M_SEEOTHERUIDS, M_WAITOK);
+ }
+ }
+
+ rm_wlock(&seeotheruids_rmlock);
+
+ error = SYSCTL_OUT(req, specificgids,
+ specificgidcnt * sizeof(*specificgids));
+ if (error == 0 && req->newptr != NULL) {
+ free(specificgids, M_SEEOTHERUIDS);
+
+ specificgids = newgids;
+ specificgidcnt = newgidcnt;
+ } else if (error != 0) {
+ free(newgids, M_SEEOTHERUIDS);
+ }
+
+ rm_wunlock(&seeotheruids_rmlock);
+ return (error);
+}
+SYSCTL_PROC(_security_mac_seeotheruids, OID_AUTO, specificgid,
+ CTLFLAG_RW | CTLTYPE_UINT | CTLFLAG_MPSAFE, 0, 0,
+ &specificgid_sysctl, "I",
+ "Specific gid(s) to be exempt from seeotheruids policy");
+
+static void
+seeotheruids_destroy(struct mac_policy_conf *mpc __unused)
+{
+ free(specificgids, M_SEEOTHERUIDS);
+}
static int
seeotheruids_check(struct ucred *cr1, struct ucred *cr2)
{
+ struct rm_priotracker tracker;
+ int error = ESRCH;
if (!seeotheruids_enabled)
return (0);
@@ -110,12 +219,6 @@
return (0);
}
- if (specificgid_enabled) {
- if (cr1->cr_rgid == specificgid ||
- groupmember(specificgid, cr1))
- return (0);
- }
-
if (cr1->cr_ruid == cr2->cr_ruid)
return (0);
@@ -124,7 +227,57 @@
return (0);
}
- return (ESRCH);
+ rm_rlock(&seeotheruids_rmlock, &tracker);
+ if (specificgid_enabled && specificgids != NULL) {
+ const gid_t *suppgroups = cr1->cr_groups;
+ size_t nsupp = cr1->cr_ngroups;
+
+#if __FreeBSD_version < 1500056
+ /*
+ * FreeBSD 15.0 changed the cr_groups layout: earlier versions
+ * used cr_groups[0] for the effective GID, but that's somewhat
+ * error-prone when propagated throughout the various parts of
+ * the system (e.g., setgroups/getgroups). In older versions,
+ * we want to hop over the egid.
+ */
+ suppgroups++;
+ nsupp--;
+#endif
+
+ for (size_t i = 0, s = 0; i < specificgidcnt; i++) {
+ gid_t cgid;
+
+ cgid = specificgids[i];
+ if (cgid == cr1->cr_rgid) {
+ error = 0;
+ break;
+ }
+
+ /*
+ * specificgids and suppgroups are both sorted
+ * ascending, so advance past all of the supplemental
+ * groups that are lower than the specificgid we're
+ * currently at.
+ */
+ while (s < nsupp && cgid > suppgroups[s])
+ s++;
+
+ /*
+ * Out of supplementary groups, but we'll keep checking
+ * for rgid matches.
+ */
+ if (s == nsupp)
+ continue;
+
+ if (cgid == suppgroups[s]) {
+ error = 0;
+ break;
+ }
+ }
+ }
+
+ rm_runlock(&seeotheruids_rmlock, &tracker);
+ return (error);
}
static int
@@ -174,6 +327,7 @@
static struct mac_policy_ops seeotheruids_ops =
{
+ .mpo_destroy = seeotheruids_destroy,
.mpo_proc_check_debug = seeotheruids_proc_check_debug,
.mpo_proc_check_sched = seeotheruids_proc_check_sched,
.mpo_proc_check_signal = seeotheruids_proc_check_signal,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, May 26, 8:12 PM (13 m, 22 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33537141
Default Alt Text
D56592.diff (6 KB)
Attached To
Mode
D56592: mac_seeotheruids: allow specificgid to be a list of groups
Attached
Detach File
Event Timeline
Log In to Comment