Skip to content

Fix race between sk_filter reassign and sk_clone()

Pavel Emelyanov lkml netdev 1 version Applied

Status from this message: I've applied this for now to my net-2.6 tree, thanks Olof

Get series with b4
b4 am [email protected]

Versions newest first

  1. v1 Latest4 patches 5 repliesApplied

Patches in v1 Applied

#Subject and filesSizeRepliesApplied
1/4Introduce the sk_detach_filter() callinclude/linux/filter.h net/core/filter.c net/core/sock.c+18 -110 replies
2/4Move the filter releasing into a separate callinclude/net/sock.h net/core/filter.c net/core/sock.c+11 -70 replies
3/4Cleanup the error path in sk_attach_filternet/core/filter.c+11 -120 replies
4/4Fix the race between sk_filter_(de|at)tach and sk_clone()include/net/sock.h net/core/filter.c+22 -130 replies

Reviews trailers per patch

None of the 4 patches has a Reviewed-by or Acked-by of their own; the series has one for all of them.

PatchPavel Emelyanov
SeriesA-b
1/4
2/4
3/4
4/4

Trailers given in replies are filled; those carried in the patches from earlier versions are outlined with dashes.

Read the v1 thread

Cover letter [PATCH 0/4] Fix race between sk_filter reassign and sk_clone()

The race can result in that some sock will get an sk_filter pointer set to kfree-d memory. Look

CPU1:                            CPU2:
sk_clone():                      sk_attach_filter():
  new_sk = sk_alloc(...);
  sock_copy(new_sk, sk); 
  /* copies the filter ptr */
  ...
  filter = new_sk->sk_filter;
  if (filter)
                                     old_fp = sk->sk_filter;
                                     ...
                                     sk_filter_release(old_fp);
                                       if (atomic_dec_and_test(&old_fp->refcnt))
     atomic_inc(&filter->refcnt);
                                          /* true */
                                          call_rcu(&fp->rcu, kfree);

that's it - after a quiescent state pass the new_sk will have a pointer on kfree-d filter.

The same problem exists for detaching filter (SO_DETACH_FILTER).

The proposed fix consists of 3 preparation patches and the fix itself.