Hi, the function makeargv() in telnet/commands.c is used to build an array of arguments for command invocation. This array has a fixed size of 20. The entry after the last argument is set to 0. Thus the array can take up to 19 arguments. But there is no check if there are more than 19 arguments.
The "help" command takes an arbitrary number of arguments and prints the help text of each argument that matches a command: $ telnet/telnet telnet> help z ! ? suspend telnet invoke a subshell print help information telnet> q $ This works fine for up to 18 arguments to the "help" command, i.e., up to 19 arguments with a terminating "0" entry in the *margv[20] array: $ telnet/telnet telnet> help z ! ? z ! ? z ! ? z ! ? z ! ? z ! ? suspend telnet invoke a subshell print help information suspend telnet invoke a subshell print help information suspend telnet invoke a subshell print help information suspend telnet invoke a subshell print help information suspend telnet invoke a subshell print help information suspend telnet invoke a subshell print help information telnet> q $ Adding another argument overflows the *margv[20] array by one entry. This writes a 0 right after the array. At least on my system (Ubuntu GNU/Linux 18.04.06 LTS with gcc 7.5.0) this overwrites the margc variable, setting it to 0. Thus no help text is printed: $ telnet/telnet telnet> help z ! ? z ! ? z ! ? z ! ? z ! ? z ! ? z telnet> q $ Adding another argument results in a higher value for margc. This results in reading past the end of the *margv[20] array, leading to a segmentation fault: $ telnet/telnet telnet> help z ! ? z ! ? z ! ? z ! ? z ! ? z ! ? z ! suspend telnet invoke a subshell print help information suspend telnet invoke a subshell print help information suspend telnet invoke a subshell print help information suspend telnet invoke a subshell print help information suspend telnet invoke a subshell print help information suspend telnet invoke a subshell print help information suspend telnet Segmentation fault (core dumped) $ The attached patch fixes this. HTH, Erik -- Reality is that which, when you stop believing in it, doesn't go away. -- Philip K. Dick
diff --git a/telnet/commands.c b/telnet/commands.c index 9e04944f..b4626676 100644 --- a/telnet/commands.c +++ b/telnet/commands.c @@ -132,10 +132,12 @@ typedef struct int needconnect; /* Do we need to be connected to execute? */ } Command; +#define TELNET_MAX_ARGS 20 + static char line[256]; static char saveline[256]; static int margc; -static char *margv[20]; +static char *margv[TELNET_MAX_ARGS]; static void makeargv (void) @@ -159,6 +161,11 @@ makeargv (void) c = *++cp; if (c == '\0') break; + if (margc + 1 >= TELNET_MAX_ARGS) + { + fprintf (stderr, "Ignoring excess arguments\n."); + break; + } *argp++ = cp; margc += 1; for (cp2 = cp; c != '\0'; c = *++cp)