From: Greg Kroah-Hartman Date: Mon, 24 Jun 2013 21:06:53 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.0.84~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c0884bda4ac3a1da2c805dcd9387b20855ab17d7;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: gianfar-add-missing-iounmap-on-error-in-gianfar_ptp_probe.patch ip_tunnel-fix-kernel-panic-with-icmp_dest_unreach.patch ipv6-assign-rt6_info-to-inet6_ifaddr-in-init_loopback.patch ipv6-fix-possible-crashes-in-ip6_cork_release.patch l2tp-fix-ppp-header-erasure-and-memory-leak.patch l2tp-fix-sendmsg-return-value.patch net-block-msg_cmsg_compat-in-send-m-msg-and-recv-m-msg.patch net-force-a-reload-of-first-item-in-hlist_nulls_for_each_entry_rcu.patch netlabel-improve-domain-mapping-validation.patch net-sctp-fix-null-pointer-dereference-in-socket-destruction.patch packet-packet_getname_spkt-make-sure-string-is-always-0-terminated.patch tcp-fix-tcp_md5_hash_skb_data.patch tcp-xps-fix-reordering-issues.patch --- diff --git a/queue-3.0/gianfar-add-missing-iounmap-on-error-in-gianfar_ptp_probe.patch b/queue-3.0/gianfar-add-missing-iounmap-on-error-in-gianfar_ptp_probe.patch new file mode 100644 index 00000000000..7cf9054c431 --- /dev/null +++ b/queue-3.0/gianfar-add-missing-iounmap-on-error-in-gianfar_ptp_probe.patch @@ -0,0 +1,29 @@ +From 273c3d4944f2b77a132a587b5ff7a134646b3de8 Mon Sep 17 00:00:00 2001 +From: Wei Yongjun +Date: Thu, 16 May 2013 22:25:34 +0000 +Subject: gianfar: add missing iounmap() on error in gianfar_ptp_probe() + +From: Wei Yongjun + +[ Upstream commit e5f5e380e0f3bb11f04ca5bc66a551e58e0ad26e ] + +Add the missing iounmap() before return from gianfar_ptp_probe() +in the error handling case. + +Signed-off-by: Wei Yongjun +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/gianfar_ptp.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/gianfar_ptp.c ++++ b/drivers/net/gianfar_ptp.c +@@ -521,6 +521,7 @@ static int gianfar_ptp_probe(struct plat + return 0; + + no_clock: ++ iounmap(etsects->regs); + no_ioremap: + release_resource(etsects->rsrc); + no_resource: diff --git a/queue-3.0/ip_tunnel-fix-kernel-panic-with-icmp_dest_unreach.patch b/queue-3.0/ip_tunnel-fix-kernel-panic-with-icmp_dest_unreach.patch new file mode 100644 index 00000000000..af2b4312c94 --- /dev/null +++ b/queue-3.0/ip_tunnel-fix-kernel-panic-with-icmp_dest_unreach.patch @@ -0,0 +1,72 @@ +From 5ea8887f9c6a80a35f470f61a744fe3febc99e54 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 24 May 2013 05:49:58 +0000 +Subject: ip_tunnel: fix kernel panic with icmp_dest_unreach + +From: Eric Dumazet + +[ Upstream commit a622260254ee481747cceaaa8609985b29a31565 ] + +Daniel Petre reported crashes in icmp_dst_unreach() with following call +graph: + +Daniel found a similar problem mentioned in + http://lkml.indiana.edu/hypermail/linux/kernel/1007.0/00961.html + +And indeed this is the root cause : skb->cb[] contains data fooling IP +stack. + +We must clear IPCB in ip_tunnel_xmit() sooner in case dst_link_failure() +is called. Or else skb->cb[] might contain garbage from GSO segmentation +layer. + +A similar fix was tested on linux-3.9, but gre code was refactored in +linux-3.10. I'll send patches for stable kernels as well. + +Many thanks to Daniel for providing reports, patches and testing ! + +Reported-by: Daniel Petre +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_gre.c | 2 +- + net/ipv4/ipip.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv4/ip_gre.c ++++ b/net/ipv4/ip_gre.c +@@ -716,6 +716,7 @@ static netdev_tx_t ipgre_tunnel_xmit(str + tiph = &tunnel->parms.iph; + } + ++ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + if ((dst = tiph->daddr) == 0) { + /* NBMA tunnel */ + +@@ -853,7 +854,6 @@ static netdev_tx_t ipgre_tunnel_xmit(str + skb_reset_transport_header(skb); + skb_push(skb, gre_hlen); + skb_reset_network_header(skb); +- memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | + IPSKB_REROUTED); + skb_dst_drop(skb); +--- a/net/ipv4/ipip.c ++++ b/net/ipv4/ipip.c +@@ -448,6 +448,7 @@ static netdev_tx_t ipip_tunnel_xmit(stru + if (tos & 1) + tos = old_iph->tos; + ++ memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + if (!dst) { + /* NBMA tunnel */ + if ((rt = skb_rtable(skb)) == NULL) { +@@ -531,7 +532,6 @@ static netdev_tx_t ipip_tunnel_xmit(stru + skb->transport_header = skb->network_header; + skb_push(skb, sizeof(struct iphdr)); + skb_reset_network_header(skb); +- memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); + IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | + IPSKB_REROUTED); + skb_dst_drop(skb); diff --git a/queue-3.0/ipv6-assign-rt6_info-to-inet6_ifaddr-in-init_loopback.patch b/queue-3.0/ipv6-assign-rt6_info-to-inet6_ifaddr-in-init_loopback.patch new file mode 100644 index 00000000000..4e26ea9d714 --- /dev/null +++ b/queue-3.0/ipv6-assign-rt6_info-to-inet6_ifaddr-in-init_loopback.patch @@ -0,0 +1,40 @@ +From e25759b91bfc1d09d71e2843e2c0f3b0e308fdca Mon Sep 17 00:00:00 2001 +From: Gao feng +Date: Sun, 2 Jun 2013 22:16:21 +0000 +Subject: ipv6: assign rt6_info to inet6_ifaddr in init_loopback + +From: Gao feng + +[ Upstream commit 534c877928a16ae5f9776436a497109639bf67dc ] + +Commit 25fb6ca4ed9cad72f14f61629b68dc03c0d9713f +"net IPv6 : Fix broken IPv6 routing table after loopback down-up" +forgot to assign rt6_info to the inet6_ifaddr. +When disable the net device, the rt6_info which allocated +in init_loopback will not be destroied in __ipv6_ifa_notify. + +This will trigger the waring message below +[23527.916091] unregister_netdevice: waiting for tap0 to become free. Usage count = 1 + +Reported-by: Arkadiusz Miskiewicz +Signed-off-by: Gao feng +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/addrconf.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -2360,8 +2360,10 @@ static void init_loopback(struct net_dev + sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); + + /* Failure cases are ignored */ +- if (!IS_ERR(sp_rt)) ++ if (!IS_ERR(sp_rt)) { ++ sp_ifa->rt = sp_rt; + ip6_ins_rt(sp_rt); ++ } + } + read_unlock_bh(&idev->lock); + } diff --git a/queue-3.0/ipv6-fix-possible-crashes-in-ip6_cork_release.patch b/queue-3.0/ipv6-fix-possible-crashes-in-ip6_cork_release.patch new file mode 100644 index 00000000000..1c9494e0766 --- /dev/null +++ b/queue-3.0/ipv6-fix-possible-crashes-in-ip6_cork_release.patch @@ -0,0 +1,36 @@ +From 6079422bffc1704cf69686ce7a1409dbb419deaf Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Fri, 17 May 2013 04:53:13 +0000 +Subject: ipv6: fix possible crashes in ip6_cork_release() + +From: Eric Dumazet + +[ Upstream commit 284041ef21fdf2e0d216ab6b787bc9072b4eb58a ] + +commit 0178b695fd6b4 ("ipv6: Copy cork options in ip6_append_data") +added some code duplication and bad error recovery, leading to potential +crash in ip6_cork_release() as kfree() could be called with garbage. + +use kzalloc() to make sure this wont happen. + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Cc: Herbert Xu +Cc: Hideaki YOSHIFUJI +Cc: Neal Cardwell +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_output.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1248,7 +1248,7 @@ int ip6_append_data(struct sock *sk, int + if (WARN_ON(np->cork.opt)) + return -EINVAL; + +- np->cork.opt = kmalloc(opt->tot_len, sk->sk_allocation); ++ np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation); + if (unlikely(np->cork.opt == NULL)) + return -ENOBUFS; + diff --git a/queue-3.0/l2tp-fix-ppp-header-erasure-and-memory-leak.patch b/queue-3.0/l2tp-fix-ppp-header-erasure-and-memory-leak.patch new file mode 100644 index 00000000000..0d2c869ce2f --- /dev/null +++ b/queue-3.0/l2tp-fix-ppp-header-erasure-and-memory-leak.patch @@ -0,0 +1,37 @@ +From 7728091d69e5b36a9b28e8219ad9af606015fe91 Mon Sep 17 00:00:00 2001 +From: Guillaume Nault +Date: Wed, 12 Jun 2013 16:07:23 +0200 +Subject: l2tp: Fix PPP header erasure and memory leak + +From: Guillaume Nault + +[ Upstream commit 55b92b7a11690bc377b5d373872a6b650ae88e64 ] + +Copy user data after PPP framing header. This prevents erasure of the +added PPP header and avoids leaking two bytes of uninitialised memory +at the end of skb's data buffer. + +Signed-off-by: Guillaume Nault +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_ppp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -350,12 +350,12 @@ static int pppol2tp_sendmsg(struct kiocb + skb_put(skb, 2); + + /* Copy user data into skb */ +- error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); ++ error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov, ++ total_len); + if (error < 0) { + kfree_skb(skb); + goto error_put_sess_tun; + } +- skb_put(skb, total_len); + + l2tp_xmit_skb(session, skb, session->hdr_len); + diff --git a/queue-3.0/l2tp-fix-sendmsg-return-value.patch b/queue-3.0/l2tp-fix-sendmsg-return-value.patch new file mode 100644 index 00000000000..97e54bef535 --- /dev/null +++ b/queue-3.0/l2tp-fix-sendmsg-return-value.patch @@ -0,0 +1,30 @@ +From e350a94b13a1b078cac50d0b836b96f38937b6e0 Mon Sep 17 00:00:00 2001 +From: Guillaume Nault +Date: Wed, 12 Jun 2013 16:07:36 +0200 +Subject: l2tp: Fix sendmsg() return value + +From: Guillaume Nault + +[ Upstream commit a6f79d0f26704214b5b702bbac525cb72997f984 ] + +PPPoL2TP sockets should comply with the standard send*() return values +(i.e. return number of bytes sent instead of 0 upon success). + +Signed-off-by: Guillaume Nault +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_ppp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -362,7 +362,7 @@ static int pppol2tp_sendmsg(struct kiocb + sock_put(ps->tunnel_sock); + sock_put(sk); + +- return error; ++ return total_len; + + error_put_sess_tun: + sock_put(ps->tunnel_sock); diff --git a/queue-3.0/net-block-msg_cmsg_compat-in-send-m-msg-and-recv-m-msg.patch b/queue-3.0/net-block-msg_cmsg_compat-in-send-m-msg-and-recv-m-msg.patch new file mode 100644 index 00000000000..339051163a2 --- /dev/null +++ b/queue-3.0/net-block-msg_cmsg_compat-in-send-m-msg-and-recv-m-msg.patch @@ -0,0 +1,267 @@ +From 4ff46b1f5e98db5c456c331267099f2183b496dc Mon Sep 17 00:00:00 2001 +From: Andy Lutomirski +Date: Wed, 22 May 2013 14:07:44 -0700 +Subject: net: Block MSG_CMSG_COMPAT in send(m)msg and recv(m)msg + +From: Andy Lutomirski + +[ Upstream commits 1be374a0518a288147c6a7398792583200a67261 and + a7526eb5d06b0084ef12d7b168d008fcf516caab ] + +MSG_CMSG_COMPAT is (AFAIK) not intended to be part of the API -- +it's a hack that steals a bit to indicate to other networking code +that a compat entry was used. So don't allow it from a non-compat +syscall. + +This prevents an oops when running this code: + +int main() +{ + int s; + struct sockaddr_in addr; + struct msghdr *hdr; + + char *highpage = mmap((void*)(TASK_SIZE_MAX - 4096), 4096, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); + if (highpage == MAP_FAILED) + err(1, "mmap"); + + s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (s == -1) + err(1, "socket"); + + addr.sin_family = AF_INET; + addr.sin_port = htons(1); + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + if (connect(s, (struct sockaddr*)&addr, sizeof(addr)) != 0) + err(1, "connect"); + + void *evil = highpage + 4096 - COMPAT_MSGHDR_SIZE; + printf("Evil address is %p\n", evil); + + if (syscall(__NR_sendmmsg, s, evil, 1, MSG_CMSG_COMPAT) < 0) + err(1, "sendmmsg"); + + return 0; +} + +Cc: David S. Miller +Signed-off-by: Andy Lutomirski +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/socket.h | 3 ++ + net/compat.c | 13 ++++++++- + net/socket.c | 67 ++++++++++++++++++++++++++++++++----------------- + 3 files changed, 59 insertions(+), 24 deletions(-) + +--- a/include/linux/socket.h ++++ b/include/linux/socket.h +@@ -332,6 +332,9 @@ extern int put_cmsg(struct msghdr*, int + + struct timespec; + ++/* The __sys_...msg variants allow MSG_CMSG_COMPAT */ ++extern long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags); ++extern long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags); + extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, + unsigned int flags, struct timespec *timeout); + extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, +--- a/net/compat.c ++++ b/net/compat.c +@@ -732,19 +732,25 @@ static unsigned char nas[21] = { + + asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned flags) + { +- return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; ++ return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); + } + + asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, + unsigned vlen, unsigned int flags) + { ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; + return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, + flags | MSG_CMSG_COMPAT); + } + + asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) + { +- return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; ++ return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); + } + + asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned flags) +@@ -766,6 +772,9 @@ asmlinkage long compat_sys_recvmmsg(int + int datagrams; + struct timespec ktspec; + ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; ++ + if (timeout == NULL) + return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, + flags | MSG_CMSG_COMPAT, NULL); +--- a/net/socket.c ++++ b/net/socket.c +@@ -1876,9 +1876,9 @@ struct used_address { + unsigned int name_len; + }; + +-static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, +- struct msghdr *msg_sys, unsigned flags, +- struct used_address *used_address) ++static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, ++ struct msghdr *msg_sys, unsigned flags, ++ struct used_address *used_address) + { + struct compat_msghdr __user *msg_compat = + (struct compat_msghdr __user *)msg; +@@ -1998,22 +1998,30 @@ out: + * BSD sendmsg interface + */ + +-SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) ++long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) + { + int fput_needed, err; + struct msghdr msg_sys; +- struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); ++ struct socket *sock; + ++ sock = sockfd_lookup_light(fd, &err, &fput_needed); + if (!sock) + goto out; + +- err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL); ++ err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL); + + fput_light(sock->file, fput_needed); + out: + return err; + } + ++SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags) ++{ ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; ++ return __sys_sendmsg(fd, msg, flags); ++} ++ + /* + * Linux sendmmsg interface + */ +@@ -2044,15 +2052,16 @@ int __sys_sendmmsg(int fd, struct mmsghd + + while (datagrams < vlen) { + if (MSG_CMSG_COMPAT & flags) { +- err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, +- &msg_sys, flags, &used_address); ++ err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry, ++ &msg_sys, flags, &used_address); + if (err < 0) + break; + err = __put_user(err, &compat_entry->msg_len); + ++compat_entry; + } else { +- err = __sys_sendmsg(sock, (struct msghdr __user *)entry, +- &msg_sys, flags, &used_address); ++ err = ___sys_sendmsg(sock, ++ (struct msghdr __user *)entry, ++ &msg_sys, flags, &used_address); + if (err < 0) + break; + err = put_user(err, &entry->msg_len); +@@ -2076,11 +2085,13 @@ int __sys_sendmmsg(int fd, struct mmsghd + SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, + unsigned int, vlen, unsigned int, flags) + { ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; + return __sys_sendmmsg(fd, mmsg, vlen, flags); + } + +-static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg, +- struct msghdr *msg_sys, unsigned flags, int nosec) ++static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, ++ struct msghdr *msg_sys, unsigned flags, int nosec) + { + struct compat_msghdr __user *msg_compat = + (struct compat_msghdr __user *)msg; +@@ -2177,23 +2188,31 @@ out: + * BSD recvmsg interface + */ + +-SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, +- unsigned int, flags) ++long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags) + { + int fput_needed, err; + struct msghdr msg_sys; +- struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); ++ struct socket *sock; + ++ sock = sockfd_lookup_light(fd, &err, &fput_needed); + if (!sock) + goto out; + +- err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0); ++ err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0); + + fput_light(sock->file, fput_needed); + out: + return err; + } + ++SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, ++ unsigned int, flags) ++{ ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; ++ return __sys_recvmsg(fd, msg, flags); ++} ++ + /* + * Linux recvmmsg interface + */ +@@ -2231,17 +2250,18 @@ int __sys_recvmmsg(int fd, struct mmsghd + * No need to ask LSM for more than the first datagram. + */ + if (MSG_CMSG_COMPAT & flags) { +- err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry, +- &msg_sys, flags & ~MSG_WAITFORONE, +- datagrams); ++ err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry, ++ &msg_sys, flags & ~MSG_WAITFORONE, ++ datagrams); + if (err < 0) + break; + err = __put_user(err, &compat_entry->msg_len); + ++compat_entry; + } else { +- err = __sys_recvmsg(sock, (struct msghdr __user *)entry, +- &msg_sys, flags & ~MSG_WAITFORONE, +- datagrams); ++ err = ___sys_recvmsg(sock, ++ (struct msghdr __user *)entry, ++ &msg_sys, flags & ~MSG_WAITFORONE, ++ datagrams); + if (err < 0) + break; + err = put_user(err, &entry->msg_len); +@@ -2308,6 +2328,9 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struc + int datagrams; + struct timespec timeout_sys; + ++ if (flags & MSG_CMSG_COMPAT) ++ return -EINVAL; ++ + if (!timeout) + return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL); + diff --git a/queue-3.0/net-force-a-reload-of-first-item-in-hlist_nulls_for_each_entry_rcu.patch b/queue-3.0/net-force-a-reload-of-first-item-in-hlist_nulls_for_each_entry_rcu.patch new file mode 100644 index 00000000000..fca3492a6fd --- /dev/null +++ b/queue-3.0/net-force-a-reload-of-first-item-in-hlist_nulls_for_each_entry_rcu.patch @@ -0,0 +1,53 @@ +From bf0713f4462b8dcb8c2cb64ed653e198eeae7fce Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 29 May 2013 09:06:27 +0000 +Subject: net: force a reload of first item in hlist_nulls_for_each_entry_rcu + +From: Eric Dumazet + +[ Upstream commit c87a124a5d5e8cf8e21c4363c3372bcaf53ea190 ] + +Roman Gushchin discovered that udp4_lib_lookup2() was not reloading +first item in the rcu protected list, in case the loop was restarted. + +This produced soft lockups as in https://lkml.org/lkml/2013/4/16/37 + +rcu_dereference(X)/ACCESS_ONCE(X) seem to not work as intended if X is +ptr->field : + +In some cases, gcc caches the value or ptr->field in a register. + +Use a barrier() to disallow such caching, as documented in +Documentation/atomic_ops.txt line 114 + +Thanks a lot to Roman for providing analysis and numerous patches. + +Diagnosed-by: Roman Gushchin +Signed-off-by: Eric Dumazet +Reported-by: Boris Zhmurov +Signed-off-by: Roman Gushchin +Acked-by: Paul E. McKenney +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/rculist_nulls.h | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +--- a/include/linux/rculist_nulls.h ++++ b/include/linux/rculist_nulls.h +@@ -105,9 +105,14 @@ static inline void hlist_nulls_add_head_ + * @head: the head for your list. + * @member: the name of the hlist_nulls_node within the struct. + * ++ * The barrier() is needed to make sure compiler doesn't cache first element [1], ++ * as this loop can be restarted [2] ++ * [1] Documentation/atomic_ops.txt around line 114 ++ * [2] Documentation/RCU/rculist_nulls.txt around line 146 + */ + #define hlist_nulls_for_each_entry_rcu(tpos, pos, head, member) \ +- for (pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \ ++ for (({barrier();}), \ ++ pos = rcu_dereference_raw(hlist_nulls_first_rcu(head)); \ + (!is_a_nulls(pos)) && \ + ({ tpos = hlist_nulls_entry(pos, typeof(*tpos), member); 1; }); \ + pos = rcu_dereference_raw(hlist_nulls_next_rcu(pos))) diff --git a/queue-3.0/net-sctp-fix-null-pointer-dereference-in-socket-destruction.patch b/queue-3.0/net-sctp-fix-null-pointer-dereference-in-socket-destruction.patch new file mode 100644 index 00000000000..cdaf80f4a2d --- /dev/null +++ b/queue-3.0/net-sctp-fix-null-pointer-dereference-in-socket-destruction.patch @@ -0,0 +1,95 @@ +From 147124af20745c950812d6f071ff8aa9affb65cc Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Thu, 6 Jun 2013 15:53:47 +0200 +Subject: net: sctp: fix NULL pointer dereference in socket destruction + +From: Daniel Borkmann + +[ Upstream commit 1abd165ed757db1afdefaac0a4bc8a70f97d258c ] + +While stress testing sctp sockets, I hit the following panic: + +BUG: unable to handle kernel NULL pointer dereference at 0000000000000020 +IP: [] sctp_endpoint_free+0xe/0x40 [sctp] +PGD 7cead067 PUD 7ce76067 PMD 0 +Oops: 0000 [#1] SMP +Modules linked in: sctp(F) libcrc32c(F) [...] +CPU: 7 PID: 2950 Comm: acc Tainted: GF 3.10.0-rc2+ #1 +Hardware name: Dell Inc. PowerEdge T410/0H19HD, BIOS 1.6.3 02/01/2011 +task: ffff88007ce0e0c0 ti: ffff88007b568000 task.ti: ffff88007b568000 +RIP: 0010:[] [] sctp_endpoint_free+0xe/0x40 [sctp] +RSP: 0018:ffff88007b569e08 EFLAGS: 00010292 +RAX: 0000000000000000 RBX: ffff88007db78a00 RCX: dead000000200200 +RDX: ffffffffa049fdb0 RSI: ffff8800379baf38 RDI: 0000000000000000 +RBP: ffff88007b569e18 R08: ffff88007c230da0 R09: 0000000000000001 +R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 +R13: ffff880077990d00 R14: 0000000000000084 R15: ffff88007db78a00 +FS: 00007fc18ab61700(0000) GS:ffff88007fc60000(0000) knlGS:0000000000000000 +CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b +CR2: 0000000000000020 CR3: 000000007cf9d000 CR4: 00000000000007e0 +DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 +Stack: + ffff88007b569e38 ffff88007db78a00 ffff88007b569e38 ffffffffa049fded + ffffffff81abf0c0 ffff88007db78a00 ffff88007b569e58 ffffffff8145b60e + 0000000000000000 0000000000000000 ffff88007b569eb8 ffffffff814df36e +Call Trace: + [] sctp_destroy_sock+0x3d/0x80 [sctp] + [] sk_common_release+0x1e/0xf0 + [] inet_create+0x2ae/0x350 + [] __sock_create+0x11f/0x240 + [] sock_create+0x30/0x40 + [] SyS_socket+0x4c/0xc0 + [] ? do_page_fault+0xe/0x10 + [] ? page_fault+0x22/0x30 + [] system_call_fastpath+0x16/0x1b +Code: 0c c9 c3 66 2e 0f 1f 84 00 00 00 00 00 e8 fb fe ff ff c9 c3 66 0f + 1f 84 00 00 00 00 00 55 48 89 e5 53 48 83 ec 08 66 66 66 66 90 <48> + 8b 47 20 48 89 fb c6 47 1c 01 c6 40 12 07 e8 9e 68 01 00 48 +RIP [] sctp_endpoint_free+0xe/0x40 [sctp] + RSP +CR2: 0000000000000020 +---[ end trace e0d71ec1108c1dd9 ]--- + +I did not hit this with the lksctp-tools functional tests, but with a +small, multi-threaded test program, that heavily allocates, binds, +listens and waits in accept on sctp sockets, and then randomly kills +some of them (no need for an actual client in this case to hit this). +Then, again, allocating, binding, etc, and then killing child processes. + +This panic then only occurs when ``echo 1 > /proc/sys/net/sctp/auth_enable'' +is set. The cause for that is actually very simple: in sctp_endpoint_init() +we enter the path of sctp_auth_init_hmacs(). There, we try to allocate +our crypto transforms through crypto_alloc_hash(). In our scenario, +it then can happen that crypto_alloc_hash() fails with -EINTR from +crypto_larval_wait(), thus we bail out and release the socket via +sk_common_release(), sctp_destroy_sock() and hit the NULL pointer +dereference as soon as we try to access members in the endpoint during +sctp_endpoint_free(), since endpoint at that time is still NULL. Now, +if we have that case, we do not need to do any cleanup work and just +leave the destruction handler. + +Signed-off-by: Daniel Borkmann +Acked-by: Neil Horman +Acked-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/socket.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/net/sctp/socket.c ++++ b/net/sctp/socket.c +@@ -3809,6 +3809,12 @@ SCTP_STATIC void sctp_destroy_sock(struc + + /* Release our hold on the endpoint. */ + ep = sctp_sk(sk)->ep; ++ /* This could happen during socket init, thus we bail out ++ * early, since the rest of the below is not setup either. ++ */ ++ if (ep == NULL) ++ return; ++ + sctp_endpoint_free(ep); + local_bh_disable(); + percpu_counter_dec(&sctp_sockets_allocated); diff --git a/queue-3.0/netlabel-improve-domain-mapping-validation.patch b/queue-3.0/netlabel-improve-domain-mapping-validation.patch new file mode 100644 index 00000000000..fe23104bf48 --- /dev/null +++ b/queue-3.0/netlabel-improve-domain-mapping-validation.patch @@ -0,0 +1,116 @@ +From d66a61908f507b1457f4d4c40457c90272f34a46 Mon Sep 17 00:00:00 2001 +From: Paul Moore +Date: Fri, 17 May 2013 09:08:50 +0000 +Subject: netlabel: improve domain mapping validation + +From: Paul Moore + +[ Upstream commit 6b21e1b77d1a3d58ebfd513264c885695e8a0ba5 ] + +The net/netlabel/netlabel_domainhash.c:netlbl_domhsh_add() function +does not properly validate new domain hash entries resulting in +potential problems when an administrator attempts to add an invalid +entry. One such problem, as reported by Vlad Halilov, is a kernel +BUG (found in netlabel_domainhash.c:netlbl_domhsh_audit_add()) when +adding an IPv6 outbound mapping with a CIPSO configuration. + +This patch corrects this problem by adding the necessary validation +code to netlbl_domhsh_add() via the newly created +netlbl_domhsh_validate() function. + +Ideally this patch should also be pushed to the currently active +-stable trees. + +Reported-by: Vlad Halilov +Signed-off-by: Paul Moore +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/netlabel/netlabel_domainhash.c | 69 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 69 insertions(+) + +--- a/net/netlabel/netlabel_domainhash.c ++++ b/net/netlabel/netlabel_domainhash.c +@@ -246,6 +246,71 @@ static void netlbl_domhsh_audit_add(stru + } + } + ++/** ++ * netlbl_domhsh_validate - Validate a new domain mapping entry ++ * @entry: the entry to validate ++ * ++ * This function validates the new domain mapping entry to ensure that it is ++ * a valid entry. Returns zero on success, negative values on failure. ++ * ++ */ ++static int netlbl_domhsh_validate(const struct netlbl_dom_map *entry) ++{ ++ struct netlbl_af4list *iter4; ++ struct netlbl_domaddr4_map *map4; ++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) ++ struct netlbl_af6list *iter6; ++ struct netlbl_domaddr6_map *map6; ++#endif /* IPv6 */ ++ ++ if (entry == NULL) ++ return -EINVAL; ++ ++ switch (entry->type) { ++ case NETLBL_NLTYPE_UNLABELED: ++ if (entry->type_def.cipsov4 != NULL || ++ entry->type_def.addrsel != NULL) ++ return -EINVAL; ++ break; ++ case NETLBL_NLTYPE_CIPSOV4: ++ if (entry->type_def.cipsov4 == NULL) ++ return -EINVAL; ++ break; ++ case NETLBL_NLTYPE_ADDRSELECT: ++ netlbl_af4list_foreach(iter4, &entry->type_def.addrsel->list4) { ++ map4 = netlbl_domhsh_addr4_entry(iter4); ++ switch (map4->type) { ++ case NETLBL_NLTYPE_UNLABELED: ++ if (map4->type_def.cipsov4 != NULL) ++ return -EINVAL; ++ break; ++ case NETLBL_NLTYPE_CIPSOV4: ++ if (map4->type_def.cipsov4 == NULL) ++ return -EINVAL; ++ break; ++ default: ++ return -EINVAL; ++ } ++ } ++#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) ++ netlbl_af6list_foreach(iter6, &entry->type_def.addrsel->list6) { ++ map6 = netlbl_domhsh_addr6_entry(iter6); ++ switch (map6->type) { ++ case NETLBL_NLTYPE_UNLABELED: ++ break; ++ default: ++ return -EINVAL; ++ } ++ } ++#endif /* IPv6 */ ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + /* + * Domain Hash Table Functions + */ +@@ -312,6 +377,10 @@ int netlbl_domhsh_add(struct netlbl_dom_ + struct netlbl_af6list *tmp6; + #endif /* IPv6 */ + ++ ret_val = netlbl_domhsh_validate(entry); ++ if (ret_val != 0) ++ return ret_val; ++ + /* XXX - we can remove this RCU read lock as the spinlock protects the + * entire function, but before we do we need to fixup the + * netlbl_af[4,6]list RCU functions to do "the right thing" with diff --git a/queue-3.0/packet-packet_getname_spkt-make-sure-string-is-always-0-terminated.patch b/queue-3.0/packet-packet_getname_spkt-make-sure-string-is-always-0-terminated.patch new file mode 100644 index 00000000000..6f37b266cf9 --- /dev/null +++ b/queue-3.0/packet-packet_getname_spkt-make-sure-string-is-always-0-terminated.patch @@ -0,0 +1,41 @@ +From 75e9eaf51fdb2ad4d047594642394d276ed8360c Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 12 Jun 2013 16:02:27 +0200 +Subject: packet: packet_getname_spkt: make sure string is always 0-terminated + +From: Daniel Borkmann + +[ Upstream commit 2dc85bf323515e59e15dfa858d1472bb25cad0fe ] + +uaddr->sa_data is exactly of size 14, which is hard-coded here and +passed as a size argument to strncpy(). A device name can be of size +IFNAMSIZ (== 16), meaning we might leave the destination string +unterminated. Thus, use strlcpy() and also sizeof() while we're +at it. We need to memset the data area beforehand, since strlcpy +does not padd the remaining buffer with zeroes for user space, so +that we do not possibly leak anything. + +Signed-off-by: Daniel Borkmann +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/packet/af_packet.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -1767,12 +1767,11 @@ static int packet_getname_spkt(struct so + return -EOPNOTSUPP; + + uaddr->sa_family = AF_PACKET; ++ memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data)); + rcu_read_lock(); + dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex); + if (dev) +- strncpy(uaddr->sa_data, dev->name, 14); +- else +- memset(uaddr->sa_data, 0, 14); ++ strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data)); + rcu_read_unlock(); + *uaddr_len = sizeof(*uaddr); + diff --git a/queue-3.0/series b/queue-3.0/series index 60f56d6b2d0..170de9620ec 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -1,3 +1,16 @@ alsa-usb-audio-work-around-android-accessory-firmware-bug.patch tilepro-work-around-module-link-error-with-gcc-4.7.patch kvm-x86-remove-vcpu-s-cpl-check-in-host-invoked-xcr-set.patch +tcp-fix-tcp_md5_hash_skb_data.patch +gianfar-add-missing-iounmap-on-error-in-gianfar_ptp_probe.patch +ipv6-fix-possible-crashes-in-ip6_cork_release.patch +netlabel-improve-domain-mapping-validation.patch +tcp-xps-fix-reordering-issues.patch +ip_tunnel-fix-kernel-panic-with-icmp_dest_unreach.patch +net-block-msg_cmsg_compat-in-send-m-msg-and-recv-m-msg.patch +net-force-a-reload-of-first-item-in-hlist_nulls_for_each_entry_rcu.patch +ipv6-assign-rt6_info-to-inet6_ifaddr-in-init_loopback.patch +net-sctp-fix-null-pointer-dereference-in-socket-destruction.patch +packet-packet_getname_spkt-make-sure-string-is-always-0-terminated.patch +l2tp-fix-ppp-header-erasure-and-memory-leak.patch +l2tp-fix-sendmsg-return-value.patch diff --git a/queue-3.0/tcp-fix-tcp_md5_hash_skb_data.patch b/queue-3.0/tcp-fix-tcp_md5_hash_skb_data.patch new file mode 100644 index 00000000000..5f6ce76bca5 --- /dev/null +++ b/queue-3.0/tcp-fix-tcp_md5_hash_skb_data.patch @@ -0,0 +1,46 @@ +From c3f00fd432bdd2e5e12f384a72e7ec48124c2690 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Mon, 13 May 2013 21:25:52 +0000 +Subject: tcp: fix tcp_md5_hash_skb_data() + +From: Eric Dumazet + +[ Upstream commit 54d27fcb338bd9c42d1dfc5a39e18f6f9d373c2e ] + +TCP md5 communications fail [1] for some devices, because sg/crypto code +assume page offsets are below PAGE_SIZE. + +This was discovered using mlx4 driver [2], but I suspect loopback +might trigger the same bug now we use order-3 pages in tcp_sendmsg() + +[1] Failure is giving following messages. + +huh, entered softirq 3 NET_RX ffffffff806ad230 preempt_count 00000100, +exited with 00000101? + +[2] mlx4 driver uses order-2 pages to allocate RX frags + +Reported-by: Matt Schnall +Signed-off-by: Eric Dumazet +Cc: Bernhard Beck +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -3043,7 +3043,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5 + + for (i = 0; i < shi->nr_frags; ++i) { + const struct skb_frag_struct *f = &shi->frags[i]; +- sg_set_page(&sg, f->page, f->size, f->page_offset); ++ unsigned int offset = f->page_offset; ++ struct page *page = f->page + (offset >> PAGE_SHIFT); ++ ++ sg_set_page(&sg, page, f->size, ++ offset_in_page(offset)); + if (crypto_hash_update(desc, &sg, f->size)) + return 1; + } diff --git a/queue-3.0/tcp-xps-fix-reordering-issues.patch b/queue-3.0/tcp-xps-fix-reordering-issues.patch new file mode 100644 index 00000000000..1016d9b07f5 --- /dev/null +++ b/queue-3.0/tcp-xps-fix-reordering-issues.patch @@ -0,0 +1,47 @@ +From 0572ccda874850a4155d0a9bc621486fa2675b2e Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 23 May 2013 07:44:20 +0000 +Subject: tcp: xps: fix reordering issues + +From: Eric Dumazet + +[ Upstream commit 547669d483e5783d722772af1483fa474da7caf9 ] + +commit 3853b5841c01a ("xps: Improvements in TX queue selection") +introduced ooo_okay flag, but the condition to set it is slightly wrong. + +In our traces, we have seen ACK packets being received out of order, +and RST packets sent in response. + +We should test if we have any packets still in host queue. + +Signed-off-by: Eric Dumazet +Cc: Tom Herbert +Cc: Yuchung Cheng +Cc: Neal Cardwell +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_output.c | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -833,11 +833,13 @@ static int tcp_transmit_skb(struct sock + &md5); + tcp_header_size = tcp_options_size + sizeof(struct tcphdr); + +- if (tcp_packets_in_flight(tp) == 0) { ++ if (tcp_packets_in_flight(tp) == 0) + tcp_ca_event(sk, CA_EVENT_TX_START); +- skb->ooo_okay = 1; +- } else +- skb->ooo_okay = 0; ++ ++ /* if no packet is in qdisc/device queue, then allow XPS to select ++ * another queue. ++ */ ++ skb->ooo_okay = sk_wmem_alloc_get(sk) == 0; + + skb_push(skb, tcp_header_size); + skb_reset_transport_header(skb);