| From foo@baz Sat Dec 5 21:06:41 PST 2015 |
| From: Sowmini Varadhan <sowmini.varadhan@oracle.com> |
| Date: Mon, 26 Oct 2015 12:46:37 -0400 |
| Subject: RDS-TCP: Recover correctly from pskb_pull()/pksb_trim() failure in rds_tcp_data_recv |
| |
| From: Sowmini Varadhan <sowmini.varadhan@oracle.com> |
| |
| [ Upstream commit 8ce675ff39b9958d1c10f86cf58e357efaafc856 ] |
| |
| Either of pskb_pull() or pskb_trim() may fail under low memory conditions. |
| If rds_tcp_data_recv() ignores such failures, the application will |
| receive corrupted data because the skb has not been correctly |
| carved to the RDS datagram size. |
| |
| Avoid this by handling pskb_pull/pskb_trim failure in the same |
| manner as the skb_clone failure: bail out of rds_tcp_data_recv(), and |
| retry via the deferred call to rds_send_worker() that gets set up on |
| ENOMEM from rds_tcp_read_sock() |
| |
| Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com> |
| Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/rds/tcp_recv.c | 11 +++++++++-- |
| 1 file changed, 9 insertions(+), 2 deletions(-) |
| |
| --- a/net/rds/tcp_recv.c |
| +++ b/net/rds/tcp_recv.c |
| @@ -234,8 +234,15 @@ static int rds_tcp_data_recv(read_descri |
| } |
| |
| to_copy = min(tc->t_tinc_data_rem, left); |
| - pskb_pull(clone, offset); |
| - pskb_trim(clone, to_copy); |
| + if (!pskb_pull(clone, offset) || |
| + pskb_trim(clone, to_copy)) { |
| + pr_warn("rds_tcp_data_recv: pull/trim failed " |
| + "left %zu data_rem %zu skb_len %d\n", |
| + left, tc->t_tinc_data_rem, skb->len); |
| + kfree_skb(clone); |
| + desc->error = -ENOMEM; |
| + goto out; |
| + } |
| skb_queue_tail(&tinc->ti_skb_list, clone); |
| |
| rdsdebug("skb %p data %p len %d off %u to_copy %zu -> " |