patch-2.1.79 linux/net/ipv4/raw.c
Next file: linux/net/ipv4/route.c
Previous file: linux/net/ipv4/ipmr.c
Back to the patch index
Back to the overall index
- Lines: 110
- Date:
Mon Jan 12 15:28:28 1998
- Orig file:
v2.1.78/linux/net/ipv4/raw.c
- Orig date:
Mon Dec 1 12:04:16 1997
diff -u --recursive --new-file v2.1.78/linux/net/ipv4/raw.c linux/net/ipv4/raw.c
@@ -5,7 +5,7 @@
*
* RAW - implementation of IP "raw" sockets.
*
- * Version: $Id: raw.c,v 1.32 1997/10/24 17:16:00 kuznet Exp $
+ * Version: $Id: raw.c,v 1.33 1997/12/27 20:41:15 kuznet Exp $
*
* Authors: Ross Biro, <bir7@leland.Stanford.Edu>
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
@@ -255,13 +255,24 @@
{
struct ipcm_cookie ipc;
struct rawfakehdr rfh;
- struct rtable *rt;
+ struct rtable *rt = NULL;
int free = 0;
u32 daddr;
u8 tos;
int err;
- if (len>65535)
+ /* This check is ONLY to check for arithmetic overflow
+ on integer(!) len. Not more! Real check will be made
+ in ip_build_xmit --ANK
+
+ BTW socket.c -> af_*.c -> ... make multiple
+ invalid conversions size_t -> int. We MUST repair it f.e.
+ by replacing all of them with size_t and revise all
+ the places sort of len += sizeof(struct iphdr)
+ If len was ULONG_MAX-10 it would be cathastrophe --ANK
+ */
+
+ if (len < 0 || len > 0xFFFF)
return -EMSGSIZE;
/*
@@ -308,10 +319,6 @@
int tmp = ip_cmsg_send(msg, &ipc);
if (tmp)
return tmp;
- if (ipc.opt && sk->ip_hdrincl) {
- kfree(ipc.opt);
- return -EINVAL;
- }
if (ipc.opt)
free=1;
}
@@ -321,10 +328,19 @@
if (!ipc.opt)
ipc.opt = sk->opt;
- if (ipc.opt && ipc.opt->srr) {
- if (!daddr)
- return -EINVAL;
- daddr = ipc.opt->faddr;
+
+ if (ipc.opt) {
+ err = -EINVAL;
+ /* Linux does not mangle headers on raw sockets,
+ * so that IP options + IP_HDRINCL is non-sense.
+ */
+ if (sk->ip_hdrincl)
+ goto done;
+ if (ipc.opt->srr) {
+ if (!daddr)
+ goto done;
+ daddr = ipc.opt->faddr;
+ }
}
tos = RT_TOS(sk->ip_tos) | (sk->localroute || (msg->msg_flags&MSG_DONTROUTE));
@@ -337,30 +353,21 @@
err = ip_route_output(&rt, daddr, rfh.saddr, tos, ipc.oif);
- if (err) {
- if (free) kfree(ipc.opt);
- return err;
- }
+ if (err)
+ goto done;
- if (rt->rt_flags&RTCF_BROADCAST && !sk->broadcast) {
- if (free) kfree(ipc.opt);
- ip_rt_put(rt);
- return -EACCES;
- }
+ err = -EACCES;
+ if (rt->rt_flags&RTCF_BROADCAST && !sk->broadcast)
+ goto done;
rfh.iov = msg->msg_iov;
rfh.saddr = rt->rt_src;
if (!ipc.addr)
ipc.addr = rt->rt_dst;
- if(sk->ip_hdrincl)
- err=ip_build_xmit(sk, raw_getrawfrag, &rfh, len, &ipc, rt, msg->msg_flags);
- else {
- if (len>65535-sizeof(struct iphdr))
- err = -EMSGSIZE;
- else
- err=ip_build_xmit(sk, raw_getfrag, &rfh, len, &ipc, rt, msg->msg_flags);
- }
+ err=ip_build_xmit(sk, sk->ip_hdrincl ? raw_getrawfrag : raw_getfrag,
+ &rfh, len, &ipc, rt, msg->msg_flags);
+done:
if (free)
kfree(ipc.opt);
ip_rt_put(rt);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov