| From 6ab007dbb1958371abff2eaaad2b26da89b3c74e Mon Sep 17 00:00:00 2001 | 
 | From: Yi Zhao <yi.zhao@windriver.com> | 
 | Date: Fri, 24 Apr 2020 09:43:44 +0800 | 
 | Subject: [PATCH] telnetd/utility.c: fix CVE-2020-10188 | 
 |  | 
 | Upstream-Status: Backport | 
 | [Fedora: https://src.fedoraproject.org/rpms/telnet/raw/master/f/telnet-0.17-overflow-exploit.patch] | 
 |  | 
 | CVE: CVE-2020-10188 | 
 |  | 
 | Signed-off-by: Yi Zhao <yi.zhao@windriver.com> | 
 | --- | 
 |  telnetd/utility.c | 32 +++++++++++++++++++++----------- | 
 |  1 file changed, 21 insertions(+), 11 deletions(-) | 
 |  | 
 | diff --git a/telnetd/utility.c b/telnetd/utility.c | 
 | index 75314cb..b9a46a6 100644 | 
 | --- a/telnetd/utility.c | 
 | +++ b/telnetd/utility.c | 
 | @@ -169,31 +169,38 @@ void 	ptyflush(void) | 
 |   */ | 
 |  static | 
 |  char * | 
 | -nextitem(char *current) | 
 | +nextitem(char *current, const char *endp) | 
 |  { | 
 | +    if (current >= endp) { | 
 | +        return NULL; | 
 | +    } | 
 |      if ((*current&0xff) != IAC) { | 
 |  	return current+1; | 
 |      } | 
 | +    if (current+1 >= endp) { | 
 | +        return NULL; | 
 | +    } | 
 |      switch (*(current+1)&0xff) { | 
 |      case DO: | 
 |      case DONT: | 
 |      case WILL: | 
 |      case WONT: | 
 | -	return current+3; | 
 | +	return current+3 <= endp ? current+3 : NULL; | 
 |      case SB:		/* loop forever looking for the SE */ | 
 |  	{ | 
 |  	    register char *look = current+2; | 
 |   | 
 | -	    for (;;) { | 
 | +	    while (look < endp) { | 
 |  		if ((*look++&0xff) == IAC) { | 
 | -		    if ((*look++&0xff) == SE) { | 
 | +		    if (look < endp && (*look++&0xff) == SE) { | 
 |  			return look; | 
 |  		    } | 
 |  		} | 
 |  	    } | 
 | +	    return NULL; | 
 |  	} | 
 |      default: | 
 | -	return current+2; | 
 | +	return current+2 <= endp ? current+2 : NULL; | 
 |      } | 
 |  }  /* end of nextitem */ | 
 |   | 
 | @@ -219,7 +226,7 @@ void netclear(void) | 
 |      register char *thisitem, *next; | 
 |      char *good; | 
 |  #define	wewant(p)	((nfrontp > p) && ((*p&0xff) == IAC) && \ | 
 | -				((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL)) | 
 | +				(nfrontp > p+1 && (((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL)))) | 
 |   | 
 |  #if	defined(ENCRYPT) | 
 |      thisitem = nclearto > netobuf ? nclearto : netobuf; | 
 | @@ -227,7 +234,7 @@ void netclear(void) | 
 |      thisitem = netobuf; | 
 |  #endif | 
 |   | 
 | -    while ((next = nextitem(thisitem)) <= nbackp) { | 
 | +    while ((next = nextitem(thisitem, nbackp)) != NULL && next <= nbackp) { | 
 |  	thisitem = next; | 
 |      } | 
 |   | 
 | @@ -239,20 +246,23 @@ void netclear(void) | 
 |      good = netobuf;	/* where the good bytes go */ | 
 |  #endif | 
 |   | 
 | -    while (nfrontp > thisitem) { | 
 | +    while (thisitem != NULL && nfrontp > thisitem) { | 
 |  	if (wewant(thisitem)) { | 
 |  	    int length; | 
 |   | 
 |  	    next = thisitem; | 
 |  	    do { | 
 | -		next = nextitem(next); | 
 | -	    } while (wewant(next) && (nfrontp > next)); | 
 | +		next = nextitem(next, nfrontp); | 
 | +	    } while (next != NULL && wewant(next) && (nfrontp > next)); | 
 | +	    if (next == NULL) { | 
 | +		next = nfrontp; | 
 | +	    } | 
 |  	    length = next-thisitem; | 
 |  	    bcopy(thisitem, good, length); | 
 |  	    good += length; | 
 |  	    thisitem = next; | 
 |  	} else { | 
 | -	    thisitem = nextitem(thisitem); | 
 | +	    thisitem = nextitem(thisitem, nfrontp); | 
 |  	} | 
 |      } | 
 |   | 
 | --  | 
 | 2.7.4 | 
 |  |