Skip to content

Commit

Permalink
Revert "socket, bpf: fix possible use after free"
Browse files Browse the repository at this point in the history
This reverts commit 02f7e41, which was
commit 02f7e41 upstream

Turns out the backport to 4.9 was broken.

Reported-by: Shuah Khan <shuahkh@osg.samsung.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Greg Kroah-Hartman committed Oct 12, 2017
1 parent f82786d commit 0044962
Showing 2 changed files with 3 additions and 17 deletions.
15 changes: 2 additions & 13 deletions net/core/filter.c
Original file line number Diff line number Diff line change
@@ -937,31 +937,20 @@ void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp)
/* try to charge the socket memory if there is space available
* return true on success
*/
static bool __sk_filter_charge(struct sock *sk, struct sk_filter *fp)
bool sk_filter_charge(struct sock *sk, struct sk_filter *fp)
{
u32 filter_size = bpf_prog_size(fp->prog->len);

/* same check as in sock_kmalloc() */
if (filter_size <= sysctl_optmem_max &&
atomic_read(&sk->sk_omem_alloc) + filter_size < sysctl_optmem_max) {
atomic_inc(&fp->refcnt);
atomic_add(filter_size, &sk->sk_omem_alloc);
return true;
}
return false;
}

bool sk_filter_charge(struct sock *sk, struct sk_filter *fp)
{
if (!atomic_inc_not_zero(&fp->refcnt))
return false;

if (!__sk_filter_charge(sk, fp)) {
sk_filter_release(fp);
return false;
}
return true;
}

static struct bpf_prog *bpf_migrate_filter(struct bpf_prog *fp)
{
struct sock_filter *old_prog;
5 changes: 1 addition & 4 deletions net/core/sock.c
Original file line number Diff line number Diff line change
@@ -1528,16 +1528,13 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
sock_reset_flag(newsk, SOCK_DONE);
skb_queue_head_init(&newsk->sk_error_queue);

rcu_read_lock();
filter = rcu_dereference(sk->sk_filter);
filter = rcu_dereference_protected(newsk->sk_filter, 1);
if (filter != NULL)
/* though it's an empty new sock, the charging may fail
* if sysctl_optmem_max was changed between creation of
* original socket and cloning
*/
is_charged = sk_filter_charge(newsk, filter);
RCU_INIT_POINTER(newsk->sk_filter, filter);
rcu_read_unlock();

if (unlikely(!is_charged || xfrm_sk_clone_policy(newsk, sk))) {
/* We need to make sure that we don't uncharge the new

0 comments on commit 0044962

Please sign in to comment.