larger than the maximum IP packet size. From NetBSD.
/*
* 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
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 */
-/* $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 $ */
/*
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;
-/* $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 $ */
/*
* 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 */
};
/*
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
-/* $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 $ */
/*
* 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;
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,
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 */
};
-/* $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 $ */
/*
goto bail;
}
+ /*
+ * 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.