ports/64546: [patch] problems with ipv6 connections when running as non-root
Dariusz Kulinski
takeda3 at netzero.net
Sun Mar 21 20:10:18 UTC 2004
>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 at 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:
More information about the freebsd-ports-bugs
mailing list