Bug 133834 - [patch] chat(8): terminate()/fatal() infinity mutual recursion
Summary: [patch] chat(8): terminate()/fatal() infinity mutual recursion
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: 7.1-STABLE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs mailing list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2009-04-18 10:10 UTC by mitrohin a.s.
Modified: 2019-01-24 06:12 UTC (History)
1 user (show)

See Also:


Attachments
file.diff (1022 bytes, patch)
2009-04-18 10:10 UTC, mitrohin a.s.
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description mitrohin a.s. 2009-04-18 10:10:01 UTC
	I have a small program, which collected data from the switches. It uses telnet 
and chat, to carry out a dialogue. If telnet is completed before the chat will be held 
all of their expectations and answer script, the chat is infinite recursion.

Fix: $ gdb /usr/bin/chat chat.core 
GNU gdb 6.1.1 [FreeBSD]
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-marcel-freebsd"...
Core was generated by `chat'.
Program terminated with signal 3, Quit.
Reading symbols from /lib/libc.so.7...done.
Loaded symbols for /lib/libc.so.7
Reading symbols from /libexec/ld-elf.so.1...done.
oaded symbols for /libexec/ld-elf.so.1
#0  0x4813e0e7 in sendto () from /lib/libc.so.7
n sendto () from /lib/libc.so.7
#1  0x4813ccee in send () from /lib/libc.so.7
#2  0x48137eb7 in vsyslog () from /lib/libc.so.7
#3  0x48137b9e in syslog () from /lib/libc.so.7
#4  0x08049433 in fatal (code=2, fmt=0x804bb40 "Can't restore terminal parameters: %m") at /usr/src/usr.bin/chat/chat.c:429
#5  0x08049832 in terminate (status=2) at /usr/src/usr.bin/chat/chat.c:544
#6  0x08049464 in fatal (code=2, fmt=0x804bb40 "Can't restore terminal parameters: %m") at /usr/src/usr.bin/chat/chat.c:432
#7  0x08049832 in terminate (status=2) at /usr/src/usr.bin/chat/chat.c:544
#8  0x08049464 in fatal (code=2, fmt=0x804bb40 "Can't restore terminal parameters: %m") at /usr/src/usr.bin/chat/chat.c:432
#9  0x08049832 in terminate (status=2) at /usr/src/usr.bin/chat/chat.c:544
...


chat.c
...
/*
 *      Print an error message and terminate.
 */

void
fatal(int code, const char *fmt, ...)
{
    va_list args;

    va_start(args, fmt);
    vfmtmsg(line, sizeof(line), fmt, args);
    if (to_log)
        syslog(LOG_ERR, "%s", line);
    if (to_stderr)
        fprintf(stderr, "%s\n", line);
    terminate(code);
}
...
void terminate(int status)
{
    echo_stderr(-1);
    if (report_file != (char *) 0 && report_fp != (FILE *) NULL) {
/*
 * Allow the last of the report string to be gathered before we terminate.
 */
        if (report_gathering) {
            int c;
            size_t rep_len;

            rep_len = strlen(report_buffer);
            while (rep_len + 1 <= sizeof(report_buffer)) {
                alarm(1);
                c = get_char();
                alarm(0);
                if (c < 0 || iscntrl(c))
                    break;
                report_buffer[rep_len] = c;
                ++rep_len;
            }
            report_buffer[rep_len] = 0;
            fprintf (report_fp, "chat:  %s\n", report_buffer);
        }
        if (verbose)
            fprintf (report_fp, "Closing \"%s\".\n", report_file);
        fclose (report_fp);
        report_fp = (FILE *) NULL;
    }

#if defined(get_term_param)
    if (have_tty_parameters) {
        if (set_term_param (&saved_tty_parameters) < 0)
            fatal(2, "Can't restore terminal parameters: %m");
    }
#endif

    exit(status);
}
...


small fix
How-To-Repeat: 1. Enable telnetd on localhost.
2. Compile program a.c

#include <stdio.h>
#include <stdlib.h>
#include <err.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <libutil.h>

int
main(int argc, char *argv[], char *envp[])
{
        pid_t pid;
        int fd;

        pid = forkpty(&fd, 0, 0, 0);
        if (!pid) {
                execl("/usr/bin/telnet", "telnet", argv[1], 0);
                err(1, "telnet %s", argv[1]);
        }
        if (pid < 0)
                err(1, "forkpty()");
        if (dup2(1, 2) < 0)
                err(1, "dup2(1, 2)");
        if (dup2(fd, 0) < 0)
                err(1, "dup2(fd, 0)");
        if (dup2(fd, 1) < 0)
                err(1, "dup2(fd, 1)");
        close(fd);
        *++argv = "chat";
        execve("/usr/bin/chat", argv, envp);
        err(1, "chat");
}

$ gcc a.c -lutil

3. Run shell command
	./a.out 127.0.0.1 -e 'User' xxx 'Password:' xxxxxxxxxx '$' exit '$' exit

Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
Trying SRA secure login:
User (root): Password: 
[ SRA accepts you ]

FreeBSD/i386 (swp.pp.ru) (ttypm)

Last login: Sat Apr 18 15:11:52 from localhost
Copyright (c) 1992-2009 The FreeBSD Project.
Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
^IThe Regents of the University of California. All rights reserved.

FreeBSD 7.1-STABLE (kernconf-freebsd7-20081220-2) #1: Sat Jan 10 16:45:33 NOVT 2009

Welcome to FreeBSD!

Before seeking technical support, please use the following resources:

o  Security advisories and updated errata information for all releases are
   at http://www.FreeBSD.org/releases/ - always consult the ERRATA section
   for your release first as it's updated frequently.

o  The Handbook and FAQ documents are at http://www.FreeBSD.org/ and,
   along with the mailing lists, can be searched by going to
   http://www.FreeBSD.org/search/.  If the doc distribution has
   been installed, they're also available formatted in /usr/share/doc.

If you still have a question or problem, please take the output of
`uname -a', along with any relevant error messages, and email it
as a question to the questions@FreeBSD.org mailing list.  If you are
unfamiliar with FreeBSD's directory layout, please refer to the hier(7)
manual page.  If you are not familiar with manual pages, type `man man'.

You may also use sysinstall(8) to re-enter the installation and
configuration utility.  Edit /etc/motd to change this login announcement.

You have new mail.
Need to see the calendar for this month? Simply type "cal".  To see the
whole year, type "cal -y".
^I^I-- Dru <genesis@istar.ca>
[swp@swp ~]$ exit
logout
Connection closed by foreign host.
load: 0.46  cmd: chat 56662 [runnable] 1.55u 0.80s 3% 5236k
load: 0.46  cmd: chat 56662 [runnable] 1.63u 0.83s 3% 5448k
load: 0.46  cmd: chat 56662 [runnable] 1.70u 0.89s 3% 5664k
load: 0.46  cmd: chat 56662 [runnable] 1.76u 0.91s 3% 5836k
load: 0.46  cmd: chat 56662 [runnable] 1.85u 0.94s 3% 6052k
load: 0.46  cmd: chat 56662 [runnable] 1.91u 0.99s 3% 6264k
load: 0.46  cmd: chat 56662 [runnable] 1.98u 1.04s 3% 6480k
^\Quit (core dumped)
Comment 1 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 07:59:30 UTC
For bugs matching the following criteria:

Status: In Progress Changed: (is less than) 2014-06-01

Reset to default assignee and clear in-progress tags.

Mail being skipped