From: Daniel Lenski Date: Tue, 27 Mar 2018 15:39:58 +0000 (-0700) Subject: check for oversize ESP packets, with 256 bytes of headroom above calculated MTU X-Git-Tag: v8.00~104 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=38a3bbcfcae5b028584f4ccd9a7280379eb0e8a3;p=users%2Fdwmw2%2Fopenconnect.git check for oversize ESP packets, with 256 bytes of headroom above calculated MTU Because GlobalProtect VPNs have no practical mechanism for negotiating the MTU whatsoever, it is entirely based on a client-side guess. Therefore, extra headroom is needed to reliably receive packets via both the HTTPS and the ESP tunnels. A similar patch by Nikolay Martynov was originally applied for the Juniper HTTPS tunnel: http://lists.infradead.org/pipermail/openconnect-devel/2017-May/004320.html And similar functionality was incorporated into the GlobalProtect HTTPS tunnel as well (gpst.c). This patch adds the extra headroom for the ESP tunnel (used by both Juniper and GlobalProtect VPNs) as well, after unexpectedly-large ESP packets were observed "in the wild": https://github.com/dlenski/openconnect/issues/96 Signed-off-by: Dan Lenski Signed-off-by: David Woodhouse --- diff --git a/esp.c b/esp.c index 6a6dd7dc..30de764d 100644 --- a/esp.c +++ b/esp.c @@ -106,6 +106,7 @@ int esp_mainloop(struct openconnect_info *vpninfo, int *timeout) struct esp *esp = &vpninfo->esp_in[vpninfo->current_esp_in]; struct esp *old_esp = &vpninfo->esp_in[vpninfo->current_esp_in ^ 1]; struct pkt *this; + int receive_mtu = MAX(2048, vpninfo->ip_info.mtu + 256); int work_done = 0; int ret; @@ -121,7 +122,7 @@ int esp_mainloop(struct openconnect_info *vpninfo, int *timeout) return 0; while (1) { - int len = vpninfo->ip_info.mtu + vpninfo->pkt_trailer; + int len = receive_mtu + vpninfo->pkt_trailer; int i; struct pkt *pkt; @@ -202,8 +203,8 @@ int esp_mainloop(struct openconnect_info *vpninfo, int *timeout) } } if (pkt->data[len - 1] == 0x05) { - struct pkt *newpkt = malloc(sizeof(*pkt) + vpninfo->ip_info.mtu + vpninfo->pkt_trailer); - int newlen = vpninfo->ip_info.mtu; + struct pkt *newpkt = malloc(sizeof(*pkt) + receive_mtu + vpninfo->pkt_trailer); + int newlen = receive_mtu; if (!newpkt) { vpn_progress(vpninfo, PRG_ERR, _("Failed to allocate memory to decrypt ESP packet\n")); @@ -216,7 +217,7 @@ int esp_mainloop(struct openconnect_info *vpninfo, int *timeout) free(newpkt); continue; } - newpkt->len = vpninfo->ip_info.mtu - newlen; + newpkt->len = receive_mtu - newlen; vpn_progress(vpninfo, PRG_TRACE, _("LZO decompressed %d bytes into %d\n"), len - 2 - pkt->data[len-2], newpkt->len);