From venglin@freebsd.lublin.pl  Wed Apr 11 23:55:17 2001
Return-Path: <venglin@freebsd.lublin.pl>
Received: from yeti.ismedia.pl (yeti.ismedia.pl [212.182.96.18])
	by hub.freebsd.org (Postfix) with SMTP id E783F37B423
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 11 Apr 2001 23:55:10 -0700 (PDT)
	(envelope-from venglin@freebsd.lublin.pl)
Received: (qmail 78682 invoked from network); 12 Apr 2001 06:55:08 -0000
Received: from unknown (HELO lagoon.freebsd.lublin.pl) (212.182.115.11)
  by 0 with SMTP; 12 Apr 2001 06:55:08 -0000
Received: (qmail 11999 invoked from network); 12 Apr 2001 06:55:07 -0000
Received: from unknown (HELO riget.scene.pl) (212.182.115.11)
  by 0 with SMTP; 12 Apr 2001 06:55:07 -0000
Received: (qmail 11995 invoked by uid 1001); 12 Apr 2001 06:55:06 -0000
Message-Id: <20010412065506.11994.qmail@riget.scene.pl>
Date: 12 Apr 2001 06:55:06 -0000
From: venglin@freebsd.lublin.pl
Reply-To: venglin@freebsd.lublin.pl
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: sendto() syscall returns EINVAL in jail environment
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         26506
>Category:       kern
>Synopsis:       [patch] sendto() syscall returns EINVAL in jail environment
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    glebius
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 12 00:00:09 PDT 2001
>Closed-Date:    Sun Mar 13 16:05:24 GMT 2005
>Last-Modified:  Sun Mar 13 16:05:24 GMT 2005
>Originator:     Przemyslaw Frasunek
>Release:        FreeBSD 4.3-RC i386
>Organization:
czuby.net
>Environment:
System: FreeBSD riget.scene.pl 4.3-RC FreeBSD 4.3-RC #0: Wed Apr 11 18:05:48 CEST 2001 venglin@riget.scene.pl:/mnt/lagoon/usr/src/sys/compile/RIGET i386

>Description:

	sendto() syscall return sometimes EINVAL in jail environment after
	upgrade from 4.2-STABLE (as of 22 Feb 2001) to 4.3-RC (as of 11 Apr
	2001).

	On 4.2-STABLE everything works good.

>How-To-Repeat:

	Run squid in jail enviroment, look at logs, run truss.

sendto(0x5,0x87c0400,0x1f,0x0,0x81f84c0,0x10)	 ERR#22 'Invalid argument'
sendto(0x5,0x87c0400,0x1f,0x0,0x81f84dc,0x10)	 ERR#22 'Invalid argument'
sendto(0x5,0x87c0800,0x1f,0x0,0x81f84c0,0x10)	 ERR#22 'Invalid argument'
sendto(0x5,0x87c0800,0x1f,0x0,0x81f84dc,0x10)	 ERR#22 'Invalid argument'

2001/04/12 08:03:26| comm_udp_sendto: FD 5, 212.182.115.2, port 53: (22) Invalid argument
2001/04/12 08:03:26| idnsSendQuery: FD 5: sendto: (22) Invalid argument

>Fix:

	Unknown.
>Release-Note:
>Audit-Trail:

