1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-07 21:21:31 +00:00

Handle case of corrupted TCP options with length 0. Fixes #2104

This commit is contained in:
dmiller
2020-08-18 20:36:12 +00:00
parent 12b17ee758
commit cfff367aa6
2 changed files with 9 additions and 10 deletions

View File

@@ -1,5 +1,9 @@
#Nmap Changelog ($Id$); -*-text-*- #Nmap Changelog ($Id$); -*-text-*-
o [GH#2104] Fixed parsing of TCP options which would hang (infinite loop) if an
option had an explicit length of 0. Affects Nmap 7.80 only.
[Daniel Miller, Imed Mnif]
o [NSE][GH#2105] Fetching of SSH2 keys might fail because of key exchange o [NSE][GH#2105] Fetching of SSH2 keys might fail because of key exchange
confusion [nnposter] confusion [nnposter]

View File

@@ -1365,13 +1365,14 @@ static bool validateTCPhdr(const u8 *tcpc, unsigned len) {
optlen = hdrlen - sizeof(struct tcp_hdr); optlen = hdrlen - sizeof(struct tcp_hdr);
#define OPTLEN_IS(expected) do { \ #define OPTLEN_IS(expected) do { \
if (optlen < (expected) || *++tcpc != (expected)) \ if (expected == 0 || optlen < (expected) || hdrlen != (expected)) \
return false; \ return false; \
optlen -= (expected); \ optlen -= (expected); \
tcpc += (expected) - 1; \ tcpc += (expected) - 1; \
} while(0); } while(0);
while (optlen > 0) { while (optlen > 0) {
hdrlen = *++tcpc;
switch (*tcpc) { switch (*tcpc) {
case 0: // EOL case 0: // EOL
/* Options processing is over. */ /* Options processing is over. */
@@ -1391,12 +1392,9 @@ static bool validateTCPhdr(const u8 *tcpc, unsigned len) {
OPTLEN_IS(2); OPTLEN_IS(2);
break; break;
case 5: /* SACK */ case 5: /* SACK */
if (optlen < *++tcpc) if (!(hdrlen - 2) || ((hdrlen - 2) % 8))
return false; return false;
if (!(*tcpc - 2) || ((*tcpc - 2) % 8)) OPTLEN_IS(hdrlen);
return false;
optlen -= *tcpc;
tcpc += (*tcpc - 1);
break; break;
case 8: /* Timestamp */ case 8: /* Timestamp */
OPTLEN_IS(10); OPTLEN_IS(10);
@@ -1408,10 +1406,7 @@ static bool validateTCPhdr(const u8 *tcpc, unsigned len) {
OPTLEN_IS(3); OPTLEN_IS(3);
break; break;
default: default:
if (optlen < 2 || optlen < *++tcpc) OPTLEN_IS(hdrlen);
return false;
optlen -= *tcpc;
tcpc += (*tcpc - 1);
break; break;
} }
} }