]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
b36c51ce62c549f74454561f66e773b0a81b59c6
[thirdparty/kernel/stable-queue.git] /
1 From cd3b3636c99fcac52c598b64061f3fe4413c6a12 Mon Sep 17 00:00:00 2001
2 From: Oleksij Rempel <linux@rempel-privat.de>
3 Date: Fri, 7 Aug 2020 12:51:57 +0200
4 Subject: can: j1939: transport: j1939_session_tx_dat(): fix use-after-free read in j1939_tp_txtimer()
5
6 From: Oleksij Rempel <o.rempel@pengutronix.de>
7
8 commit cd3b3636c99fcac52c598b64061f3fe4413c6a12 upstream.
9
10 The current stack implementation do not support ECTS requests of not
11 aligned TP sized blocks.
12
13 If ECTS will request a block with size and offset spanning two TP
14 blocks, this will cause memcpy() to read beyond the queued skb (which
15 does only contain one TP sized block).
16
17 Sometimes KASAN will detect this read if the memory region beyond the
18 skb was previously allocated and freed. In other situations it will stay
19 undetected. The ETP transfer in any case will be corrupted.
20
21 This patch adds a sanity check to avoid this kind of read and abort the
22 session with error J1939_XTP_ABORT_ECTS_TOO_BIG.
23
24 Reported-by: syzbot+5322482fe520b02aea30@syzkaller.appspotmail.com
25 Fixes: 9d71dd0c7009 ("can: add support of SAE J1939 protocol")
26 Cc: linux-stable <stable@vger.kernel.org> # >= v5.4
27 Signed-off-by: Oleksij Rempel <o.rempel@pengutronix.de>
28 Link: https://lore.kernel.org/r/20200807105200.26441-3-o.rempel@pengutronix.de
29 Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
30 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
31
32 ---
33 net/can/j1939/transport.c | 15 +++++++++++++++
34 1 file changed, 15 insertions(+)
35
36 --- a/net/can/j1939/transport.c
37 +++ b/net/can/j1939/transport.c
38 @@ -787,6 +787,18 @@ static int j1939_session_tx_dat(struct j
39 if (len > 7)
40 len = 7;
41
42 + if (offset + len > se_skb->len) {
43 + netdev_err_once(priv->ndev,
44 + "%s: 0x%p: requested data outside of queued buffer: offset %i, len %i, pkt.tx: %i\n",
45 + __func__, session, skcb->offset, se_skb->len , session->pkt.tx);
46 + return -EOVERFLOW;
47 + }
48 +
49 + if (!len) {
50 + ret = -ENOBUFS;
51 + break;
52 + }
53 +
54 memcpy(&dat[1], &tpdat[offset], len);
55 ret = j1939_tp_tx_dat(session, dat, len + 1);
56 if (ret < 0) {
57 @@ -1120,6 +1132,9 @@ static enum hrtimer_restart j1939_tp_txt
58 * cleanup including propagation of the error to user space.
59 */
60 break;
61 + case -EOVERFLOW:
62 + j1939_session_cancel(session, J1939_XTP_ABORT_ECTS_TOO_BIG);
63 + break;
64 case 0:
65 session->tx_retry = 0;
66 break;