]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.9.179/xfrm4-fix-uninitialized-memory-read-in-_decode_sessi.patch
Linux 4.14.122
[thirdparty/kernel/stable-queue.git] / releases / 4.9.179 / xfrm4-fix-uninitialized-memory-read-in-_decode_sessi.patch
1 From ad0a82646e23903711e29db3bd04179997b47a80 Mon Sep 17 00:00:00 2001
2 From: Steffen Klassert <steffen.klassert@secunet.com>
3 Date: Tue, 26 Feb 2019 07:04:50 +0100
4 Subject: xfrm4: Fix uninitialized memory read in _decode_session4
5
6 [ Upstream commit 8742dc86d0c7a9628117a989c11f04a9b6b898f3 ]
7
8 We currently don't reload pointers pointing into skb header
9 after doing pskb_may_pull() in _decode_session4(). So in case
10 pskb_may_pull() changed the pointers, we read from random
11 memory. Fix this by putting all the needed infos on the
12 stack, so that we don't need to access the header pointers
13 after doing pskb_may_pull().
14
15 Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
16 Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
17 Signed-off-by: Sasha Levin <sashal@kernel.org>
18 ---
19 net/ipv4/xfrm4_policy.c | 24 +++++++++++++-----------
20 1 file changed, 13 insertions(+), 11 deletions(-)
21
22 diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
23 index 622e158a6fc40..1805413cd2251 100644
24 --- a/net/ipv4/xfrm4_policy.c
25 +++ b/net/ipv4/xfrm4_policy.c
26 @@ -108,7 +108,8 @@ static void
27 _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
28 {
29 const struct iphdr *iph = ip_hdr(skb);
30 - u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
31 + int ihl = iph->ihl;
32 + u8 *xprth = skb_network_header(skb) + ihl * 4;
33 struct flowi4 *fl4 = &fl->u.ip4;
34 int oif = 0;
35
36 @@ -119,6 +120,11 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
37 fl4->flowi4_mark = skb->mark;
38 fl4->flowi4_oif = reverse ? skb->skb_iif : oif;
39
40 + fl4->flowi4_proto = iph->protocol;
41 + fl4->daddr = reverse ? iph->saddr : iph->daddr;
42 + fl4->saddr = reverse ? iph->daddr : iph->saddr;
43 + fl4->flowi4_tos = iph->tos;
44 +
45 if (!ip_is_fragment(iph)) {
46 switch (iph->protocol) {
47 case IPPROTO_UDP:
48 @@ -130,7 +136,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
49 pskb_may_pull(skb, xprth + 4 - skb->data)) {
50 __be16 *ports;
51
52 - xprth = skb_network_header(skb) + iph->ihl * 4;
53 + xprth = skb_network_header(skb) + ihl * 4;
54 ports = (__be16 *)xprth;
55
56 fl4->fl4_sport = ports[!!reverse];
57 @@ -143,7 +149,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
58 pskb_may_pull(skb, xprth + 2 - skb->data)) {
59 u8 *icmp;
60
61 - xprth = skb_network_header(skb) + iph->ihl * 4;
62 + xprth = skb_network_header(skb) + ihl * 4;
63 icmp = xprth;
64
65 fl4->fl4_icmp_type = icmp[0];
66 @@ -156,7 +162,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
67 pskb_may_pull(skb, xprth + 4 - skb->data)) {
68 __be32 *ehdr;
69
70 - xprth = skb_network_header(skb) + iph->ihl * 4;
71 + xprth = skb_network_header(skb) + ihl * 4;
72 ehdr = (__be32 *)xprth;
73
74 fl4->fl4_ipsec_spi = ehdr[0];
75 @@ -168,7 +174,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
76 pskb_may_pull(skb, xprth + 8 - skb->data)) {
77 __be32 *ah_hdr;
78
79 - xprth = skb_network_header(skb) + iph->ihl * 4;
80 + xprth = skb_network_header(skb) + ihl * 4;
81 ah_hdr = (__be32 *)xprth;
82
83 fl4->fl4_ipsec_spi = ah_hdr[1];
84 @@ -180,7 +186,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
85 pskb_may_pull(skb, xprth + 4 - skb->data)) {
86 __be16 *ipcomp_hdr;
87
88 - xprth = skb_network_header(skb) + iph->ihl * 4;
89 + xprth = skb_network_header(skb) + ihl * 4;
90 ipcomp_hdr = (__be16 *)xprth;
91
92 fl4->fl4_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
93 @@ -193,7 +199,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
94 __be16 *greflags;
95 __be32 *gre_hdr;
96
97 - xprth = skb_network_header(skb) + iph->ihl * 4;
98 + xprth = skb_network_header(skb) + ihl * 4;
99 greflags = (__be16 *)xprth;
100 gre_hdr = (__be32 *)xprth;
101
102 @@ -210,10 +216,6 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
103 break;
104 }
105 }
106 - fl4->flowi4_proto = iph->protocol;
107 - fl4->daddr = reverse ? iph->saddr : iph->daddr;
108 - fl4->saddr = reverse ? iph->daddr : iph->saddr;
109 - fl4->flowi4_tos = iph->tos;
110 }
111
112 static inline int xfrm4_garbage_collect(struct dst_ops *ops)
113 --
114 2.20.1
115