Subject: raw_ip.c has subtle bug
To: None <netbsd-bugs@NetBSD.ORG>
From: Perry E. Metzger <perry@imsi.com>
List: netbsd-bugs
Date: 02/26/1995 14:00:42
I believe the bug is still in NetBSD; its a two character fix. (Sorry
for not using send-pr; I'm not able to access my NetBSD machine at the
moment.)
.pm
Path: imsi.com!uunet!in1.uu.net!usc!howland.reston.ans.net!lamarck.sura.net!ra.nrl.navy.mil!danmcd
From: danmcd@sundance.itd.nrl.navy.mil (Dan McDonald)
Newsgroups: comp.bugs.4bsd,comp.unix.bsd,comp.os.386bsd.bugs,comp.protocols.tcp-ip
Subject: BUG in 4.4 raw_ip.c
Followup-To: comp.bugs.4bsd
Date: 15 Feb 1995 15:43:37 GMT
Organization: Information Technology Division, Naval Research Laboratory
Lines: 112
Message-ID: <3ht7f9$5v5@ra.nrl.navy.mil>
NNTP-Posting-Host: sundance.itd.nrl.navy.mil
Xref: imsi.com comp.bugs.4bsd:2034 comp.unix.bsd:18571 comp.os.386bsd.bugs:3254 comp.protocols.tcp-ip:38455
There is an obscure bug in 4.4 BSD (including 4.4-Lite) which affect raw
sockets that are bound to an address.
The fix is all of two characters, which inverts two tests in raw_ip.c. The
following is a context diff:
=====================(Cut up to and including here.)======================
armitage(sys/netinet)[0]% diff -c raw_ip.c /usr/src/sys/netinet/raw_ip.c
*** raw_ip.c Wed Feb 15 07:28:07 1995
--- /usr/src/sys/netinet/raw_ip.c Fri Dec 16 13:10:14 1994
***************
*** 93,102 ****
if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != ip->ip_p)
continue;
if (inp->inp_laddr.s_addr &&
! inp->inp_laddr.s_addr != ip->ip_dst.s_addr)
continue;
if (inp->inp_faddr.s_addr &&
! inp->inp_faddr.s_addr != ip->ip_src.s_addr)
continue;
if (last) {
struct mbuf *n;
--- 93,102 ----
if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != ip->ip_p)
continue;
if (inp->inp_laddr.s_addr &&
! inp->inp_laddr.s_addr == ip->ip_dst.s_addr)
continue;
if (inp->inp_faddr.s_addr &&
! inp->inp_faddr.s_addr == ip->ip_src.s_addr)
continue;
if (last) {
struct mbuf *n;
=====================(Cut up to and including here.)======================
To determine if your system is affected by this bug, here is code to test
it. (You will need to be root to run this...)
=====================(Cut up to and including here.)======================
/*
* test.c -- Silly program to test raw socket. Run without an argument
* to send. Run with an argument to receive.
*
* Daniel L. McDonald - U. S. Naval Research Laboratory
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
main(int argc)
{
int s;
s = socket(PF_INET,SOCK_RAW,69); /* 69, AFAIK, is not an
assigned protocol. */
if (s == -1)
{
perror("socket");
exit(1);
}
printf("argc = %d\n",argc);
if (argc > 1)
{
char *buf="Hello";
struct sockaddr_in dst = {AF_INET};
int rc;
dst.sin_addr.s_addr = htonl(0x7f000001); /* send it over loopback. */
rc = connect(s,&dst,sizeof(struct sockaddr_in));
if (rc == -1)
perror("connect");
else if ((rc = send(s,buf,strlen(buf)+1,0)) == -1)
perror("send");
else printf("%d bytes sent.\n",rc);
}
else
{
char buf[30];
struct sockaddr_in src={AF_INET,0, htonl(0x7f000001)};
int srclen,rc;
bzero(buf,10);
rc=bind(s,&src,sizeof(struct sockaddr_in));
if (rc == -1)
perror("bind");
else if ((rc=recvfrom(s,buf,30,0,&src,&srclen)) != -1)
printf("Got '%s' (%d bytes total) from %s, srclen %d\n",buf+20,rc,
inet_ntoa(src.sin_addr),srclen);
else perror("recvfrom");
}
}
=====================(Cut up to and including here.)======================
A few people had been notified of this earlier. I apologize for not
informing everyone sooner.
Enjoy!
--
Daniel L. McDonald | Mail: danmcd@itd.nrl.navy.mil -------------------------+
Computer Scientist | WWW: http://wintermute.itd.nrl.navy.mil/danmcd.html |
Naval Research Lab | Phone: (202) 404-7122 #include <disclaimer.h> |
Washington, DC | "Rise from the ashes, A blaze of everyday glory" - Rush +