]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Apr 2017 13:09:12 +0000 (15:09 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 19 Apr 2017 13:09:12 +0000 (15:09 +0200)
added patches:
ibmveth-calculate-gso_segs-for-large-packets.patch
net-ipv6-check-route-protocol-when-deleting-routes.patch
sunrpc-fix-refcounting-problems-with-auth_gss-messages.patch
tty-serial-atmel-rs485-half-duplex-w-dma-enable-rx-after-tx-is-done.patch

queue-4.4/ibmveth-calculate-gso_segs-for-large-packets.patch [new file with mode: 0644]
queue-4.4/net-ipv6-check-route-protocol-when-deleting-routes.patch [new file with mode: 0644]
queue-4.4/series
queue-4.4/sunrpc-fix-refcounting-problems-with-auth_gss-messages.patch [new file with mode: 0644]
queue-4.4/tty-serial-atmel-rs485-half-duplex-w-dma-enable-rx-after-tx-is-done.patch [new file with mode: 0644]

diff --git a/queue-4.4/ibmveth-calculate-gso_segs-for-large-packets.patch b/queue-4.4/ibmveth-calculate-gso_segs-for-large-packets.patch
new file mode 100644 (file)
index 0000000..6469570
--- /dev/null
@@ -0,0 +1,58 @@
+From 94acf164dc8f1184e8d0737be7125134c2701dbe Mon Sep 17 00:00:00 2001
+From: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
+Date: Tue, 13 Dec 2016 18:15:09 -0600
+Subject: ibmveth: calculate gso_segs for large packets
+
+From: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
+
+commit 94acf164dc8f1184e8d0737be7125134c2701dbe upstream.
+
+Include calculations to compute the number of segments
+that comprise an aggregated large packet.
+
+Signed-off-by: Thomas Falcon <tlfalcon@linux.vnet.ibm.com>
+Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Reviewed-by: Jonathan Maxwell <jmaxwell37@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/ibm/ibmveth.c |   12 ++++++++++--
+ 1 file changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/ibm/ibmveth.c
++++ b/drivers/net/ethernet/ibm/ibmveth.c
+@@ -1179,7 +1179,9 @@ map_failed:
+ static void ibmveth_rx_mss_helper(struct sk_buff *skb, u16 mss, int lrg_pkt)
+ {
++      struct tcphdr *tcph;
+       int offset = 0;
++      int hdr_len;
+       /* only TCP packets will be aggregated */
+       if (skb->protocol == htons(ETH_P_IP)) {
+@@ -1206,14 +1208,20 @@ static void ibmveth_rx_mss_helper(struct
+       /* if mss is not set through Large Packet bit/mss in rx buffer,
+        * expect that the mss will be written to the tcp header checksum.
+        */
++      tcph = (struct tcphdr *)(skb->data + offset);
+       if (lrg_pkt) {
+               skb_shinfo(skb)->gso_size = mss;
+       } else if (offset) {
+-              struct tcphdr *tcph = (struct tcphdr *)(skb->data + offset);
+-
+               skb_shinfo(skb)->gso_size = ntohs(tcph->check);
+               tcph->check = 0;
+       }
++
++      if (skb_shinfo(skb)->gso_size) {
++              hdr_len = offset + tcph->doff * 4;
++              skb_shinfo(skb)->gso_segs =
++                              DIV_ROUND_UP(skb->len - hdr_len,
++                                           skb_shinfo(skb)->gso_size);
++      }
+ }
+ static int ibmveth_poll(struct napi_struct *napi, int budget)
diff --git a/queue-4.4/net-ipv6-check-route-protocol-when-deleting-routes.patch b/queue-4.4/net-ipv6-check-route-protocol-when-deleting-routes.patch
new file mode 100644 (file)
index 0000000..47bf0b0
--- /dev/null
@@ -0,0 +1,38 @@
+From c2ed1880fd61a998e3ce40254a99a2ad000f1a7d Mon Sep 17 00:00:00 2001
+From: Mantas M <grawity@gmail.com>
+Date: Fri, 16 Dec 2016 10:30:59 +0200
+Subject: net: ipv6: check route protocol when deleting routes
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mantas M <grawity@gmail.com>
+
+commit c2ed1880fd61a998e3ce40254a99a2ad000f1a7d upstream.
+
+The protocol field is checked when deleting IPv4 routes, but ignored for
+IPv6, which causes problems with routing daemons accidentally deleting
+externally set routes (observed by multiple bird6 users).
+
+This can be verified using `ip -6 route del <prefix> proto something`.
+
+Signed-off-by: Mantas Mikulėnas <grawity@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv6/route.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -2084,6 +2084,8 @@ static int ip6_route_del(struct fib6_con
+                               continue;
+                       if (cfg->fc_metric && cfg->fc_metric != rt->rt6i_metric)
+                               continue;
++                      if (cfg->fc_protocol && cfg->fc_protocol != rt->rt6i_protocol)
++                              continue;
+                       dst_hold(&rt->dst);
+                       read_unlock_bh(&table->tb6_lock);
index e5f877fc9be0988c71cecfd2776359ec0736e59a..15ea943a79db856ab0dd60aeba1f3bb272e06d23 100644 (file)
@@ -37,3 +37,7 @@ pegasus-use-heap-buffers-for-all-register-access.patch
 rtl8150-use-heap-buffers-for-all-register-access.patch
 catc-combine-failure-cleanup-code-in-catc_probe.patch
 catc-use-heap-buffer-for-memory-size-test.patch
+ibmveth-calculate-gso_segs-for-large-packets.patch
+sunrpc-fix-refcounting-problems-with-auth_gss-messages.patch
+tty-serial-atmel-rs485-half-duplex-w-dma-enable-rx-after-tx-is-done.patch
+net-ipv6-check-route-protocol-when-deleting-routes.patch
diff --git a/queue-4.4/sunrpc-fix-refcounting-problems-with-auth_gss-messages.patch b/queue-4.4/sunrpc-fix-refcounting-problems-with-auth_gss-messages.patch
new file mode 100644 (file)
index 0000000..c477322
--- /dev/null
@@ -0,0 +1,85 @@
+From 1cded9d2974fe4fe339fc0ccd6638b80d465ab2c Mon Sep 17 00:00:00 2001
+From: NeilBrown <neilb@suse.com>
+Date: Mon, 5 Dec 2016 15:10:11 +1100
+Subject: SUNRPC: fix refcounting problems with auth_gss messages.
+
+From: NeilBrown <neilb@suse.com>
+
+commit 1cded9d2974fe4fe339fc0ccd6638b80d465ab2c upstream.
+
+There are two problems with refcounting of auth_gss messages.
+
+First, the reference on the pipe->pipe list (taken by a call
+to rpc_queue_upcall()) is not counted.  It seems to be
+assumed that a message in pipe->pipe will always also be in
+pipe->in_downcall, where it is correctly reference counted.
+
+However there is no guaranty of this.  I have a report of a
+NULL dereferences in rpc_pipe_read() which suggests a msg
+that has been freed is still on the pipe->pipe list.
+
+One way I imagine this might happen is:
+- message is queued for uid=U and auth->service=S1
+- rpc.gssd reads this message and starts processing.
+  This removes the message from pipe->pipe
+- message is queued for uid=U and auth->service=S2
+- rpc.gssd replies to the first message. gss_pipe_downcall()
+  calls __gss_find_upcall(pipe, U, NULL) and it finds the
+  *second* message, as new messages are placed at the head
+  of ->in_downcall, and the service type is not checked.
+- This second message is removed from ->in_downcall and freed
+  by gss_release_msg() (even though it is still on pipe->pipe)
+- rpc.gssd tries to read another message, and dereferences a pointer
+  to this message that has just been freed.
+
+I fix this by incrementing the reference count before calling
+rpc_queue_upcall(), and decrementing it if that fails, or normally in
+gss_pipe_destroy_msg().
+
+It seems strange that the reply doesn't target the message more
+precisely, but I don't know all the details.  In any case, I think the
+reference counting irregularity became a measureable bug when the
+extra arg was added to __gss_find_upcall(), hence the Fixes: line
+below.
+
+The second problem is that if rpc_queue_upcall() fails, the new
+message is not freed. gss_alloc_msg() set the ->count to 1,
+gss_add_msg() increments this to 2, gss_unhash_msg() decrements to 1,
+then the pointer is discarded so the memory never gets freed.
+
+Fixes: 9130b8dbc6ac ("SUNRPC: allow for upcalls for same uid but different gss service")
+Link: https://bugzilla.opensuse.org/show_bug.cgi?id=1011250
+Signed-off-by: NeilBrown <neilb@suse.com>
+Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
+Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/sunrpc/auth_gss/auth_gss.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -541,9 +541,13 @@ gss_setup_upcall(struct gss_auth *gss_au
+               return gss_new;
+       gss_msg = gss_add_msg(gss_new);
+       if (gss_msg == gss_new) {
+-              int res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg);
++              int res;
++              atomic_inc(&gss_msg->count);
++              res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg);
+               if (res) {
+                       gss_unhash_msg(gss_new);
++                      atomic_dec(&gss_msg->count);
++                      gss_release_msg(gss_new);
+                       gss_msg = ERR_PTR(res);
+               }
+       } else
+@@ -836,6 +840,7 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg
+                       warn_gssd();
+               gss_release_msg(gss_msg);
+       }
++      gss_release_msg(gss_msg);
+ }
+ static void gss_pipe_dentry_destroy(struct dentry *dir,
diff --git a/queue-4.4/tty-serial-atmel-rs485-half-duplex-w-dma-enable-rx-after-tx-is-done.patch b/queue-4.4/tty-serial-atmel-rs485-half-duplex-w-dma-enable-rx-after-tx-is-done.patch
new file mode 100644 (file)
index 0000000..4f8ec82
--- /dev/null
@@ -0,0 +1,67 @@
+From b389f173aaa1204d6dc1f299082a162eb0491545 Mon Sep 17 00:00:00 2001
+From: Richard Genoud <richard.genoud@gmail.com>
+Date: Tue, 6 Dec 2016 13:05:33 +0100
+Subject: tty/serial: atmel: RS485 half duplex w/DMA: enable RX after TX is done
+
+From: Richard Genoud <richard.genoud@gmail.com>
+
+commit b389f173aaa1204d6dc1f299082a162eb0491545 upstream.
+
+When using RS485 in half duplex, RX should be enabled when TX is
+finished, and stopped when TX starts.
+
+Before commit 0058f0871efe7b01c6 ("tty/serial: atmel: fix RS485 half
+duplex with DMA"), RX was not disabled in atmel_start_tx() if the DMA
+was used. So, collisions could happened.
+
+But disabling RX in atmel_start_tx() uncovered another bug:
+RX was enabled again in the wrong place (in atmel_tx_dma) instead of
+being enabled when TX is finished (in atmel_complete_tx_dma), so the
+transmission simply stopped.
+
+This bug was not triggered before commit 0058f0871efe7b01c6
+("tty/serial: atmel: fix RS485 half duplex with DMA") because RX was
+never disabled before.
+
+Moving atmel_start_rx() in atmel_complete_tx_dma() corrects the problem.
+
+Reported-by: Gil Weber <webergil@gmail.com>
+Fixes: 0058f0871efe7b01c6
+Tested-by: Gil Weber <webergil@gmail.com>
+Signed-off-by: Richard Genoud <richard.genoud@gmail.com>
+Acked-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Signed-off-by: Alexandre Belloni <alexandre.belloni@free-electrons.com>
+Tested-by: Bryan Evenson <bevenson@melinkcorp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/tty/serial/atmel_serial.c |   11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- a/drivers/tty/serial/atmel_serial.c
++++ b/drivers/tty/serial/atmel_serial.c
+@@ -810,6 +810,11 @@ static void atmel_complete_tx_dma(void *
+        */
+       if (!uart_circ_empty(xmit))
+               tasklet_schedule(&atmel_port->tasklet);
++      else if ((port->rs485.flags & SER_RS485_ENABLED) &&
++               !(port->rs485.flags & SER_RS485_RX_DURING_TX)) {
++              /* DMA done, stop TX, start RX for RS485 */
++              atmel_start_rx(port);
++      }
+       spin_unlock_irqrestore(&port->lock, flags);
+ }
+@@ -912,12 +917,6 @@ static void atmel_tx_dma(struct uart_por
+               desc->callback = atmel_complete_tx_dma;
+               desc->callback_param = atmel_port;
+               atmel_port->cookie_tx = dmaengine_submit(desc);
+-
+-      } else {
+-              if (port->rs485.flags & SER_RS485_ENABLED) {
+-                      /* DMA done, stop TX, start RX for RS485 */
+-                      atmel_start_rx(port);
+-              }
+       }
+       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)