Hi all, someone has described a remote DoS vulnerability in many telnetd implementations that I just happened to stumble over:
https://pierrekim.github.io/blog/2022-08-24-2-byte-dos-freebsd-netbsd-telnetd-netkit-telnetd-inetutils-telnetd-kerberos-telnetd.html The vulnerability is a NULL pointer dereference when reading either of two two byte sequences: 1: 0xff 0xf7 2: 0xff 0xf8 The blog shows GNU Inetutils' telnetd as vulnerable: https://pierrekim.github.io/blog/2022-08-24-2-byte-dos-freebsd-netbsd-telnetd-netkit-telnetd-inetutils-telnetd-kerberos-telnetd.html#remote-dos-inetutils The blog post analyzes the issue as using a table before this table has been initialized: https://pierrekim.github.io/blog/2022-08-24-2-byte-dos-freebsd-netbsd-telnetd-netkit-telnetd-inetutils-telnetd-kerberos-telnetd.html#remote-dos-root-cause-analysis They show a patch against the FreeBSD 13.1 version of telnetd to fix the two code paths, i.e., check for NULL and don't dereference a NULL pointer. Since that might omit setting a variable before its use, they add an initialization for said variable. The FreeBSD patch works on different lines than need to be changed in GNU Inetutils' telnetd, so it cannot apply as is. In GNU Inetutils, the code lines to dereference table entries without first checking for NULL are in lines 321 and 323 of file "telnetd/state.c". The variable "ch" declared in line 315 of this file needs to be initialized to "(cc_t) (_POSIX_VDISABLE)", because it may not be assigned any value if the table is not yet initialized. References:line 315: https://git.savannah.gnu.org/cgit/inetutils.git/tree/telnetd/state.c#n315 line 321: https://git.savannah.gnu.org/cgit/inetutils.git/tree/telnetd/state.c#n321 line 323: https://git.savannah.gnu.org/cgit/inetutils.git/tree/telnetd/state.c#n323
I have attached a completely untested, not even compile tested, patch to do this (just the code changes, no NEWS or commit log or anything). Please test before committing. They write that they do not intend to contact the maintainers: https://pierrekim.github.io/blog/2022-08-24-2-byte-dos-freebsd-netbsd-telnetd-netkit-telnetd-inetutils-telnetd-kerberos-telnetd.html#full-disclosure Thus this email. Thanks, Erik
diff --git a/telnetd/state.c b/telnetd/state.c index ffc6cbaf..c2d760f8 100644 --- a/telnetd/state.c +++ b/telnetd/state.c @@ -312,15 +312,21 @@ telrcv (void) case EC: case EL: { - cc_t ch; + cc_t ch = (cc_t) (_POSIX_VDISABLE); DEBUG (debug_options, 1, printoption ("td: recv IAC", c)); ptyflush (); /* half-hearted */ init_termbuf (); if (c == EC) - ch = *slctab[SLC_EC].sptr; + { + if (slctab[SLC_EC].sptr) + ch = *slctab[SLC_EC].sptr; + } else - ch = *slctab[SLC_EL].sptr; + { + if (slctab[SLC_EL].sptr) + ch = *slctab[SLC_EL].sptr; + } if (ch != (cc_t) (_POSIX_VDISABLE)) pty_output_byte ((unsigned char) ch); break;