From owner-freebsd-net@FreeBSD.ORG Tue Apr 9 11:58:34 2013 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 7D6945C4 for ; Tue, 9 Apr 2013 11:58:34 +0000 (UTC) (envelope-from prvs=18115ede16=killing@multiplay.co.uk) Received: from mail1.multiplay.co.uk (mail1.multiplay.co.uk [85.236.96.23]) by mx1.freebsd.org (Postfix) with ESMTP id 0E73F389 for ; Tue, 9 Apr 2013 11:58:33 +0000 (UTC) Received: from r2d2 ([46.65.172.4]) by mail1.multiplay.co.uk (mail1.multiplay.co.uk [85.236.96.23]) (MDaemon PRO v10.0.4) with ESMTP id md50003172461.msg for ; Tue, 09 Apr 2013 12:58:27 +0100 X-Spam-Processed: mail1.multiplay.co.uk, Tue, 09 Apr 2013 12:58:27 +0100 (not processed: message from valid local sender) X-MDDKIM-Result: neutral (mail1.multiplay.co.uk) X-MDRemoteIP: 46.65.172.4 X-Return-Path: prvs=18115ede16=killing@multiplay.co.uk X-Envelope-From: killing@multiplay.co.uk X-MDaemon-Deliver-To: freebsd-net@freebsd.org Message-ID: From: "Steven Hartland" To: Subject: Review of patch for raw packet source address selection under jails Date: Tue, 9 Apr 2013 12:58:33 +0100 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0E76_01CE3521.F1381360" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2900.5931 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Apr 2013 11:58:34 -0000 This is a multi-part message in MIME format. ------=_NextPart_000_0E76_01CE3521.F1381360 Content-Type: text/plain; format=flowed; charset="iso-8859-1"; reply-type=original Content-Transfer-Encoding: 7bit Currently source address selection for raw packets under jails uses prison_get_ip4 in the INADDR_ANY case. This can cause an invalid source address to be used, including using addresses which are unusable e.g. down interfaces un-routable addresses etc. I suspect this is a hang over from when jails where essentially single IP. The attached patch switches to use full resolution for raw packets via in_pcbladdr, which fixes this problem in all of our testing. Is this the correct path to take? Regards Steve ================================================ This e.mail is private and confidential between Multiplay (UK) Ltd. and the person or entity to whom it is addressed. In the event of misdirection, the recipient is prohibited from using, copying, printing or otherwise disseminating it or any information contained in it. In the event of misdirection, illegible or incomplete transmission please telephone +44 845 868 1337 or return the E.mail to postmaster@multiplay.co.uk. ------=_NextPart_000_0E76_01CE3521.F1381360 Content-Type: application/octet-stream; name="jail-raw-srcaddr.patch" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="jail-raw-srcaddr.patch" Fix jailed raw sockets not setting the correct source address by=0A= calling in_pcbladdr instead of prison_get_ip4=0A= --- sys/netinet/in_pcb.h.orig 2013-04-05 16:59:33.005670964 +0000=0A= +++ sys/netinet/in_pcb.h 2013-04-05 17:00:24.725266747 +0000=0A= @@ -490,6 +490,8 @@=0A= struct ucred *, int);=0A= int in_pcbbind_setup(struct inpcb *, struct sockaddr *, in_addr_t *,=0A= u_short *, struct ucred *);=0A= +int in_pcbladdr(struct inpcb *, struct in_addr *, struct in_addr *,=0A= + struct ucred *);=0A= int in_pcbconnect(struct inpcb *, struct sockaddr *, struct ucred *);=0A= int in_pcbconnect_setup(struct inpcb *, struct sockaddr *, in_addr_t *,=0A= u_short *, in_addr_t *, u_short *, struct inpcb **,=0A= --- sys/netinet/in_pcb.c.orig 2013-04-05 16:59:28.252798648 +0000=0A= +++ sys/netinet/in_pcb.c 2013-04-05 16:59:38.888509732 +0000=0A= @@ -596,7 +596,7 @@=0A= * Do proper source address selection on an unbound socket in case=0A= * of connect. Take jails into account as well.=0A= */=0A= -static int=0A= +int=0A= in_pcbladdr(struct inpcb *inp, struct in_addr *faddr, struct in_addr = *laddr,=0A= struct ucred *cred)=0A= {=0A= --- sys/netinet/raw_ip.c.orig 2013-04-05 16:44:24.458314711 +0000=0A= +++ sys/netinet/raw_ip.c 2013-04-05 17:10:54.902524046 +0000=0A= @@ -442,16 +442,16 @@=0A= ip->ip_p =3D inp->inp_ip_p;=0A= ip->ip_len =3D m->m_pkthdr.len;=0A= ip->ip_src =3D inp->inp_laddr;=0A= + ip->ip_dst.s_addr =3D dst;=0A= if (jailed(inp->inp_cred)) {=0A= /*=0A= * prison_local_ip4() would be good enough but would=0A= * let a source of INADDR_ANY pass, which we do not=0A= - * want to see from jails. We do not go through the=0A= - * pain of in_pcbladdr() for raw sockets.=0A= + * want to see from jails.=0A= */=0A= if (ip->ip_src.s_addr =3D=3D INADDR_ANY)=0A= - error =3D prison_get_ip4(inp->inp_cred,=0A= - &ip->ip_src);=0A= + error =3D in_pcbladdr(inp, &ip->ip_dst, &ip->ip_src,=0A= + inp->inp_cred);=0A= else=0A= error =3D prison_local_ip4(inp->inp_cred,=0A= &ip->ip_src);=0A= @@ -461,7 +461,6 @@=0A= return (error);=0A= }=0A= }=0A= - ip->ip_dst.s_addr =3D dst;=0A= ip->ip_ttl =3D inp->inp_ip_ttl;=0A= } else {=0A= if (m->m_pkthdr.len > IP_MAXPACKET) {=0A= ------=_NextPart_000_0E76_01CE3521.F1381360--