Subject: Re: struct socket and gid?
To: Jeremy C. Reed <reed@reedmedia.net>
From: Peter Postma <peter@pointless.nl>
List: tech-net
Date: 01/26/2006 00:46:05
--IS0zKkzwUGydFO0o
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Tue, Jan 24, 2006 at 11:33:15PM -0800, Jeremy C. Reed wrote:
> (Please CC me on replies.)
> 
> PF offers a group keyword for a rule to only apply if the packets are from 
> sockets owned by the specified group.
> 
> This was noted by itojun in 
> http://mail-index.netbsd.org/tech-net/2003/06/30/0042.html but there are 
> so many emails that I didn't see anything related to this.
> 
> Are there plans to have socket struct also contain the gid?
> 
> DragonFly (and FreeBSD) socket has:
>         struct  ucred *so_cred;         /* user credentials */
> 
> And this ucred has various information like real group id, saved group id.
> 
> OpenBSD has the real and effective group IDs.
> 

I've attached a patch that adds ui_gid member to uidinfo and initializes
it in socreate(). There might be a better way to do this though.

> Anyways, I am curious: has there been any work or proposals related to
> this for NetBSD?
>

Not yet, this is the first. Are there any problems with this proposal
(and patch)?

-- 
Peter Postma

--IS0zKkzwUGydFO0o
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="uidinfo+gid.diff"

Index: kern/kern_resource.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_resource.c,v
retrieving revision 1.99
diff -u -p -r1.99 kern_resource.c
--- kern/kern_resource.c	11 Dec 2005 12:24:29 -0000	1.99
+++ kern/kern_resource.c	25 Jan 2006 22:48:10 -0000
@@ -890,6 +890,7 @@ again:
 
 	LIST_INSERT_HEAD(uipp, uip, ui_hash);
 	uip->ui_uid = uid;
+	uip->ui_gid = GID_MAX;
 	simple_lock_init(&uip->ui_slock);
 	simple_unlock(&uihashtbl_slock);
 
@@ -897,6 +898,23 @@ again:
 }
 
 /*
+ * Same as uid_find(), but initialize the ui_gid member as well.
+ */
+struct uidinfo *
+uid_find1(uid_t uid, gid_t gid)
+{
+	struct uidinfo *uip;
+	int s;
+
+	uip = uid_find(uid);
+	UILOCK(uip, s);
+	uip->ui_gid = gid;
+	UIUNLOCK(uip, s);
+
+	return uip;
+}
+
+/*
  * Change the count associated with number of processes
  * a given user is using.
  */
Index: kern/uipc_socket.c
===================================================================
RCS file: /cvsroot/src/sys/kern/uipc_socket.c,v
retrieving revision 1.115
diff -u -p -r1.115 uipc_socket.c
--- kern/uipc_socket.c	27 Dec 2005 00:00:29 -0000	1.115
+++ kern/uipc_socket.c	25 Jan 2006 22:48:10 -0000
@@ -454,6 +454,7 @@ socreate(int dom, struct socket **aso, i
 	const struct protosw	*prp;
 	struct socket	*so;
 	uid_t		uid;
+	gid_t		gid;
 	int		error, s;
 
 	if (proto)
@@ -480,10 +481,12 @@ socreate(int dom, struct socket **aso, i
 #endif
 	if (l != NULL) {
 		uid = l->l_proc->p_ucred->cr_uid;
+		gid = l->l_proc->p_ucred->cr_gid;
 	} else {
 		uid = 0;
+		gid = 0;
 	}
-	so->so_uidinfo = uid_find(uid);
+	so->so_uidinfo = uid_find1(uid, gid);
 	error = (*prp->pr_usrreq)(so, PRU_ATTACH, (struct mbuf *)0,
 	    (struct mbuf *)(long)proto, (struct mbuf *)0, l);
 	if (error) {
Index: sys/resourcevar.h
===================================================================
RCS file: /cvsroot/src/sys/sys/resourcevar.h,v
retrieving revision 1.30
diff -u -p -r1.30 resourcevar.h
--- sys/resourcevar.h	11 Dec 2005 12:25:21 -0000	1.30
+++ sys/resourcevar.h	25 Jan 2006 22:48:10 -0000
@@ -92,6 +92,7 @@ struct plimit {
 struct uidinfo {
 	LIST_ENTRY(uidinfo) ui_hash;
 	uid_t	ui_uid;
+	gid_t	ui_gid;
 	long	ui_proccnt;	/* Number of processes */
 	long	ui_lockcnt;	/* Number of locks */
 	rlim_t	ui_sbsize;	/* socket buffer size */
@@ -115,6 +116,7 @@ extern u_long uihash;		/* size of hash t
 int       chgproccnt(uid_t, int);
 int       chgsbsize(struct uidinfo *, u_long *, u_long, rlim_t);
 struct uidinfo *uid_find(uid_t);
+struct uidinfo *uid_find1(uid_t, gid_t);
 
 extern char defcorename[];
 void	 addupc_intr(struct proc *, u_long);

--IS0zKkzwUGydFO0o--