mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
xfrm4: Fix uninitialized memory read in _decode_session4
[ Upstream commit8742dc86d0] We currently don't reload pointers pointing into skb header after doing pskb_may_pull() in _decode_session4(). So in case pskb_may_pull() changed the pointers, we read from random memory. Fix this by putting all the needed infos on the stack, so that we don't need to access the header pointers after doing pskb_may_pull(). Fixes:1da177e4c3("Linux-2.6.12-rc2") Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
cb7adeca5d
commit
d569023171
@@ -111,7 +111,8 @@ static void
|
||||
_decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
|
||||
{
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
u8 *xprth = skb_network_header(skb) + iph->ihl * 4;
|
||||
int ihl = iph->ihl;
|
||||
u8 *xprth = skb_network_header(skb) + ihl * 4;
|
||||
struct flowi4 *fl4 = &fl->u.ip4;
|
||||
int oif = 0;
|
||||
|
||||
@@ -122,6 +123,11 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
|
||||
fl4->flowi4_mark = skb->mark;
|
||||
fl4->flowi4_oif = reverse ? skb->skb_iif : oif;
|
||||
|
||||
fl4->flowi4_proto = iph->protocol;
|
||||
fl4->daddr = reverse ? iph->saddr : iph->daddr;
|
||||
fl4->saddr = reverse ? iph->daddr : iph->saddr;
|
||||
fl4->flowi4_tos = iph->tos;
|
||||
|
||||
if (!ip_is_fragment(iph)) {
|
||||
switch (iph->protocol) {
|
||||
case IPPROTO_UDP:
|
||||
@@ -133,7 +139,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
|
||||
pskb_may_pull(skb, xprth + 4 - skb->data)) {
|
||||
__be16 *ports;
|
||||
|
||||
xprth = skb_network_header(skb) + iph->ihl * 4;
|
||||
xprth = skb_network_header(skb) + ihl * 4;
|
||||
ports = (__be16 *)xprth;
|
||||
|
||||
fl4->fl4_sport = ports[!!reverse];
|
||||
@@ -146,7 +152,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
|
||||
pskb_may_pull(skb, xprth + 2 - skb->data)) {
|
||||
u8 *icmp;
|
||||
|
||||
xprth = skb_network_header(skb) + iph->ihl * 4;
|
||||
xprth = skb_network_header(skb) + ihl * 4;
|
||||
icmp = xprth;
|
||||
|
||||
fl4->fl4_icmp_type = icmp[0];
|
||||
@@ -159,7 +165,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
|
||||
pskb_may_pull(skb, xprth + 4 - skb->data)) {
|
||||
__be32 *ehdr;
|
||||
|
||||
xprth = skb_network_header(skb) + iph->ihl * 4;
|
||||
xprth = skb_network_header(skb) + ihl * 4;
|
||||
ehdr = (__be32 *)xprth;
|
||||
|
||||
fl4->fl4_ipsec_spi = ehdr[0];
|
||||
@@ -171,7 +177,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
|
||||
pskb_may_pull(skb, xprth + 8 - skb->data)) {
|
||||
__be32 *ah_hdr;
|
||||
|
||||
xprth = skb_network_header(skb) + iph->ihl * 4;
|
||||
xprth = skb_network_header(skb) + ihl * 4;
|
||||
ah_hdr = (__be32 *)xprth;
|
||||
|
||||
fl4->fl4_ipsec_spi = ah_hdr[1];
|
||||
@@ -183,7 +189,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
|
||||
pskb_may_pull(skb, xprth + 4 - skb->data)) {
|
||||
__be16 *ipcomp_hdr;
|
||||
|
||||
xprth = skb_network_header(skb) + iph->ihl * 4;
|
||||
xprth = skb_network_header(skb) + ihl * 4;
|
||||
ipcomp_hdr = (__be16 *)xprth;
|
||||
|
||||
fl4->fl4_ipsec_spi = htonl(ntohs(ipcomp_hdr[1]));
|
||||
@@ -196,7 +202,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
|
||||
__be16 *greflags;
|
||||
__be32 *gre_hdr;
|
||||
|
||||
xprth = skb_network_header(skb) + iph->ihl * 4;
|
||||
xprth = skb_network_header(skb) + ihl * 4;
|
||||
greflags = (__be16 *)xprth;
|
||||
gre_hdr = (__be32 *)xprth;
|
||||
|
||||
@@ -213,10 +219,6 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse)
|
||||
break;
|
||||
}
|
||||
}
|
||||
fl4->flowi4_proto = iph->protocol;
|
||||
fl4->daddr = reverse ? iph->saddr : iph->daddr;
|
||||
fl4->saddr = reverse ? iph->daddr : iph->saddr;
|
||||
fl4->flowi4_tos = iph->tos;
|
||||
}
|
||||
|
||||
static void xfrm4_update_pmtu(struct dst_entry *dst, struct sock *sk,
|
||||
|
||||
Reference in New Issue
Block a user