summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorThorsten Lockert <tholo@cvs.openbsd.org>1997-01-26 01:23:47 +0000
committerThorsten Lockert <tholo@cvs.openbsd.org>1997-01-26 01:23:47 +0000
commit4b93c01e3b45629f5e6739cb2c2532c35ffa3a58 (patch)
tree5bca63bdbaf229bdf26c449141a5c4b33c4202e3 /sys
parent4640a9fc32fcc4332d35c8a19d0953fdfafbc06e (diff)
Make ip_len and ip_off unsigned values; don't transmit or accept packets
larger than the maximum IP packet size. From NetBSD.
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/ip.h8
-rw-r--r--sys/netinet/ip_input.c10
-rw-r--r--sys/netinet/ip_var.h13
-rw-r--r--sys/netinet/raw_ip.c10
-rw-r--r--sys/netinet/udp.h2
-rw-r--r--sys/netinet/udp_usrreq.c11
6 files changed, 37 insertions, 17 deletions
diff --git a/sys/netinet/ip.h b/sys/netinet/ip.h
index 3214fb3f920..fb866314786 100644
--- a/sys/netinet/ip.h
+++ b/sys/netinet/ip.h
@@ -43,10 +43,6 @@
/*
* Structure of an internet header, naked of options.
- *
- * We declare ip_len and ip_off to be short, rather than u_short
- * pragmatically since otherwise unsigned comparisons can result
- * against negative integers quite easily, and fail in subtle ways.
*/
struct ip {
#if BYTE_ORDER == LITTLE_ENDIAN
@@ -58,9 +54,9 @@ struct ip {
ip_hl:4; /* header length */
#endif
u_int8_t ip_tos; /* type of service */
- int16_t ip_len; /* total length */
+ u_int16_t ip_len; /* total length */
u_int16_t ip_id; /* identification */
- int16_t ip_off; /* fragment offset field */
+ u_int16_t ip_off; /* fragment offset field */
#define IP_RF 0x8000 /* reserved fragment flag */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index 89b2beb91be..2d8ab0bedb9 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_input.c,v 1.19 1996/10/27 00:47:33 deraadt Exp $ */
+/* $OpenBSD: ip_input.c,v 1.20 1997/01/26 01:23:43 tholo Exp $ */
/* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */
/*
@@ -569,10 +569,16 @@ insert:
return (0);
/*
- * Reassembly is complete; concatenate fragments.
+ * Reassembly is complete. Check for a bogus message size and
+ * concatenate fragments.
*/
q = fp->ipq_fragq.lh_first;
ip = q->ipqe_ip;
+ if ((next + (ip->ip_hl << 2)) > IP_MAXPACKET) {
+ ipstat.ips_toolong++;
+ ip_freef(fp);
+ return (0);
+ }
m = dtom(q->ipqe_ip);
t = m->m_next;
m->m_next = 0;
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index 7caed51f3e9..c79623bd0a8 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ip_var.h,v 1.3 1996/03/03 22:30:42 niklas Exp $ */
+/* $OpenBSD: ip_var.h,v 1.4 1997/01/26 01:23:44 tholo Exp $ */
/* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */
/*
@@ -42,11 +42,11 @@
* Overlay for ip header used by other protocols (tcp, udp).
*/
struct ipovly {
- u_int8_t ih_x1[9]; /* (unused) */
- u_int8_t ih_pr; /* protocol */
- int16_t ih_len; /* protocol length */
- struct in_addr ih_src; /* source internet address */
- struct in_addr ih_dst; /* destination internet address */
+ u_int8_t ih_x1[9]; /* (unused) */
+ u_int8_t ih_pr; /* protocol */
+ u_int16_t ih_len; /* protocol length */
+ struct in_addr ih_src; /* source internet address */
+ struct in_addr ih_dst; /* destination internet address */
};
/*
@@ -144,6 +144,7 @@ struct ipstat {
u_long ips_rawout; /* total raw ip packets generated */
u_long ips_badfrags; /* malformed fragments (bad length) */
u_long ips_rcvmemdrop; /* frags dropped for lack of memory */
+ u_long ips_toolong; /* ip length > max ip packet size */
};
#ifdef _KERNEL
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index aaedb610567..97d641fddb4 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: raw_ip.c,v 1.7 1996/08/14 20:19:20 deraadt Exp $ */
+/* $OpenBSD: raw_ip.c,v 1.8 1997/01/26 01:23:44 tholo Exp $ */
/* $NetBSD: raw_ip.c,v 1.25 1996/02/18 18:58:33 christos Exp $ */
/*
@@ -171,6 +171,10 @@ rip_output(m, va_alist)
* Otherwise, allocate an mbuf for a header and fill it in.
*/
if ((inp->inp_flags & INP_HDRINCL) == 0) {
+ if ((m->m_pkthdr.len + sizeof(struct ip)) > IP_MAXPACKET) {
+ m_freem(m);
+ return (EMSGSIZE);
+ }
M_PREPEND(m, sizeof(struct ip), M_WAIT);
ip = mtod(m, struct ip *);
ip->ip_tos = 0;
@@ -181,6 +185,10 @@ rip_output(m, va_alist)
ip->ip_dst.s_addr = dst;
ip->ip_ttl = MAXTTL;
} else {
+ if (m->m_pkthdr.len > IP_MAXPACKET) {
+ m_freem(m);
+ return (EMSGSIZE);
+ }
ip = mtod(m, struct ip *);
/*
* don't allow both user specified and setsockopt options,
diff --git a/sys/netinet/udp.h b/sys/netinet/udp.h
index c7964dfd30f..95bc044f7d9 100644
--- a/sys/netinet/udp.h
+++ b/sys/netinet/udp.h
@@ -42,6 +42,6 @@
struct udphdr {
u_int16_t uh_sport; /* source port */
u_int16_t uh_dport; /* destination port */
- int16_t uh_ulen; /* udp length */
+ u_int16_t uh_ulen; /* udp length */
u_int16_t uh_sum; /* udp checksum */
};
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index f78e4be2d7f..31bdf858ac9 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: udp_usrreq.c,v 1.7 1996/07/05 20:42:18 deraadt Exp $ */
+/* $OpenBSD: udp_usrreq.c,v 1.8 1997/01/26 01:23:46 tholo Exp $ */
/* $NetBSD: udp_usrreq.c,v 1.28 1996/03/16 23:54:03 christos Exp $ */
/*
@@ -461,6 +461,15 @@ udp_output(m, va_alist)
}
/*
+ * Compute the packet length of the IP header, and
+ * punt if the length looks bogus.
+ */
+ if ((len + sizeof(struct udpiphdr)) > IP_MAXPACKET) {
+ error = EMSGSIZE;
+ goto release;
+ }
+
+ /*
* Fill in mbuf with extended UDP header
* and addresses and length put into network format.
*/