summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '1055_linux-4.9.56.patch')
-rw-r--r--1055_linux-4.9.56.patch72
1 files changed, 72 insertions, 0 deletions
diff --git a/1055_linux-4.9.56.patch b/1055_linux-4.9.56.patch
new file mode 100644
index 00000000..46e3ea33
--- /dev/null
+++ b/1055_linux-4.9.56.patch
@@ -0,0 +1,72 @@
+diff --git a/Makefile b/Makefile
+index 2a995675d6bf..feab5f5a507c 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 9
+-SUBLEVEL = 55
++SUBLEVEL = 56
+ EXTRAVERSION =
+ NAME = Roaring Lionus
+
+diff --git a/net/core/filter.c b/net/core/filter.c
+index bfeedbbde214..4eb4ce0aeef4 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -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;
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 2a77cc50f021..231c38d91855 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -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