123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131 |
- From 99afdd5ecd787e40f06473304125eee93139031a Mon Sep 17 00:00:00 2001
- From: Michal Ruprich <michalruprich@gmail.com>
- Date: Sun, 12 Apr 2020 22:41:50 +0200
- Subject: [PATCH 53/60] telnetd: Fix arbitrary remote code execution via short
- writes or urgent data
- Fixes: CVE-2020-10188
- Closes: #956084
- Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2020-10188
- Patch-Origin: Fedora / RedHat
- Patch-URL: https://src.fedoraproject.org/rpms/telnet/raw/master/f/telnet-0.17-overflow-exploit.patch
- ---
- telnetd/telnetd.h | 2 +-
- telnetd/utility.c | 35 ++++++++++++++++++++++-------------
- 2 files changed, 23 insertions(+), 14 deletions(-)
- diff --git a/telnetd/telnetd.h b/telnetd/telnetd.h
- index 044025d2..fa970e24 100644
- --- a/telnetd/telnetd.h
- +++ b/telnetd/telnetd.h
- @@ -271,7 +271,7 @@ void io_drain (void);
-
- int stilloob (int s);
- void ptyflush (void);
- -char *nextitem (char *current);
- +char *nextitem (char *current, const char *endp);
- void netclear (void);
- void netflush (void);
-
- diff --git a/telnetd/utility.c b/telnetd/utility.c
- index db93c205..c9df8a79 100644
- --- a/telnetd/utility.c
- +++ b/telnetd/utility.c
- @@ -484,10 +484,14 @@ stilloob (int s)
- * character.
- */
- 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)
- {
- @@ -495,19 +499,20 @@ nextitem (char *current)
- case DONT:
- case WILL:
- case WONT:
- - return current + 3;
- + return current + 3 <= endp ? current + 3 : NULL;
-
- case SB: /* loop forever looking for the SE */
- {
- char *look = current + 2;
-
- - for (;;)
- - if ((*look++ & 0xff) == IAC && (*look++ & 0xff) == SE)
- + while (look < endp)
- + if ((*look++ & 0xff) == IAC && look < endp && (*look++ & 0xff) == SE)
- return look;
-
- - default:
- - return current + 2;
- + return NULL;
- }
- + default:
- + return current + 2 <= endp ? current + 2 : NULL;
- }
- } /* end of nextitem */
-
- @@ -529,8 +534,9 @@ nextitem (char *current)
- * us in any case.
- */
- #define wewant(p) \
- - ((nfrontp > p) && ((*p&0xff) == IAC) && \
- - ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL))
- + ((nfrontp > p) && ((*p & 0xff) == IAC) && \
- + (nfrontp > p + 1 && (((*(p + 1) & 0xff) != EC) && \
- + ((*(p + 1)&0xff) != EL))))
-
-
- void
- @@ -545,7 +551,7 @@ netclear (void)
- thisitem = netobuf;
- #endif /* ENCRYPTION */
-
- - while ((next = nextitem (thisitem)) <= nbackp)
- + while ((next = nextitem (thisitem, nbackp)) != NULL && next <= nbackp)
- thisitem = next;
-
- /* Now, thisitem is first before/at boundary. */
- @@ -556,15 +562,18 @@ netclear (void)
- good = netobuf; /* where the good bytes go */
- #endif /* ENCRYPTION */
-
- - while (nfrontp > thisitem)
- + while (thisitem != NULL && nfrontp > thisitem)
- {
- if (wewant (thisitem))
- {
- int length;
-
- - for (next = thisitem; wewant (next) && nfrontp > next;
- - next = nextitem (next))
- + for (next = thisitem;
- + next != NULL && wewant (next) && nfrontp > next;
- + next = nextitem (next, nfrontp))
- ;
- + if (next == NULL)
- + next = nfrontp;
-
- length = next - thisitem;
- memmove (good, thisitem, length);
- @@ -573,7 +582,7 @@ netclear (void)
- }
- else
- {
- - thisitem = nextitem (thisitem);
- + thisitem = nextitem (thisitem, nfrontp);
- }
- }
-
- --
- 2.26.0.292.g33ef6b2f38
|