From: "Cyril A. Vechera" <cyril@piter.net>
To: <freebsd-gnats-submit@FreeBSD.org>, <venglin@freebsd.lublin.pl>
Cc:  
Subject: Re: kern/26506: sendto() syscall returns EINVAL in jail environment
Date: Tue, 8 May 2001 18:03:51 +0400

 Problem has been solved.
 
 *** in_pcb.c.orig       Tue Mar 13 01:10:51 2001
 --- in_pcb.c    Tue May  8 17:00:21 2001
 ***************
 *** 485,499 ****
         struct sockaddr_in sa;
         int error;
 
 -       if (inp->inp_laddr.s_addr == INADDR_ANY && p->p_prison != NULL) {
 -               bzero(&sa, sizeof (sa));
 -               sa.sin_addr.s_addr = htonl(p->p_prison->pr_ip);
 -               sa.sin_len=sizeof (sa);
 -               sa.sin_family = AF_INET;
 -               error = in_pcbbind(inp, (struct sockaddr *)&sa, p);
 -               if (error)
 -                       return (error);
 -       }
         /*
          *   Call inner routine, to assign local interface address.
          */
 --- 485,490 ----
 ***************
 *** 507,513 ****
         }
         if (inp->inp_laddr.s_addr == INADDR_ANY) {
                 if (inp->inp_lport == 0) {
 !                       error = in_pcbbind(inp, (struct sockaddr *)0, p);
                         if (error)
                             return (error);
                 }
 --- 498,509 ----
         }
         if (inp->inp_laddr.s_addr == INADDR_ANY) {
                 if (inp->inp_lport == 0) {
 !                       bzero(&sa, sizeof (sa));
 !                       if (p->p_prison )
 !                               sa.sin_addr.s_addr =
 htonl(p->p_prison->pr_ip);
 !                       sa.sin_len = sizeof (sa);
 !                       sa.sin_family = AF_INET;
 !                       error = in_pcbbind(inp, (struct sockaddr *)&sa, p);
                         if (error)
                             return (error);
 
 
 
 
 

From: "Cyril A. Vechera" <cyril@piter.net>
To: <freebsd-gnats-submit@FreeBSD.org>, <venglin@freebsd.lublin.pl>
Cc:  
Subject: Re: kern/26506: sendto() syscall returns EINVAL in jail environment
Date: Wed, 9 May 2001 16:35:30 +0400

 Sorry, previous patch produces a little performance leak.
 Please, attend to this.
 
 *** in_pcb.c.orig       Tue Mar 13 01:10:51 2001
 --- in_pcb.c    Wed May  9 16:36:13 2001
 ***************
 *** 485,499 ****
         struct sockaddr_in sa;
         int error;
 
 -       if (inp->inp_laddr.s_addr == INADDR_ANY && p->p_prison != NULL) {
 -               bzero(&sa, sizeof (sa));
 -               sa.sin_addr.s_addr = htonl(p->p_prison->pr_ip);
 -               sa.sin_len=sizeof (sa);
 -               sa.sin_family = AF_INET;
 -               error = in_pcbbind(inp, (struct sockaddr *)&sa, p);
 -               if (error)
 -                       return (error);
 -       }
         /*
          *   Call inner routine, to assign local interface address.
          */
 --- 485,490 ----
 ***************
 *** 507,513 ****
         }
         if (inp->inp_laddr.s_addr == INADDR_ANY) {
                 if (inp->inp_lport == 0) {
 !                       error = in_pcbbind(inp, (struct sockaddr *)0, p);
                         if (error)
                             return (error);
                 }
 --- 498,511 ----
         }
         if (inp->inp_laddr.s_addr == INADDR_ANY) {
                 if (inp->inp_lport == 0) {
 !                       if (p->p_prison ) {
 !                               bzero(&sa, sizeof (sa));
 !                               sa.sin_addr.s_addr =
 htonl(p->p_prison->pr_ip);
 !                               sa.sin_len = sizeof (sa);
 !                               sa.sin_family = AF_INET;
 !                               error = in_pcbbind(inp, (struct sockaddr
 *)&sa, p);
 !                       } else
 !                               error = in_pcbbind(inp, (struct sockaddr
 *)0, p);
                         if (error)
                             return (error);
                 }
 
 
 

From: Przemyslaw Frasunek <venglin@freebsd.lublin.pl>
To: freebsd-gnats-submit@freebsd.org
Cc:  
Subject: Re: kern/26506: sendto() syscall returns EINVAL in jail environment
Date: Tue, 5 Mar 2002 16:46:39 +0100

 This problem still persists on 4.5-STABLE. When patch from audit-trail (sent
 almost year ago) will be commited?
 
 This works for me on recent 4.5-STABLE:
 
 --- /disc1/jail2/home/venglin/in_pcb.c  Tue Mar  5 16:36:17 2002
 +++ in_pcb.c    Tue Mar  5 16:24:35 2002
 @@ -499,7 +499,7 @@
         struct sockaddr_in *sin = (struct sockaddr_in *)nam;
         struct sockaddr_in sa;
         int error;
 -
 +/*
         if (inp->inp_laddr.s_addr == INADDR_ANY && p->p_prison != NULL) {
                 bzero(&sa, sizeof (sa));
                 sa.sin_addr.s_addr = htonl(p->p_prison->pr_ip);
 @@ -509,6 +509,7 @@
                 if (error)
                         return (error);
         }
 +*/
         /*
          *   Call inner routine, to assign local interface address.
          */
 @@ -522,9 +523,16 @@
         }
         if (inp->inp_laddr.s_addr == INADDR_ANY) {
                 if (inp->inp_lport == 0) {
 -                       error = in_pcbbind(inp, (struct sockaddr *)0, p);
          */
 @@ -522,9 +523,16 @@
         }
         if (inp->inp_laddr.s_addr == INADDR_ANY) {
                 if (inp->inp_lport == 0) {
 -                       error = in_pcbbind(inp, (struct sockaddr *)0, p);
 -                       if (error)
 -                           return (error);
 +                               if (p->p_prison ) {
 +                                       bzero(&sa, sizeof (sa));
 +                                       sa.sin_addr.s_addr = htonl(p->p_prison->pr_ip);
 +                                       sa.sin_len = sizeof (sa);
 +                                       sa.sin_family = AF_INET;
 +                                       error = in_pcbbind(inp, (struct sockaddr *)&sa, p);
 +                               } else
 +                                       error = in_pcbbind(inp, (struct sockaddr *)0, p);
 +                               if (error)
 +                                       return (error);
                 }
                 inp->inp_laddr = ifaddr->sin_addr;
         }
 
 -- 
 * Fido: 2:480/124 ** WWW: http://www.frasunek.com/ ** NIC-HDL: PMF9-RIPE *
 * Inet: przemyslaw@frasunek.com ** PGP: D48684904685DF43EA93AFA13BE170BF *
Responsible-Changed-From-To: freebsd-bugs->phk 
Responsible-Changed-By: green 
Responsible-Changed-When: Thu Jun 20 10:21:41 PDT 2002 
Responsible-Changed-Why:  
This looks to be correct, but I'll give phk final review for deweirding 
this bug, since he is responsible for jail. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=26506 

From: Lamont Granquist <lamont@scriptkiddie.org>
To: freebsd-gnats-submit@FreeBSD.org, venglin@freebsd.lublin.pl
Cc:  
Subject: Re: kern/26506: sendto() syscall returns EINVAL in jail environment
Date: Sun, 05 Jan 2003 15:41:32 -0800

 I've got a suggested two line patch for this here:
 
 http://docs.freebsd.org/cgi/getmsg.cgi?fetch=75861+0+archive/2002/freebsd-hacke$
 
 There's also a discusion of the root cause of the problem here:
 
 http://docs.freebsd.org/cgi/getmsg.cgi?fetch=79811+0+archive/2002/freebsd-hacke$
 
 I keep having people e-mailing me about this PR fairly frequently and 
 the people experiencing the problems have been having success with my 
 patch.
 
 

From: Oliver Eikemeier <eikemeier@fillmore-labs.com>
To: freebsd-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: kern/26506: sendto() syscall returns EINVAL in jail environment
Date: Mon, 28 Apr 2003 15:45:19 +0200

 Just a reminder:
 
 This bug is still not fixed in 4.8-STABLE. As a consequence port
 irc/ircd-hybrid does not work properly in a jail, see the discussion
 in thread "jail bug with ircd-hybrid in_pcbconnect()?" on freebsd-hackers:
 <http://groups.google.com/groups?th=4298e8dddbdc169a>
 
 The proposed patch from Lamont Granquist works for me and is in message
 "UDP jail bug patch (was Re: (PATCH) Re: jail bug with ircd-hybrid in_pcbconnect()?)"
 in freebsd-stable and freebsd-hackers:
 <http://www.freebsd.org/cgi/getmsg.cgi?fetch=75861+78220+/usr/local/www/db/text/2002/freebsd-hackers/20020331.freebsd-hackers>
 or
 <http://groups.google.com/groups?selm=20020325202752.P5308-100000%40coredump.scriptkiddie.org>
 
 --- in_pcb.c.patch begins here ---
 --- sys/netinet/in_pcb.c.orig	Fri Jan 24 06:11:33 2003
 +++ sys/netinet/in_pcb.c	Mon Mar 17 12:00:00 2003
 @@ -512,6 +512,8 @@
  	int error;
 
  	if (inp->inp_laddr.s_addr == INADDR_ANY && p->p_prison != NULL) {
 +		if (inp->inp_lport != 0)
 +			inp->inp_laddr.s_addr = htonl(p->p_prison->pr_ip);
  		bzero(&sa, sizeof (sa));
  		sa.sin_addr.s_addr = htonl(p->p_prison->pr_ip);
  		sa.sin_len=sizeof (sa);
 --- in_pcb.c.patch end here ---
 
 Regards
     Oliver
 
Responsible-Changed-From-To: phk->bugs 
Responsible-Changed-By: phk 
Responsible-Changed-When: Tue Jul 29 03:29:21 PDT 2003 
Responsible-Changed-Why:  
I do not have time to work on jail right now, sorry. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=26506 
Responsible-Changed-From-To: bugs->freebsd-bugs 
Responsible-Changed-By: arved 
Responsible-Changed-When: Mon Aug 4 11:19:14 PDT 2003 
Responsible-Changed-Why:  
Fix responsible 

http://www.freebsd.org/cgi/query-pr.cgi?pr=26506 

From: lupe@lupe-christoph.de (Lupe Christoph)
To: freebsd-gnats-submit@FreeBSD.org
Cc: venglin@freebsd.lublin.pl
Subject: Re: kern/26506: sendto() syscall returns EINVAL in jail environment
Date: Sun, 14 Sep 2003 15:33:10 +0200

 The two-line patch does not work for snmpwalk. It fails on the *second*
 invocation of sendto(), with or without the patch:
 
 275   socket(PF_INET, SOCK_DGRAM, IPPROTO_IP) = 6
 275   setsockopt(6, SOL_SOCKET, SO_SNDBUF, [131072], 4) = 0
 275   setsockopt(6, SOL_SOCKET, SO_RCVBUF, [131072], 4) = 0
 275   sendto(6, "0&\2\1\0\4\6public\241\31\2\4NE\335\376\2\1\0\2\1\0000"..., 40, 0, {sa_family=AF_INET, sin_port=htons(161), sin_addr=inet_addr("172.17.0.7")}, 16) = 40   
 275   gettimeofday({1063545390, 64920}, NULL) = 0   
 275   gettimeofday({1063545390, 65344}, NULL) = 0
 275   select(7, [6], NULL, NULL, {0, 999576}) = 1 (in [6])
 275   break(0x809b000)                  = 0
 275   recvfrom(6, "0\201\200\2\1\0\4\6public\242s\2\4NE\335\376\2\1\0\2\1"..., 65536, 0, {sa_family=AF_INET, sin_port=htons(161), sin_addr=inet_addr("172.17.0.8")}, [16]) = 131
 275   fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(5, 0), ...}) = 0
 275   ioctl(1, TIOCGETA, {B38400 opost isig icanon echo ...}) = 0
 275   write(1, "SNMPv2-MIB::sysDescr.0 = STRING:"..., 121) = 121
 275   sendto(6, "0)\2\1\0\4\6public\241\34\2\4NE\335\377\2\1\0\2\1\0000"..., 43, 0, {sa_family=AF_INET, sin_port=htons(161), sin_addr=inet_addr("172.17.0.7")}, 16) = -1 EINVAL (Invalid argument)
 275   write(2, "snmpwalk: Failure in sendto (Inv"..., 47) = 47
 275   close(6)                          = 0
 275   exit(1)                           = ?
 
 This is on 4.8-RELEASE-p4. Przemyslaw Frasunek's patch for 4.5-STABLE
 does not apply to 4.8-STABLE, so I can't check if that method works.
 It's possible this problem is caused by something else, anyway.
 -- 
 | lupe@lupe-christoph.de       |           http://www.lupe-christoph.de/ |
 | "Violence is the resort of the violent" Lu Tze                         |
 | "Thief of Time", Terry Pratchett                                       |

From: Vincent Tougait <viny@scientiae.net>
To: freebsd-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: kern/26506: [patch] sendto() syscall returns EINVAL in jail
	environment
Date: Fri, 26 Nov 2004 16:19:07 +0100

 --=-2uyUitBh9ScHvfaIOLS/
 Content-Type: text/plain
 Content-Transfer-Encoding: 7bit
 
 I had the same problem on a FreeBSD 5.3-BETA4. An ircd wouldn't resolve
 IPs as DNS requests would fail, sendto() returning EINVAL. As available
 patches didn't apply to 5.X, I did some search and I eventually found
 that it came from a test in src/sys/netinet/in_pcb.c, in function
 in_pcbbind_setup(inp, nam, laddrp, lportp, cred) :
 
 if (sin->sin_port != *lportp) {
 	/* Don't allow the port to change. */
 	if (*lportp != 0)
 		return (EINVAL);
 	lport = sin->sin_port;
 }
 /* NB: lport is left as 0 if the port isn't being changed. */
 
 For some reason, *lportp isn't null. By looking a little further, it
 seems that in_pcbbind_setup() is called by udp_output(inp, m, addr,
 control, td) in src/sys/netinet/udp_usrreq.c.
 
 if (lport == 0) {
 	error = EINVAL;
 	goto release;
 }
 error = in_pcbbind_setup(inp, (struct sockaddr *)&src,
     &laddr.s_addr, &lport, td->td_ucred);
 
 So just before the call, there is a test which returns EINVAL if lport
 is null. Then in_pcbbind_setup() is called with lport as value, which is
 not null (else it would return EINVAL there). As nothing seems to affect
 *lportp in in_pcbbind_setup(), *lportp is still not null when the second
 test occurs and it returns EINVAL.
 
 By commenting the test in in_pcbbind_setup (diff attached), I was able
 to make my ircd work. I didn't see any problems since, but I'm not
 really sure I did the best thing.
 
 --=-2uyUitBh9ScHvfaIOLS/
 Content-Disposition: attachment; filename=patch-in_pcb.c
 Content-Type: text/x-patch; name=patch-in_pcb.c; charset=iso8859-1
 Content-Transfer-Encoding: 7bit
 
 Index: src/sys/netinet/in_pcb.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v
 retrieving revision 1.156
 diff -r1.156 in_pcb.c
 296,298d295
 < 			/* Don't allow the port to change. */
 < 			if (*lportp != 0)
 < 				return (EINVAL);
 
 --=-2uyUitBh9ScHvfaIOLS/--
 

From: Vincent Tougait <viny@FreeBSD.org>
To: freebsd-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: kern/26506: [patch] sendto() syscall returns EINVAL in jail
	environment
Date: Fri, 26 Nov 2004 16:08:58 +0100

 --=-aS4TsxR2BDyHbb2JfPNf
 Content-Type: text/plain
 Content-Transfer-Encoding: 7bit
 
 I had the same problem on a FreeBSD 5.3-BETA4. An ircd wouldn't resolve
 IPs as DNS requests would fail, sendto() returning EINVAL. As available
 patches didn't apply to 5.X, I did some search and I eventually found
 that it came from a test in src/sys/netinet/in_pcb.c, in function
 in_pcbbind_setup(inp, nam, laddrp, lportp, cred) :
 
 if (sin->sin_port != *lportp) {
 	/* Don't allow the port to change. */
 	if (*lportp != 0)
 		return (EINVAL);
 	lport = sin->sin_port;
 }
 /* NB: lport is left as 0 if the port isn't being changed. */
 
 For some reason, *lportp isn't null. By looking a little further, it
 seems that in_pcbbind_setup() is called by udp_output(inp, m, addr,
 control, td) in src/sys/netinet/udp_usrreq.c.
 
 if (lport == 0) {
 	error = EINVAL;
 	goto release;
 }
 error = in_pcbbind_setup(inp, (struct sockaddr *)&src,
     &laddr.s_addr, &lport, td->td_ucred);
 
 So just before the call, there is a test which returns EINVAL if lport
 is null. Then in_pcbbind_setup() is called with lport as value, which is
 not null (else it would return EINVAL there). As nothing seems to affect
 *lportp in in_pcbbind_setup(), *lportp is still not null when the second
 test occurs and it returns EINVAL.
 
 By commenting the test in in_pcbbind_setup (diff attached), I was able
 to make my ircd work. I didn't see any problems since, but I'm not
 really sure I did the best thing.
 
 --=-aS4TsxR2BDyHbb2JfPNf
 Content-Disposition: attachment; filename=patch-in_pcb.c
 Content-Type: text/x-patch; name=patch-in_pcb.c; charset=iso8859-1
 Content-Transfer-Encoding: 7bit
 
 Index: src/sys/netinet/in_pcb.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v
 retrieving revision 1.156
 diff -r1.156 in_pcb.c
 296,298d295
 < 			/* Don't allow the port to change. */
 < 			if (*lportp != 0)
 < 				return (EINVAL);
 
 --=-aS4TsxR2BDyHbb2JfPNf--
 

From: Vincent Tougait <viny@scientiae.net>
To: freebsd-gnats-submit@FreeBSD.org, venglin@freebsd.lublin.pl
Cc:  
Subject: Re: kern/26506: [patch] sendto() syscall returns EINVAL in jail
	environment
Date: Fri, 26 Nov 2004 16:03:37 +0100

 --=-JpRQDeCU6X8jdrA6D5HV
 Content-Type: text/plain
 Content-Transfer-Encoding: 7bit
 
 I had the same problem on a FreeBSD 5.3-BETA4. An ircd wouldn't resolve
 IPs as DNS requests would fail, sendto() returning EINVAL. As available
 patches didn't apply to 5.X, I did some search and I eventually found
 that it came from a test in src/sys/netinet/in_pcb.c, in function
 in_pcbbind_setup(inp, nam, laddrp, lportp, cred) :
 
 if (sin->sin_port != *lportp) {
 	/* Don't allow the port to change. */
 	if (*lportp != 0)
 		return (EINVAL);
 	lport = sin->sin_port;
 }
 /* NB: lport is left as 0 if the port isn't being changed. */
 
 For some reason, *lportp isn't null. By looking a little further, it
 seems that in_pcbbind_setup() is called by udp_output(inp, m, addr,
 control, td) in src/sys/netinet/udp_usrreq.c.
 
 if (lport == 0) {
 	error = EINVAL;
 	goto release;
 }
 error = in_pcbbind_setup(inp, (struct sockaddr *)&src,
     &laddr.s_addr, &lport, td->td_ucred);
 
 So just before the call, there is a test which returns EINVAL if lport
 is null. Then in_pcbbind_setup() is called with lport as value, which is
 not null (else it would return EINVAL there). As nothing seems to affect
 *lportp in in_pcbbind_setup(), *lportp is still not null when the second
 test occurs and it returns EINVAL.
 
 By commenting the test in in_pcbbind_setup (diff attached), I was able
 to make my ircd work. I didn't see any problems since, but I'm not
 really sure I did the best thing.
 
 --=-JpRQDeCU6X8jdrA6D5HV
 Content-Disposition: attachment; filename=patch-in_pcb.c
 Content-Type: text/x-patch; name=patch-in_pcb.c; charset=iso8859-1
 Content-Transfer-Encoding: 7bit
 
 Index: src/sys/netinet/in_pcb.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v
 retrieving revision 1.156
 diff -r1.156 in_pcb.c
 296,298d295
 < 			/* Don't allow the port to change. */
 < 			if (*lportp != 0)
 < 				return (EINVAL);
 
 --=-JpRQDeCU6X8jdrA6D5HV--
 

From: Jared Mauch <jared@puck.nether.net>
To: freebsd-gnats-submit@FreeBSD.org, venglin@freebsd.lublin.pl
Cc: Jared Mauch <jared@puck.nether.net>, robert@watson.org
Subject: Re: kern/26506: [patch] sendto() syscall returns EINVAL in jail environment
Date: Sat, 15 Jan 2005 22:33:57 -0500

 	I'm also seeing this behaviour in FreeBSD 5.3
 (EINVAL from within a Jail for SNMP)
 
 	Is anyone working on tracking this down, or should this
 just be closed/chalked up to a unfixable bug?
 
 	I can spend some time testing a fix/fixes to this issue..
 
 	- Jared
 
 -- 
 Jared Mauch  | pgp key available via finger from jared@puck.nether.net
 clue++;      | http://puck.nether.net/~jared/  My statements are only mine.
Responsible-Changed-From-To: freebsd-bugs->rwatson 
Responsible-Changed-By: rwatson 
Responsible-Changed-When: Sun Jan 16 12:24:48 GMT 2005 
Responsible-Changed-Why:  
Take ownership of this bug. 


http://www.freebsd.org/cgi/query-pr.cgi?pr=26506 

From: Gleb Smirnoff <glebius@freebsd.org>
To: freebsd-gnats-submit@freebsd.org
Cc:  
Subject: Re: kern/26506: [patch] sendto() syscall returns EINVAL in jail environment
Date: Mon, 21 Feb 2005 00:09:21 +0300

 Add this patch to Audit-Trail for public review. Works for me.
 Interested parties, please test.
 
 Index: udp_usrreq.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/netinet/udp_usrreq.c,v
 retrieving revision 1.171
 diff -u -r1.171 udp_usrreq.c
 --- udp_usrreq.c	7 Jan 2005 01:45:45 -0000	1.171
 +++ udp_usrreq.c	20 Feb 2005 19:39:59 -0000
 @@ -801,9 +801,10 @@
  		if (error)
  			goto release;
  
 -		/* Commit the local port if newly assigned. */
 +		/* Commit the local addr and port if newly assigned. */
  		if (inp->inp_laddr.s_addr == INADDR_ANY &&
  		    inp->inp_lport == 0) {
 +			inp->inp_laddr = laddr;
  			inp->inp_lport = lport;
  			if (in_pcbinshash(inp) != 0) {
  				inp->inp_lport = 0;
 
 -- 
 Totus tuus, Glebius.
 GLEBIUS-RIPN GLEB-RIPE

From: Gleb Smirnoff <glebius@freebsd.org>
To: Doug White <dwhite@gumbysoft.com>
Cc: Robert Watson <rwatson@freebsd.org>, dwhite@freebsd.org,
	jared@puck.nether.net, freebsd-gnats-submit@freebsd.org
Subject: Re: kern/26506
Date: Mon, 21 Feb 2005 12:18:29 +0300

 On Sun, Feb 20, 2005 at 02:30:34PM -0800, Doug White wrote:
 D> This patch appears to work.  I don't know if its correct or not, just that
 D> the previous behavior stops occuring after the patch is applied :-)
 
 There is a problem with it: if a non-jail multihomed host opens socket,
 and uses sendto() to send packets into different directions, this socket
 is bound to the interface which was used on first packet. This is incorrect.
 
 This patch allows binding to a particular address only for jail case. I'm
 not yet sure, that this solution is the best.
 
 Index: udp_usrreq.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/netinet/udp_usrreq.c,v
 retrieving revision 1.171
 diff -u -r1.171 udp_usrreq.c
 --- udp_usrreq.c	7 Jan 2005 01:45:45 -0000	1.171
 +++ udp_usrreq.c	21 Feb 2005 08:14:11 -0000
 @@ -804,6 +804,10 @@
  		/* Commit the local port if newly assigned. */
  		if (inp->inp_laddr.s_addr == INADDR_ANY &&
  		    inp->inp_lport == 0) {
 +			/* Remember addr if jailed, to prevent
 +			 * rebinding */
 +			if (jailed(inp->inp_socket->so_cred))
 +				inp->inp_laddr = laddr;
  			inp->inp_lport = lport;
  			if (in_pcbinshash(inp) != 0) {
  				inp->inp_lport = 0;
 -- 
 Totus tuus, Glebius.
 GLEBIUS-RIPN GLEB-RIPE

From: Jared Mauch <jared@puck.nether.net>
To: Gleb Smirnoff <glebius@freebsd.org>
Cc: Doug White <dwhite@gumbysoft.com>,
	Robert Watson <rwatson@freebsd.org>, dwhite@freebsd.org,
	jared@puck.nether.net, freebsd-gnats-submit@freebsd.org
Subject: Re: kern/26506
Date: Mon, 21 Feb 2005 15:55:18 -0500

 On Mon, Feb 21, 2005 at 12:18:29PM +0300, Gleb Smirnoff wrote:
 > On Sun, Feb 20, 2005 at 02:30:34PM -0800, Doug White wrote:
 > D> This patch appears to work.  I don't know if its correct or not, just that
 > D> the previous behavior stops occuring after the patch is applied :-)
 > 
 > There is a problem with it: if a non-jail multihomed host opens socket,
 > and uses sendto() to send packets into different directions, this socket
 > is bound to the interface which was used on first packet. This is incorrect.
 > 
 > This patch allows binding to a particular address only for jail case. I'm
 > not yet sure, that this solution is the best.
 
 	Patch seems to work in some quick testing here.
 
 	I'll do some longer lived tests shortly.
 
 	- jared
 
 -- 
 Jared Mauch  | pgp key available via finger from jared@puck.nether.net
 clue++;      | http://puck.nether.net/~jared/  My statements are only mine.
State-Changed-From-To: open->patched 
State-Changed-By: glebius 
State-Changed-When: Tue Feb 22 07:56:28 GMT 2005 
State-Changed-Why:  
Fixed in HEAD. 


Responsible-Changed-From-To: rwatson->glebius 
Responsible-Changed-By: glebius 
Responsible-Changed-When: Tue Feb 22 07:56:28 GMT 2005 
Responsible-Changed-Why:  
Blame me if any problems. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=26506 

From: Jared Mauch <jared@puck.nether.net>
To: Gleb Smirnoff <glebius@freebsd.org>
Cc: Doug White <dwhite@gumbysoft.com>,
	Robert Watson <rwatson@freebsd.org>, dwhite@freebsd.org,
	jared@puck.nether.net, freebsd-gnats-submit@freebsd.org
Subject: Re: kern/26506
Date: Tue, 22 Feb 2005 11:02:38 -0500

 On Mon, Feb 21, 2005 at 03:55:18PM -0500, Jared Mauch wrote:
 > On Mon, Feb 21, 2005 at 12:18:29PM +0300, Gleb Smirnoff wrote:
 > > On Sun, Feb 20, 2005 at 02:30:34PM -0800, Doug White wrote:
 > > D> This patch appears to work.  I don't know if its correct or not, just that
 > > D> the previous behavior stops occuring after the patch is applied :-)
 > > 
 > > There is a problem with it: if a non-jail multihomed host opens socket,
 > > and uses sendto() to send packets into different directions, this socket
 > > is bound to the interface which was used on first packet. This is incorrect.
 > > 
 > > This patch allows binding to a particular address only for jail case. I'm
 > > not yet sure, that this solution is the best.
 
 	Hopefully this won't cause too many issues in gnats (as
 the bug got flagged as patched), but i've had no problems after many hours.
 
 	This seems to be working nicely for my jailed host, including
 the ability to do large udp transactions (snmpbulkwalk).
 
 	Please let me know if you'd like me to perform any
 specific tests on my system, otherwise I do appreciate the effort in
 resolving this bug!
 
 	- Jared
 
 -- 
 Jared Mauch  | pgp key available via finger from jared@puck.nether.net
 clue++;      | http://puck.nether.net/~jared/  My statements are only mine.
State-Changed-From-To: patched->closed 
State-Changed-By: glebius 
State-Changed-When: Sun Mar 13 16:04:42 GMT 2005 
State-Changed-Why:  
Fix merged to RELENG_5 and will go into 5.4-RELEASE 

http://www.freebsd.org/cgi/query-pr.cgi?pr=26506 
>Unformatted:
