Commit cd931326 authored by Alexey Kuznetsov's avatar Alexey Kuznetsov Committed by David S. Miller

[NET]: miscellaneous fixes.

1. Fix illegal dereference of potentially freed memory in xfrm_policy.c
2. Complete wildcard flow addresses to real ones in xfrm_lookup().
3. Respect optional flag when chacking for input policy.
4. Delete orphaned comments in ip.h.
5. Fix mistakedly freed route in tcp connect.
parent 689827f0
...@@ -18,8 +18,6 @@ ...@@ -18,8 +18,6 @@
#define _LINUX_IP_H #define _LINUX_IP_H
#include <asm/byteorder.h> #include <asm/byteorder.h>
/* SOL_IP socket options */
#define IPTOS_TOS_MASK 0x1E #define IPTOS_TOS_MASK 0x1E
#define IPTOS_TOS(tos) ((tos)&IPTOS_TOS_MASK) #define IPTOS_TOS(tos) ((tos)&IPTOS_TOS_MASK)
#define IPTOS_LOWDELAY 0x10 #define IPTOS_LOWDELAY 0x10
...@@ -67,14 +65,6 @@ ...@@ -67,14 +65,6 @@
#define MAXTTL 255 #define MAXTTL 255
#define IPDEFTTL 64 #define IPDEFTTL 64
/* struct timestamp, struct route and MAX_ROUTES are removed.
REASONS: it is clear that nobody used them because:
- MAX_ROUTES value was wrong.
- "struct route" was wrong.
- "struct timestamp" had fatally misaligned bitfields and was completely unusable.
*/
#define IPOPT_OPTVAL 0 #define IPOPT_OPTVAL 0
#define IPOPT_OLEN 1 #define IPOPT_OLEN 1
#define IPOPT_OFFSET 2 #define IPOPT_OFFSET 2
......
...@@ -867,6 +867,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) ...@@ -867,6 +867,7 @@ int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
inet->id = tp->write_seq ^ jiffies; inet->id = tp->write_seq ^ jiffies;
err = tcp_connect(sk); err = tcp_connect(sk);
rt = NULL;
if (err) if (err)
goto failure; goto failure;
......
...@@ -347,6 +347,7 @@ static void xfrm_policy_timer(unsigned long data) ...@@ -347,6 +347,7 @@ static void xfrm_policy_timer(unsigned long data)
struct xfrm_policy *xp = (struct xfrm_policy*)data; struct xfrm_policy *xp = (struct xfrm_policy*)data;
unsigned long now = (unsigned long)xtime.tv_sec; unsigned long now = (unsigned long)xtime.tv_sec;
long next = LONG_MAX; long next = LONG_MAX;
u32 index;
if (xp->dead) if (xp->dead)
goto out; goto out;
...@@ -368,10 +369,11 @@ static void xfrm_policy_timer(unsigned long data) ...@@ -368,10 +369,11 @@ static void xfrm_policy_timer(unsigned long data)
return; return;
expired: expired:
index = xp->index;
xfrm_pol_put(xp); xfrm_pol_put(xp);
/* Not 100% correct. id can be recycled in theory */ /* Not 100% correct. id can be recycled in theory */
xp = xfrm_policy_byid(0, xp->index, 1); xp = xfrm_policy_byid(0, index, 1);
if (xp) { if (xp) {
xfrm_policy_kill(xp); xfrm_policy_kill(xp);
xfrm_pol_put(xp); xfrm_pol_put(xp);
...@@ -1082,6 +1084,17 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, ...@@ -1082,6 +1084,17 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
u32 genid; u32 genid;
u16 family = (*dst_p)->ops->family; u16 family = (*dst_p)->ops->family;
switch (family) {
case AF_INET:
if (!fl->fl4_src)
fl->fl4_src = rt->rt_src;
if (!fl->fl4_dst)
fl->fl4_dst = rt->rt_dst;
case AF_INET6:
/* Still not clear... */
default:
}
restart: restart:
genid = xfrm_policy_genid; genid = xfrm_policy_genid;
policy = NULL; policy = NULL;
...@@ -1120,8 +1133,6 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl, ...@@ -1120,8 +1133,6 @@ int xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
* is required only for output policy. * is required only for output policy.
*/ */
if (family == AF_INET) { if (family == AF_INET) {
fl->oif = rt->u.dst.dev->ifindex;
fl->fl4_src = rt->rt_src;
read_lock_bh(&policy->lock); read_lock_bh(&policy->lock);
for (dst = policy->bundles; dst; dst = dst->next) { for (dst = policy->bundles; dst; dst = dst->next) {
struct xfrm_dst *xdst = (struct xfrm_dst*)dst; struct xfrm_dst *xdst = (struct xfrm_dst*)dst;
...@@ -1451,10 +1462,11 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, ...@@ -1451,10 +1462,11 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
if (pol->action == XFRM_POLICY_ALLOW) { if (pol->action == XFRM_POLICY_ALLOW) {
if (pol->xfrm_nr != 0) { if (pol->xfrm_nr != 0) {
struct sec_path *sp; struct sec_path *sp;
static struct sec_path dummy;
int i, k; int i, k;
if ((sp = skb->sp) == NULL) if ((sp = skb->sp) == NULL)
goto reject; sp = &dummy;
/* For each tmpl search corresponding xfrm. /* For each tmpl search corresponding xfrm.
* Order is _important_. Later we will implement * Order is _important_. Later we will implement
...@@ -1462,6 +1474,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, ...@@ -1462,6 +1474,8 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
* are implied between each two transformations. * are implied between each two transformations.
*/ */
for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) { for (i = pol->xfrm_nr-1, k = 0; i >= 0; i--) {
if (pol->xfrm_vec[i].optional)
continue;
switch (family) { switch (family) {
case AF_INET: case AF_INET:
k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k); k = xfrm_policy_ok(pol->xfrm_vec+i, sp, k);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment