On Wed, 11 Nov 2020 21:17:40 +0530 parameswaran krishnamurthy <parkr...@gmail.com> wrote:
> Package: telnetd
> Version: 0.17-41
> Severity: serious
>
>
> Problem Statement:
>
> The in.telnetd process is seen to crash on running Nessus security scan.
>
> in.telnetd version:
> telnetd_0.17-41_amd64.deb (Debian stretch image)
>
> /etc/inetd.conf:
> telnet stream tcp6 nowait telnetd /usr/sbin/tcpd /usr/sbin/in.telnetd
>
> Possible root cause:
>
> The telnetd process invokes netflush() to flush() data
>
> root@OS10:# #154080 0x00007f681f34a8d9 in _IO_new_do_write (fp=,
> data=, to_do=1350) at fileops.c:502
> root@OS10:# #154081 0x00007f681f348978 in _IO_new_file_sync
> (fp=0x55a7d9b45150) at fileops.c:882
> root@OS10:# #154082 0x00007f681f33e03c in __GI__IO_fflush
> (fp=0x55a7d9b45150) at iofflush.c:40
> root@OS10:# #154083 0x000055a7d97f95a0 in netflush () at utility.c:325
> root@OS10:# #154084 0x000055a7d97f95d6 in ttloop () at utility.c:81
> root@OS10:# #154085 0x000055a7d97f5c55 in getterminaltype
> (name=0x7ffe09676c70 "") at telnetd.c:484
> root@OS10:# #154086 doit (who_len=16, who=0x7ffe09676bf0) at telnetd.c:722
> root@OS10:# #154087 main (argc=, argv=, env=) at telnetd.c:402
>
> 2)Error is encountered while flushing.This results in invocation of
> cleanup function
>
> oot@OS10:# #154071 0x00007f681f34c4cc in _IO_flush_all_lockp
> (do_lock=do_lock@entry=0) at genops.c:792
> root@OS10:# #154072 0x00007f681f34c695 in _IO_cleanup () at genops.c:957
> root@OS10:# #154073 0x00007f681f30c8e3 in __run_exit_handlers
> (status=0, listp=, run_list_atexit=run_list_atexit@entry=true,
> run_dtors=run_dtors@entry=true) at exit.c:96
> root@OS10:# #154074 0x00007f681f30c99a in __GI_exit (status=) at exit.c:105
> root@OS10:# #154075 0x000055a7d97f8fd2 in cleanup (sig=sig@entry=0) at
> sys_term.c:736
> root@OS10:# #154076 0x000055a7d97f92d0 in netwritebuf () at utility.c:288
> root@OS10:~# #154077 0x000055a7d97f94be in netwrite (cookie=,
>
> 3)The cleanup function invokes exit(0), which in turn trigger flushing
> again. The flushing encounters the error again ,resulting in
> continuous loop.
>
> root@OS10:# #154070 0x00007f681f34a8d9 in _IO_new_do_write (fp=,
> data=, to_do=1350) at fileops.c:502
> root@OS10:# #154071 0x00007f681f34c4cc in _IO_flush_all_lockp
> (do_lock=do_lock@entry=0) at genops.c:792
> root@OS10:# #154072 0x00007f681f34c695 in _IO_cleanup () at genops.c:957
> root@OS10:# #154073 0x00007f681f30c8e3 in __run_exit_handlers
> (status=0, listp=, run_list_atexit=run_list_atexit@entry=true,
> run_dtors=run_dtors@entry=true) at exit.c:96
> root@OS10:# #154074 0x00007f681f30c99a in __GI_exit (status=) at exit.c:105

Noticed the same. Attached a patch to fix this issue.


Description: Infinite recursion on cleanup.
 This is haappening from the handling from "Abort Output"
 command. This causes flushing of "netfile", which in turn
 calls fflush. In this case, the netwritebuf() also fails
 to write the iovec. That in turns calls cleanup(0). This
 leads to another call to fflush() from the atexit handler,
 causing a recursion that never ends as writev() in netwrtebuf()
 keeps on failing.
 
 Fix by chekcing the return from netwritebuf and return error
 to the caller.

Author: Nachiketa Prachanda <nprac...@vyatta.att-mail.com>
Comment: Fix infinite recursion on cleanup
Forwarded: no
Last Update: 2020-11-16

--- a/telnetd/utility.c
+++ b/telnetd/utility.c
@@ -236,7 +236,7 @@
        doclear--;
 }  /* end of netclear */
 
-static void
+static int
 netwritebuf(void)
 {
        struct iovec *vector;
@@ -247,11 +247,11 @@
        int ltrailing = trailing;
 
        if (!listlen)
-               return;
+               return 0;
 
        vector = malloc(listlen * sizeof(struct iovec));
        if (!vector) {
-               return;
+               return -1;
        }
 
        len = listlen - (doclear & ltrailing);
@@ -284,9 +284,12 @@
        free(vector);
 
        if (n < 0) {
-               if (errno != EWOULDBLOCK && errno != EINTR)
-                       cleanup(0);
-               return;
+               if (errno != EWOULDBLOCK && errno != EINTR) {
+                       syslog(LOG_INFO, "telnetd:%s:%d:errno=%d\n", __func__, 
__LINE__, errno);
+                       return -1;
+                       /* cleanup(0); */
+               }
+               return 0;
        }
 
        len = n + skip;
@@ -312,6 +315,7 @@
        }
 
        skip = len;
+       return 0;
 }
 
 /*
@@ -1247,7 +1251,8 @@
                ret += l;
        }
 
-       netwritebuf();
+       if (netwritebuf() < 0)
+               return -1;
        return ret;
 }
 

Reply via email to