Commit 6ee9ceee authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller

[IPSEC]: Fix OOPS when deleting an ip address.

Looks like I was too hasty in blaming myself :) Although my patch does
fix a real bug, it cannot have been responsible for the crash that the OP
reported.  The reason is that the state timer always keeps a reference to
the state so even if it is incorrectly re-added the reference will prevent
the crash.

Hence the problem is still a bug in the ref counting.  I think I've found
the real culprit now.  __xfrm?_find_acq() is missing an xfrm_state_hold
on the create path.  This also explains why I never see it myself since
Openswan never creates states through that code-path.
parent 91d7f4e3
......@@ -83,9 +83,7 @@ __xfrm4_find_acq(u8 mode, u32 reqid, u8 proto,
break;
}
}
if (x0) {
xfrm_state_hold(x0);
} else if (create && (x0 = xfrm_state_alloc()) != NULL) {
if (!x0 && create && (x0 = xfrm_state_alloc()) != NULL) {
x0->sel.daddr.a4 = daddr->a4;
x0->sel.saddr.a4 = saddr->a4;
x0->sel.prefixlen_d = 32;
......@@ -105,6 +103,8 @@ __xfrm4_find_acq(u8 mode, u32 reqid, u8 proto,
list_add_tail(&x0->bydst, xfrm4_state_afinfo.state_bydst+h);
wake_up(&km_waitq);
}
if (x0)
xfrm_state_hold(x0);
return x0;
}
......
......@@ -90,9 +90,7 @@ __xfrm6_find_acq(u8 mode, u32 reqid, u8 proto,
break;
}
}
if (x0) {
xfrm_state_hold(x0);
} else if (create && (x0 = xfrm_state_alloc()) != NULL) {
if (!x0 && create && (x0 = xfrm_state_alloc()) != NULL) {
ipv6_addr_copy((struct in6_addr *)x0->sel.daddr.a6,
(struct in6_addr *)daddr);
ipv6_addr_copy((struct in6_addr *)x0->sel.saddr.a6,
......@@ -115,6 +113,8 @@ __xfrm6_find_acq(u8 mode, u32 reqid, u8 proto,
list_add_tail(&x0->bydst, xfrm6_state_afinfo.state_bydst+h);
wake_up(&km_waitq);
}
if (x0)
xfrm_state_hold(x0);
return x0;
}
......
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