]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.4/s390-qeth-fix-use-after-free-in-error-path.patch
Linux 3.18.137
[thirdparty/kernel/stable-queue.git] / queue-4.4 / s390-qeth-fix-use-after-free-in-error-path.patch
1 From 7a52d6ee03c768885b211035c04a1de160575705 Mon Sep 17 00:00:00 2001
2 From: Julian Wiedmann <jwi@linux.ibm.com>
3 Date: Mon, 4 Feb 2019 17:40:07 +0100
4 Subject: s390/qeth: fix use-after-free in error path
5
6 [ Upstream commit afa0c5904ba16d59b0454f7ee4c807dae350f432 ]
7
8 The error path in qeth_alloc_qdio_buffers() that takes care of
9 cleaning up the Output Queues is buggy. It first frees the queue, but
10 then calls qeth_clear_outq_buffers() with that very queue struct.
11
12 Make the call to qeth_clear_outq_buffers() part of the free action
13 (in the correct order), and while at it fix the naming of the helper.
14
15 Fixes: 0da9581ddb0f ("qeth: exploit asynchronous delivery of storage blocks")
16 Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
17 Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
18 Signed-off-by: David S. Miller <davem@davemloft.net>
19 Signed-off-by: Sasha Levin <sashal@kernel.org>
20 ---
21 drivers/s390/net/qeth_core_main.c | 15 ++++++---------
22 1 file changed, 6 insertions(+), 9 deletions(-)
23
24 diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
25 index 533bd2467910..b40604d0126f 100644
26 --- a/drivers/s390/net/qeth_core_main.c
27 +++ b/drivers/s390/net/qeth_core_main.c
28 @@ -2452,11 +2452,12 @@ static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *q, int bidx)
29 return rc;
30 }
31
32 -static void qeth_free_qdio_out_buf(struct qeth_qdio_out_q *q)
33 +static void qeth_free_output_queue(struct qeth_qdio_out_q *q)
34 {
35 if (!q)
36 return;
37
38 + qeth_clear_outq_buffers(q, 1);
39 qdio_free_buffers(q->qdio_bufs, QDIO_MAX_BUFFERS_PER_Q);
40 kfree(q);
41 }
42 @@ -2529,10 +2530,8 @@ static int qeth_alloc_qdio_buffers(struct qeth_card *card)
43 card->qdio.out_qs[i]->bufs[j] = NULL;
44 }
45 out_freeoutq:
46 - while (i > 0) {
47 - qeth_free_qdio_out_buf(card->qdio.out_qs[--i]);
48 - qeth_clear_outq_buffers(card->qdio.out_qs[i], 1);
49 - }
50 + while (i > 0)
51 + qeth_free_output_queue(card->qdio.out_qs[--i]);
52 kfree(card->qdio.out_qs);
53 card->qdio.out_qs = NULL;
54 out_freepool:
55 @@ -2565,10 +2564,8 @@ static void qeth_free_qdio_buffers(struct qeth_card *card)
56 qeth_free_buffer_pool(card);
57 /* free outbound qdio_qs */
58 if (card->qdio.out_qs) {
59 - for (i = 0; i < card->qdio.no_out_queues; ++i) {
60 - qeth_clear_outq_buffers(card->qdio.out_qs[i], 1);
61 - qeth_free_qdio_out_buf(card->qdio.out_qs[i]);
62 - }
63 + for (i = 0; i < card->qdio.no_out_queues; i++)
64 + qeth_free_output_queue(card->qdio.out_qs[i]);
65 kfree(card->qdio.out_qs);
66 card->qdio.out_qs = NULL;
67 }
68 --
69 2.19.1
70