ipsec: Fix xfrm_state_walk race
As discovered by Timo Teräs, the currently xfrm_state_walk scheme is racy because if a second dump finishes before the first, we may free xfrm states that the first dump would walk over later. This patch fixes this by storing the dumps in a list in order to calculate the correct completion counter which cures this problem. I've expanded netlink_cb in order to accomodate the extra state related to this. It shouldn't be a big deal since netlink_cb is kmalloced for each dump and we're just increasing it by 4 or 8 bytes. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
fcaa40669c
commit
5c1824587f
@@ -1246,6 +1246,8 @@ struct xfrm6_tunnel {
|
||||
};
|
||||
|
||||
struct xfrm_state_walk {
|
||||
struct list_head list;
|
||||
unsigned long genid;
|
||||
struct xfrm_state *state;
|
||||
int count;
|
||||
u8 proto;
|
||||
@@ -1281,13 +1283,7 @@ static inline void xfrm6_fini(void)
|
||||
extern int xfrm_proc_init(void);
|
||||
#endif
|
||||
|
||||
static inline void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto)
|
||||
{
|
||||
walk->proto = proto;
|
||||
walk->state = NULL;
|
||||
walk->count = 0;
|
||||
}
|
||||
|
||||
extern void xfrm_state_walk_init(struct xfrm_state_walk *walk, u8 proto);
|
||||
extern int xfrm_state_walk(struct xfrm_state_walk *walk,
|
||||
int (*func)(struct xfrm_state *, int, void*), void *);
|
||||
extern void xfrm_state_walk_done(struct xfrm_state_walk *walk);
|
||||
|
Reference in New Issue
Block a user