Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 21 Mar 2004 12:09:24 -0800 (PST)
From:      Dariusz Kulinski <takeda3@netzero.net>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   ports/64546: [patch] problems with ipv6 connections when running as non-root
Message-ID:  <200403212009.i2LK9OSh019098@freebsd.takeda.tk>
Resent-Message-ID: <200403212010.i2LKAHkE027462@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         64546
>Category:       ports
>Synopsis:       [patch] problems with ipv6 connections when running as non-root
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Sun Mar 21 12:10:17 PST 2004
>Closed-Date:
>Last-Modified:
>Originator:     Dariusz Kulinski
>Release:        FreeBSD 4.9-RELEASE-p4 i386
>Organization:
>Environment:
System: FreeBSD freebsd.takeda.tk 4.9-RELEASE-p4 FreeBSD 4.9-RELEASE-p4 #0: Wed Mar 17 22:05:17 PST 2004 root@freebsd.takeda.tk:/usr/obj/usr/src/sys/TUNED i386


	
>Description:
	oidentd had problems with connections through ipv6 while was degraded to regular user,
	new patch was added to fix that issue
>How-To-Repeat:
	
>Fix:

	

--- oidentd.patch begins here ---
diff -ruN oidentd.bak/files/patch-unprivileged_ipv6 oidentd/files/patch-unprivileged_ipv6
--- oidentd.bak/files/patch-unprivileged_ipv6	Wed Dec 31 16:00:00 1969
+++ oidentd/files/patch-unprivileged_ipv6	Sat Mar 20 20:38:56 2004
@@ -0,0 +1,392 @@
+diff -ru src.old/kernel/freebsd.c src/kernel/freebsd.c
+--- src.old/kernel/freebsd.c	Sat Mar 20 20:36:51 2004
++++ src/kernel/freebsd.c	Sat Mar 20 20:37:09 2004
+@@ -159,11 +159,11 @@
+ 
+ #ifdef _HAVE_OLD_INPCB
+ 
+-static struct socket *getlist4(	void *arg,
++static struct socket *getlist(	void *arg,
+ 								in_port_t lport,
+ 								in_port_t fport,
+-								const struct in_addr *laddr,
+-								const struct in_addr *faddr)
++								const struct sockaddr *laddr,
++								const struct sockaddr *faddr)
+ {
+ 	struct inpcb *pcbp = arg;
+ 	struct inpcb *head;
+@@ -175,8 +175,8 @@
+ 
+ 	do {
+ 		if (opt_enabled(PROXY)) {
+-			if (faddr->s_addr == SIN4(&proxy)->sin_addr.s_addr &&
+-				laddr->s_addr != SIN4(&proxy)->sin_addr.s_addr &&
++			if (SIN4(faddr)->sin_addr.s_addr == SIN4(&proxy)->sin_addr.s_addr &&
++				SIN4(laddr)->sin_addr.s_addr != SIN4(&proxy)->sin_addr.s_addr &&
+ 				pcbp->inp_fport == fport &&
+ 				pcbp->inp_lport == lport)
+ 			{
+@@ -184,8 +184,8 @@
+ 			}
+ 		}
+ 
+-		if (pcbp->inp_faddr.s_addr == faddr->s_addr &&
+-			pcbp->inp_laddr.s_addr == laddr->s_addr &&
++		if (pcbp->inp_faddr.s_addr == SIN4(faddr)->sin_addr.s_addr &&
++			pcbp->inp_laddr.s_addr == SIN4(laddr)->sin_addr.s_addr &&
+ 			pcbp->inp_fport == fport &&
+ 			pcbp->inp_lport == lport)
+ 		{
+@@ -199,16 +199,33 @@
+ 
+ #else
+ 
+-static struct socket *getlist4(	void *arg,
++static struct socket *getlist(	void *arg,
+ 								in_port_t lport,
+ 								in_port_t fport,
+-								const struct in_addr *laddr,
+-								const struct in_addr *faddr)
++								const struct sockaddr *local,
++								const struct sockaddr *remote)
+ {
+ 	struct inpcb *head, pcbp;
+ 	struct inpcbhead *pcbhead = arg;
++	char *faddr, *laddr, *pfaddr, *pladdr;
++	int alen;
+ 
+-	(void) laddr;
++	if (remote->sa_family != local->sa_family)
++		return (NULL);
++	switch (remote->sa_family) {
++	case AF_INET:
++		faddr = (char *)&SIN4(remote)->sin_addr;
++		laddr = (char *)&SIN4(local)->sin_addr;
++		break;
++#ifdef INP_IPV6
++	case AF_INET6:
++		faddr = (char *)&SIN6(remote)->sin6_addr;
++		laddr = (char *)&SIN6(local)->sin6_addr;
++		break;
++#endif
++	default:
++		return (NULL);
++	}
+ 
+ 	head = pcbhead->lh_first;
+ 	if (head == NULL)
+@@ -218,9 +235,9 @@
+ 		if (getbuf((u_long) head, &pcbp, sizeof(struct inpcb)) == -1)
+ 			break;
+ 
+-		if (opt_enabled(PROXY)) {
+-			if (faddr->s_addr == SIN4(&proxy)->sin_addr.s_addr &&
+-				laddr->s_addr != SIN4(&proxy)->sin_addr.s_addr &&
++		if (opt_enabled(PROXY) && remote->sa_family == AF_INET) {
++			if (SIN4(remote)->sin_addr.s_addr == SIN4(&proxy)->sin_addr.s_addr &&
++				SIN4(local)->sin_addr.s_addr != SIN4(&proxy)->sin_addr.s_addr &&
+ 				pcbp.inp_fport == fport &&
+ 				pcbp.inp_lport == lport)
+ 			{
+@@ -228,8 +245,32 @@
+ 			}
+ 		}
+ 
+-		if (pcbp.inp_faddr.s_addr == faddr->s_addr &&
+-			pcbp.inp_laddr.s_addr == laddr->s_addr &&
++#ifdef INP_IPV6
++		if (pcbp.inp_vflag & INP_IPV4)
++		{
++			if (remote->sa_family != AF_INET)
++				continue;
++			pfaddr = (char *)&pcbp.inp_faddr;
++			pladdr = (char *)&pcbp.inp_laddr;
++			alen = sizeof(struct in_addr);
++		}
++		else if (pcbp.inp_vflag & INP_IPV6)
++		{
++			if (remote->sa_family != AF_INET6)
++				continue;
++			pfaddr = (char *)&pcbp.in6p_faddr;
++			pladdr = (char *)&pcbp.in6p_laddr;
++			alen = sizeof(struct in6_addr);
++		}
++		else
++			continue;
++#else
++		pfaddr = (char *)&pcbp.inp_faddr;
++		pladdr = (char *)&pcbp.inp_laddr;
++		alen = sizeof(struct in_addr);
++#endif
++		if (memcmp(pfaddr, faddr, alen) == 0 &&
++			memcmp(pladdr, laddr, alen) == 0 &&
+ 			pcbp.inp_fport == fport &&
+ 			pcbp.inp_lport == lport)
+ 		{
+@@ -248,7 +289,7 @@
+ ** Return the UID of the connection owner
+ */
+ 
+-int get_user4(	in_port_t lport,
++static int get_user(	in_port_t lport,
+ 				in_port_t fport,
+ 				struct sockaddr_storage *laddr,
+ 				struct sockaddr_storage *faddr)
+@@ -276,8 +317,9 @@
+ 	tcb.inp_prev = (struct inpcb *) kinfo->nl[N_TCB].n_value;
+ #endif
+ 
+-	sockp = getlist4(&tcb, lport, fport,
+-				&SIN4(laddr)->sin_addr, &SIN4(faddr)->sin_addr);
++	sockp = getlist(&tcb, lport, fport,
++				(struct sockaddr *)laddr,
++				(struct sockaddr *)faddr);
+ 
+ 	if (sockp == NULL)
+ 		return (-1);
+@@ -346,6 +388,14 @@
+ 	return (-1);
+ }
+ 
++int get_user4(	in_port_t lport,
++				in_port_t fport,
++				struct sockaddr_storage *laddr,
++				struct sockaddr_storage *faddr)
++{
++	return (get_user(lport, fport, laddr, faddr));
++}
++
+ #ifdef MASQ_SUPPORT
+ 
+ /*
+@@ -456,36 +506,7 @@
+ 				struct sockaddr_storage *laddr,
+ 				struct sockaddr_storage *faddr)
+ {
+-	struct ucred ucred;
+-	struct sockaddr_in6 sin6[2];
+-	int len;
+-	int ret;
+-
+-	len = sizeof(struct ucred);
+-
+-	memset(sin6, 0, sizeof(sin6));
+-
+-	sin6[0].sin6_len = sizeof(struct sockaddr_in6);
+-	sin6[0].sin6_family = AF_INET6;
+-	sin6[0].sin6_port = lport;
+-	memcpy(&sin6[0].sin6_addr, &SIN6(laddr)->sin6_addr,
+-		sizeof(sin6[0].sin6_addr));
+-
+-	sin6[1].sin6_len = sizeof(struct sockaddr_in6);
+-	sin6[1].sin6_family = AF_INET6;
+-	sin6[1].sin6_port = fport;
+-	memcpy(&sin6[1].sin6_addr, &SIN6(faddr)->sin6_addr,
+-		sizeof(sin6[1].sin6_addr));
+-
+-	ret = sysctlbyname("net.inet6.tcp6.getcred",
+-			&ucred, &len, sin6, sizeof(sin6));
+-
+-	if (ret == -1) {
+-		debug("sysctlbyname: %s", strerror(errno));
+-		return (-1);
+-	}
+-
+-	return (ucred.cr_uid);
++	return (get_user(lport, fport, laddr, faddr));
+ }
+ 
+ #endif
+diff -ru src.old/kernel/freebsd5.c src/kernel/freebsd5.c
+--- src.old/kernel/freebsd5.c	Sat Mar 20 20:36:51 2004
++++ src/kernel/freebsd5.c	Sat Mar 20 20:37:13 2004
+@@ -160,11 +160,11 @@
+ 
+ #ifdef _HAVE_OLD_INPCB
+ 
+-static struct socket *getlist4(	void *arg,
++static struct socket *getlist(	void *arg,
+ 								in_port_t lport,
+ 								in_port_t fport,
+-								const struct in_addr *laddr,
+-								const struct in_addr *faddr)
++								const struct sockaddr *laddr,
++								const struct sockaddr *faddr)
+ {
+ 	struct inpcb *pcbp = arg;
+ 	struct inpcb *head;
+@@ -176,8 +176,8 @@
+ 
+ 	do {
+ 		if (opt_enabled(PROXY)) {
+-			if (faddr->s_addr == SIN4(&proxy)->sin_addr.s_addr &&
+-				laddr->s_addr != SIN4(&proxy)->sin_addr.s_addr &&
++			if (SIN4(faddr)->sin_addr.s_addr == SIN4(&proxy)->sin_addr.s_addr &&
++				SIN4(laddr)->sin_addr.s_addr != SIN4(&proxy)->sin_addr.s_addr &&
+ 				pcbp->inp_fport == fport &&
+ 				pcbp->inp_lport == lport)
+ 			{
+@@ -185,8 +185,8 @@
+ 			}
+ 		}
+ 
+-		if (pcbp->inp_faddr.s_addr == faddr->s_addr &&
+-			pcbp->inp_laddr.s_addr == laddr->s_addr &&
++		if (pcbp->inp_faddr.s_addr == SIN4(faddr)->sin_addr.s_addr &&
++			pcbp->inp_laddr.s_addr == SIN4(laddr)->sin_addr.s_addr &&
+ 			pcbp->inp_fport == fport &&
+ 			pcbp->inp_lport == lport)
+ 		{
+@@ -200,16 +200,31 @@
+ 
+ #else
+ 
+-static struct socket *getlist4(	void *arg,
++static struct socket *getlist(	void *arg,
+ 								in_port_t lport,
+ 								in_port_t fport,
+-								const struct in_addr *laddr,
+-								const struct in_addr *faddr)
++								const struct sockaddr *local,
++								const struct sockaddr *remote)
+ {
+ 	struct inpcb *head, pcbp;
+ 	struct inpcbhead *pcbhead = arg;
++	char *faddr, *laddr, *pfaddr, *pladdr;
++	int alen;
+ 
+-	(void) laddr;
++	if (remote->sa_family != local->sa_family)
++		return (NULL);
++	switch (remote->sa_family) {
++	case AF_INET:
++		faddr = (char *)&SIN4(remote)->sin_addr;
++		laddr = (char *)&SIN4(local)->sin_addr;
++		break;
++	case AF_INET6:
++		faddr = (char *)&SIN6(remote)->sin6_addr;
++		laddr = (char *)&SIN6(local)->sin6_addr;
++		break;
++	default:
++		return (NULL);
++	}
+ 
+ 	head = pcbhead->lh_first;
+ 	if (head == NULL)
+@@ -219,9 +234,9 @@
+ 		if (getbuf((u_long) head, &pcbp, sizeof(struct inpcb)) == -1)
+ 			break;
+ 
+-		if (opt_enabled(PROXY)) {
+-			if (faddr->s_addr == SIN4(&proxy)->sin_addr.s_addr &&
+-				laddr->s_addr != SIN4(&proxy)->sin_addr.s_addr &&
++		if (opt_enabled(PROXY) && remote->sa_family == AF_INET) {
++			if (SIN4(remote)->sin_addr.s_addr == SIN4(&proxy)->sin_addr.s_addr &&
++				SIN4(local)->sin_addr.s_addr != SIN4(&proxy)->sin_addr.s_addr &&
+ 				pcbp.inp_fport == fport &&
+ 				pcbp.inp_lport == lport)
+ 			{
+@@ -229,8 +244,26 @@
+ 			}
+ 		}
+ 
+-		if (pcbp.inp_faddr.s_addr == faddr->s_addr &&
+-			pcbp.inp_laddr.s_addr == laddr->s_addr &&
++		if (pcbp.inp_vflag & INP_IPV4)
++		{
++			if (remote->sa_family != AF_INET)
++				continue;
++			pfaddr = (char *)&pcbp.inp_faddr;
++			pladdr = (char *)&pcbp.inp_laddr;
++			alen = sizeof(struct in_addr);
++		}
++		else if (pcbp.inp_vflag & INP_IPV6)
++		{
++			if (remote->sa_family != AF_INET6)
++				continue;
++			pfaddr = (char *)&pcbp.in6p_faddr;
++			pladdr = (char *)&pcbp.in6p_laddr;
++			alen = sizeof(struct in6_addr);
++		}
++		else
++			continue;
++		if (memcmp(pfaddr, faddr, alen) == 0 &&
++			memcmp(pladdr, laddr, alen) == 0 &&
+ 			pcbp.inp_fport == fport &&
+ 			pcbp.inp_lport == lport)
+ 		{
+@@ -249,7 +282,7 @@
+ ** Return the UID of the connection owner
+ */
+ 
+-int get_user4(	in_port_t lport,
++static int get_user(	in_port_t lport,
+ 				in_port_t fport,
+ 				struct sockaddr_storage *laddr,
+ 				struct sockaddr_storage *faddr)
+@@ -276,8 +309,9 @@
+ 	tcb.inp_prev = (struct inpcb *) kinfo->nl[N_TCB].n_value;
+ #endif
+ 
+-	sockp = getlist4(&tcb, lport, fport,
+-				&SIN4(laddr)->sin_addr, &SIN4(faddr)->sin_addr);
++	sockp = getlist(&tcb, lport, fport,
++				(struct sockaddr *)laddr,
++				(struct sockaddr *)faddr);
+ 
+ 	if (sockp == NULL)
+ 		return (-1);
+@@ -338,6 +372,14 @@
+ 	return (-1);
+ }
+ 
++int get_user4(	in_port_t lport,
++				in_port_t fport,
++				struct sockaddr_storage *laddr,
++				struct sockaddr_storage *faddr)
++{
++	return (get_user(lport, fport, laddr, faddr));
++}
++
+ #ifdef MASQ_SUPPORT
+ 
+ /*
+@@ -448,36 +490,7 @@
+ 				struct sockaddr_storage *laddr,
+ 				struct sockaddr_storage *faddr)
+ {
+-	struct ucred ucred;
+-	struct sockaddr_in6 sin6[2];
+-	int len;
+-	int ret;
+-
+-	len = sizeof(struct ucred);
+-
+-	memset(sin6, 0, sizeof(sin6));
+-
+-	sin6[0].sin6_len = sizeof(struct sockaddr_in6);
+-	sin6[0].sin6_family = AF_INET6;
+-	sin6[0].sin6_port = lport;
+-	memcpy(&sin6[0].sin6_addr, &SIN6(laddr)->sin6_addr,
+-		sizeof(sin6[0].sin6_addr));
+-
+-	sin6[1].sin6_len = sizeof(struct sockaddr_in6);
+-	sin6[1].sin6_family = AF_INET6;
+-	sin6[1].sin6_port = fport;
+-	memcpy(&sin6[1].sin6_addr, &SIN6(faddr)->sin6_addr,
+-		sizeof(sin6[1].sin6_addr));
+-
+-	ret = sysctlbyname("net.inet6.tcp6.getcred",
+-			&ucred, &len, sin6, sizeof(sin6));
+-
+-	if (ret == -1) {
+-		debug("sysctlbyname: %s", strerror(errno));
+-		return (-1);
+-	}
+-
+-	return (ucred.cr_uid);
++	return (get_user(lport, fport, laddr, faddr));
+ }
+ 
+ #endif
--- oidentd.patch ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200403212009.i2LK9OSh019098>