summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2018-12-18 00:13:17 +0100
committerDavid S. Miller <davem@davemloft.net>2018-12-17 21:38:04 -0800
commit11789039da536fea96c98a40c2b441decf2e7323 (patch)
tree68004178117f344d16b990edf36e7a18367aa24f
parenta28777f250311ac574237e6145ac72c7b3b7b049 (diff)
downloadlwn-11789039da536fea96c98a40c2b441decf2e7323.tar.gz
lwn-11789039da536fea96c98a40c2b441decf2e7323.zip
fou: Prevent unbounded recursion in GUE error handler
Handling exceptions for direct UDP encapsulation in GUE (that is, UDP-in-UDP) leads to unbounded recursion in the GUE exception handler, syzbot reported. While draft-ietf-intarea-gue-06 doesn't explicitly forbid direct encapsulation of UDP in GUE, it probably doesn't make sense to set up GUE this way, and it's currently not even possible to configure this. Skip exception handling if the GUE proto/ctype field is set to the UDP protocol number. Should we need to handle exceptions for UDP-in-GUE one day, we might need to either explicitly set a bound for recursion, or implement a special iterative handling for these cases. Reported-and-tested-by: syzbot+43f6755d1c2e62743468@syzkaller.appspotmail.com Fixes: b8a51b38e4d4 ("fou, fou6: ICMP error handlers for FoU and GUE") Signed-off-by: Stefano Brivio <sbrivio@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/ipv4/fou.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index 0d0ad19ecb87..0c9f171fb085 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -1061,6 +1061,13 @@ static int gue_err(struct sk_buff *skb, u32 info)
if (validate_gue_flags(guehdr, optlen))
return -EINVAL;
+ /* Handling exceptions for direct UDP encapsulation in GUE would lead to
+ * recursion. Besides, this kind of encapsulation can't even be
+ * configured currently. Discard this.
+ */
+ if (guehdr->proto_ctype == IPPROTO_UDP)
+ return -EOPNOTSUPP;
+
skb_set_transport_header(skb, -(int)sizeof(struct icmphdr));
ret = gue_err_proto_handler(guehdr->proto_ctype, skb, info);