diff options
| author | Alexei Starovoitov <[email protected]> | 2013-11-20 03:12:34 +0000 |
|---|---|---|
| committer | David S. Miller <[email protected]> | 2013-11-20 20:28:44 +0000 |
| commit | dcdfdf56b4a6c9437fc37dbc9cee94a788f9b0c4 (patch) | |
| tree | f240417b7245048480497491fc82b464f14ebadd /net/unix/af_unix.c | |
| parent | Merge branch 'r8152' (diff) | |
| download | kernel-dcdfdf56b4a6c9437fc37dbc9cee94a788f9b0c4.tar.gz kernel-dcdfdf56b4a6c9437fc37dbc9cee94a788f9b0c4.zip | |
ipv4: fix race in concurrent ip_route_input_slow()
CPUs can ask for local route via ip_route_input_noref() concurrently.
if nh_rth_input is not cached yet, CPUs will proceed to allocate
equivalent DSTs on 'lo' and then will try to cache them in nh_rth_input
via rt_cache_route()
Most of the time they succeed, but on occasion the following two lines:
orig = *p;
prev = cmpxchg(p, orig, rt);
in rt_cache_route() do race and one of the cpus fails to complete cmpxchg.
But ip_route_input_slow() doesn't check the return code of rt_cache_route(),
so dst is leaking. dst_destroy() is never called and 'lo' device
refcnt doesn't go to zero, which can be seen in the logs as:
unregister_netdevice: waiting for lo to become free. Usage count = 1
Adding mdelay() between above two lines makes it easily reproducible.
Fix it similar to nh_pcpu_rth_output case.
Fixes: d2d68ba9fe8b ("ipv4: Cache input routes in fib_info nexthops.")
Signed-off-by: Alexei Starovoitov <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Diffstat (limited to 'net/unix/af_unix.c')
0 files changed, 0 insertions, 0 deletions
