From: Greg Kroah-Hartman Date: Sat, 26 Sep 2015 18:15:52 +0000 (-0700) Subject: 3.10-stable patches X-Git-Tag: v4.1.9~14 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e3e9d3bec47e9fe5920f69deada70acf0998656f;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: sctp-fix-asconf-list-handling.patch vhost-scsi-potential-memory-corruption.patch x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch --- diff --git a/queue-3.10/sctp-fix-asconf-list-handling.patch b/queue-3.10/sctp-fix-asconf-list-handling.patch new file mode 100644 index 00000000000..d074542a576 --- /dev/null +++ b/queue-3.10/sctp-fix-asconf-list-handling.patch @@ -0,0 +1,186 @@ +From 2d45a02d0166caf2627fe91897c6ffc3b19514c4 Mon Sep 17 00:00:00 2001 +From: Marcelo Ricardo Leitner +Date: Fri, 12 Jun 2015 10:16:41 -0300 +Subject: sctp: fix ASCONF list handling + +From: Marcelo Ricardo Leitner + +commit 2d45a02d0166caf2627fe91897c6ffc3b19514c4 upstream. + +->auto_asconf_splist is per namespace and mangled by functions like +sctp_setsockopt_auto_asconf() which doesn't guarantee any serialization. + +Also, the call to inet_sk_copy_descendant() was backuping +->auto_asconf_list through the copy but was not honoring +->do_auto_asconf, which could lead to list corruption if it was +different between both sockets. + +This commit thus fixes the list handling by using ->addr_wq_lock +spinlock to protect the list. A special handling is done upon socket +creation and destruction for that. Error handlig on sctp_init_sock() +will never return an error after having initialized asconf, so +sctp_destroy_sock() can be called without addrq_wq_lock. The lock now +will be take on sctp_close_sock(), before locking the socket, so we +don't do it in inverse order compared to sctp_addr_wq_timeout_handler(). + +Instead of taking the lock on sctp_sock_migrate() for copying and +restoring the list values, it's preferred to avoid rewritting it by +implementing sctp_copy_descendant(). + +Issue was found with a test application that kept flipping sysctl +default_auto_asconf on and off, but one could trigger it by issuing +simultaneous setsockopt() calls on multiple sockets or by +creating/destroying sockets fast enough. This is only triggerable +locally. + +Fixes: 9f7d653b67ae ("sctp: Add Auto-ASCONF support (core).") +Reported-by: Ji Jianwen +Suggested-by: Neil Horman +Suggested-by: Hannes Frederic Sowa +Acked-by: Hannes Frederic Sowa +Signed-off-by: Marcelo Ricardo Leitner +Signed-off-by: David S. Miller +[wangkai: backport to 3.10: adjust context] +Signed-off-by: Wang Kai +Signed-off-by: Greg Kroah-Hartman +--- + include/net/netns/sctp.h | 1 + + include/net/sctp/structs.h | 4 ++++ + net/sctp/socket.c | 43 ++++++++++++++++++++++++++++++++----------- + 3 files changed, 37 insertions(+), 11 deletions(-) + +--- a/include/net/netns/sctp.h ++++ b/include/net/netns/sctp.h +@@ -31,6 +31,7 @@ struct netns_sctp { + struct list_head addr_waitq; + struct timer_list addr_wq_timer; + struct list_head auto_asconf_splist; ++ /* Lock that protects both addr_waitq and auto_asconf_splist */ + spinlock_t addr_wq_lock; + + /* Lock that protects the local_addr_list writers */ +--- a/include/net/sctp/structs.h ++++ b/include/net/sctp/structs.h +@@ -228,6 +228,10 @@ struct sctp_sock { + atomic_t pd_mode; + /* Receive to here while partial delivery is in effect. */ + struct sk_buff_head pd_lobby; ++ ++ /* These must be the last fields, as they will skipped on copies, ++ * like on accept and peeloff operations ++ */ + struct list_head auto_asconf_list; + int do_auto_asconf; + }; +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -1548,8 +1548,10 @@ SCTP_STATIC void sctp_close(struct sock + + /* Supposedly, no process has access to the socket, but + * the net layers still may. ++ * Also, sctp_destroy_sock() needs to be called with addr_wq_lock ++ * held and that should be grabbed before socket lock. + */ +- sctp_local_bh_disable(); ++ spin_lock_bh(&net->sctp.addr_wq_lock); + sctp_bh_lock_sock(sk); + + /* Hold the sock, since sk_common_release() will put sock_put() +@@ -1559,7 +1561,7 @@ SCTP_STATIC void sctp_close(struct sock + sk_common_release(sk); + + sctp_bh_unlock_sock(sk); +- sctp_local_bh_enable(); ++ spin_unlock_bh(&net->sctp.addr_wq_lock); + + sock_put(sk); + +@@ -3508,6 +3510,7 @@ static int sctp_setsockopt_auto_asconf(s + if ((val && sp->do_auto_asconf) || (!val && !sp->do_auto_asconf)) + return 0; + ++ spin_lock_bh(&sock_net(sk)->sctp.addr_wq_lock); + if (val == 0 && sp->do_auto_asconf) { + list_del(&sp->auto_asconf_list); + sp->do_auto_asconf = 0; +@@ -3516,6 +3519,7 @@ static int sctp_setsockopt_auto_asconf(s + &sock_net(sk)->sctp.auto_asconf_splist); + sp->do_auto_asconf = 1; + } ++ spin_unlock_bh(&sock_net(sk)->sctp.addr_wq_lock); + return 0; + } + +@@ -4007,18 +4011,28 @@ SCTP_STATIC int sctp_init_sock(struct so + local_bh_disable(); + percpu_counter_inc(&sctp_sockets_allocated); + sock_prot_inuse_add(net, sk->sk_prot, 1); ++ ++ /* Nothing can fail after this block, otherwise ++ * sctp_destroy_sock() will be called without addr_wq_lock held ++ */ + if (net->sctp.default_auto_asconf) { ++ spin_lock(&sock_net(sk)->sctp.addr_wq_lock); + list_add_tail(&sp->auto_asconf_list, + &net->sctp.auto_asconf_splist); + sp->do_auto_asconf = 1; +- } else ++ spin_unlock(&sock_net(sk)->sctp.addr_wq_lock); ++ } else { + sp->do_auto_asconf = 0; ++ } ++ + local_bh_enable(); + + return 0; + } + +-/* Cleanup any SCTP per socket resources. */ ++/* Cleanup any SCTP per socket resources. Must be called with ++ * sock_net(sk)->sctp.addr_wq_lock held if sp->do_auto_asconf is true ++ */ + SCTP_STATIC void sctp_destroy_sock(struct sock *sk) + { + struct sctp_sock *sp; +@@ -6957,6 +6971,19 @@ void sctp_copy_sock(struct sock *newsk, + newinet->mc_list = NULL; + } + ++static inline void sctp_copy_descendant(struct sock *sk_to, ++ const struct sock *sk_from) ++{ ++ int ancestor_size = sizeof(struct inet_sock) + ++ sizeof(struct sctp_sock) - ++ offsetof(struct sctp_sock, auto_asconf_list); ++ ++ if (sk_from->sk_family == PF_INET6) ++ ancestor_size += sizeof(struct ipv6_pinfo); ++ ++ __inet_sk_copy_descendant(sk_to, sk_from, ancestor_size); ++} ++ + /* Populate the fields of the newsk from the oldsk and migrate the assoc + * and its messages to the newsk. + */ +@@ -6971,7 +6998,6 @@ static void sctp_sock_migrate(struct soc + struct sk_buff *skb, *tmp; + struct sctp_ulpevent *event; + struct sctp_bind_hashbucket *head; +- struct list_head tmplist; + + /* Migrate socket buffer sizes and all the socket level options to the + * new socket. +@@ -6979,12 +7005,7 @@ static void sctp_sock_migrate(struct soc + newsk->sk_sndbuf = oldsk->sk_sndbuf; + newsk->sk_rcvbuf = oldsk->sk_rcvbuf; + /* Brute force copy old sctp opt. */ +- if (oldsp->do_auto_asconf) { +- memcpy(&tmplist, &newsp->auto_asconf_list, sizeof(tmplist)); +- inet_sk_copy_descendant(newsk, oldsk); +- memcpy(&newsp->auto_asconf_list, &tmplist, sizeof(tmplist)); +- } else +- inet_sk_copy_descendant(newsk, oldsk); ++ sctp_copy_descendant(newsk, oldsk); + + /* Restore the ep value that was overwritten with the above structure + * copy. diff --git a/queue-3.10/series b/queue-3.10/series index 2f7c426f79d..f27beb69ada 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -28,3 +28,6 @@ ib-mlx4-forbid-using-sysfs-to-change-roce-pkeys.patch ib-mlx4-use-correct-sl-on-ah-query-under-roce.patch stmmac-fix-check-for-phydev-being-open.patch hfs-hfsplus-cache-pages-correctly-between-bnode_create-and-bnode_free.patch +sctp-fix-asconf-list-handling.patch +vhost-scsi-potential-memory-corruption.patch +x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch diff --git a/queue-3.10/vhost-scsi-potential-memory-corruption.patch b/queue-3.10/vhost-scsi-potential-memory-corruption.patch new file mode 100644 index 00000000000..6045cc83fcc --- /dev/null +++ b/queue-3.10/vhost-scsi-potential-memory-corruption.patch @@ -0,0 +1,58 @@ +From 59c816c1f24df0204e01851431d3bab3eb76719c Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Thu, 5 Feb 2015 10:37:33 +0300 +Subject: vhost/scsi: potential memory corruption + +From: Dan Carpenter + +commit 59c816c1f24df0204e01851431d3bab3eb76719c upstream. + +This code in vhost_scsi_make_tpg() is confusing because we limit "tpgt" +to UINT_MAX but the data type of "tpg->tport_tpgt" and that is a u16. + +I looked at the context and it turns out that in +vhost_scsi_set_endpoint(), "tpg->tport_tpgt" is used as an offset into +the vs_tpg[] array which has VHOST_SCSI_MAX_TARGET (256) elements so +anything higher than 255 then it is invalid. I have made that the limit +now. + +In vhost_scsi_send_evt() we mask away values higher than 255, but now +that the limit has changed, we don't need the mask. + +Signed-off-by: Dan Carpenter +Signed-off-by: Nicholas Bellinger +[ The affected function was renamed to vhost_scsi_make_tpg before + the vulnerability was announced, I ported it to 3.10 stable and + changed the code in function tcm_vhost_make_tpg] +Signed-off-by: Wang Long +Signed-off-by: Greg Kroah-Hartman +--- + drivers/vhost/scsi.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/vhost/scsi.c ++++ b/drivers/vhost/scsi.c +@@ -1088,7 +1088,7 @@ static void tcm_vhost_send_evt(struct vh + * lun[4-7] need to be zero according to virtio-scsi spec. + */ + evt->event.lun[0] = 0x01; +- evt->event.lun[1] = tpg->tport_tpgt & 0xFF; ++ evt->event.lun[1] = tpg->tport_tpgt; + if (lun->unpacked_lun >= 256) + evt->event.lun[2] = lun->unpacked_lun >> 8 | 0x40 ; + evt->event.lun[3] = lun->unpacked_lun & 0xFF; +@@ -1894,12 +1894,12 @@ static struct se_portal_group *tcm_vhost + struct tcm_vhost_tport, tport_wwn); + + struct tcm_vhost_tpg *tpg; +- unsigned long tpgt; ++ u16 tpgt; + int ret; + + if (strstr(name, "tpgt_") != name) + return ERR_PTR(-EINVAL); +- if (kstrtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX) ++ if (kstrtou16(name + 5, 10, &tpgt) || tpgt >= VHOST_SCSI_MAX_TARGET) + return ERR_PTR(-EINVAL); + + tpg = kzalloc(sizeof(struct tcm_vhost_tpg), GFP_KERNEL); diff --git a/queue-3.10/x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch b/queue-3.10/x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch new file mode 100644 index 00000000000..dbbfb03d899 --- /dev/null +++ b/queue-3.10/x86-bpf_jit-fix-compilation-of-large-bpf-programs.patch @@ -0,0 +1,47 @@ +From 3f7352bf21f8fd7ba3e2fcef9488756f188e12be Mon Sep 17 00:00:00 2001 +From: Alexei Starovoitov +Date: Fri, 22 May 2015 15:42:55 -0700 +Subject: x86: bpf_jit: fix compilation of large bpf programs + +From: Alexei Starovoitov + +commit 3f7352bf21f8fd7ba3e2fcef9488756f188e12be upstream. + +x86 has variable length encoding. x86 JIT compiler is trying +to pick the shortest encoding for given bpf instruction. +While doing so the jump targets are changing, so JIT is doing +multiple passes over the program. Typical program needs 3 passes. +Some very short programs converge with 2 passes. Large programs +may need 4 or 5. But specially crafted bpf programs may hit the +pass limit and if the program converges on the last iteration +the JIT compiler will be producing an image full of 'int 3' insns. +Fix this corner case by doing final iteration over bpf program. + +Fixes: 0a14842f5a3c ("net: filter: Just In Time compiler for x86-64") +Reported-by: Daniel Borkmann +Signed-off-by: Alexei Starovoitov +Tested-by: Daniel Borkmann +Acked-by: Daniel Borkmann +Signed-off-by: David S. Miller +Signed-off-by: Jiri Slaby +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/net/bpf_jit_comp.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/arch/x86/net/bpf_jit_comp.c ++++ b/arch/x86/net/bpf_jit_comp.c +@@ -176,7 +176,12 @@ void bpf_jit_compile(struct sk_filter *f + } + cleanup_addr = proglen; /* epilogue address */ + +- for (pass = 0; pass < 10; pass++) { ++ /* JITed image shrinks with every pass and the loop iterates ++ * until the image stops shrinking. Very large bpf programs ++ * may converge on the last pass. In such case do one more ++ * pass to emit the final image ++ */ ++ for (pass = 0; pass < 10 || image; pass++) { + u8 seen_or_pass0 = (pass == 0) ? (SEEN_XREG | SEEN_DATAREF | SEEN_MEM) : seen; + /* no prologue/epilogue for trivial filters (RET something) */ + proglen = 0;