[PATCH 3/3] telnet: Avoid command evaluation crashes.

Erik Auerswald <[email protected]>
Newsgroups gmane.comp.gnu.inetutils.bugs
Message-ID <af0432abc89763bcd1b204fa83506aacfb1e911c.1645978829.git.auerswal@unix-ag.uni-kl.de>
Avoid crashing when given unexpected or invalid commands.
Reported by Peter Kasza in
<https://lists.gnu.org/archive/html/bug-inetutils/2017-06/msg00000.html>,
AiDai in
<https://savannah.gnu.org/bugs/?61725> and
<https://savannah.gnu.org/bugs/?61726>,
and ZFeiXQ in
<https://lists.gnu.org/archive/html/bug-inetutils/2021-12/msg00017.html>.

* NEWS: Mention fixes.
* libtelnet/genget.c (genget): Don't accept a single space as
command name.  Return &ambiguous for duplicated command names.
* telnet/commands.c: Define TELNET_MAX_ARGS and use it for *margv[].
(makeargv): Ignore arguments that don't fit into *margv[].
(setcmd): Don't dereference null pointer.
(unsetcmd): Don't dereference null pointer.
(cmdtab2[]): Add help text for help command.
(help): Don't dereference null pointer.
---
 NEWS               |  9 +++++++++
 libtelnet/genget.c |  4 +---
 telnet/commands.c  | 24 +++++++++++++++++++++---
 3 files changed, 31 insertions(+), 6 deletions(-)

diff --git a/NEWS b/NEWS
index 319bb2f9..c0333253 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,15 @@ variable has exactly 44 bytes.  This concerns the CVE-2019-0053 fixes.
 Reported by Erik Auerswald in
 <https://lists.gnu.org/archive/html/bug-inetutils/2022-02/msg00004.html>.
 
+Avoid crashing when given unexpected or invalid commands.  Reported by
+Peter Kasza in
+<https://lists.gnu.org/archive/html/bug-inetutils/2017-06/msg00000.html>,
+AiDai in
+<https://savannah.gnu.org/bugs/?61725>,
+<https://savannah.gnu.org/bugs/?61726>,
+and ZFeiXQ in
+<https://lists.gnu.org/archive/html/bug-inetutils/2021-12/msg00017.html>.
+
 ** Various bugs fixes, internal improvements and clean ups.
 
 Further cleanup of configure.ac, updates to modern autoconf releases,
diff --git a/libtelnet/genget.c b/libtelnet/genget.c
index 6051f7b4..c2b0a37a 100644
--- a/libtelnet/genget.c
+++ b/libtelnet/genget.c
@@ -87,7 +87,7 @@ genget (char *name, char **table, int stlen)
   register char **c, **found;
   register int n;
 
-  if (name == 0)
+  if (name == 0 || (name[0] == ' ' && name[1] == '\0'))
     return 0;
 
   found = 0;
@@ -95,8 +95,6 @@ genget (char *name, char **table, int stlen)
     {
       if ((n = isprefix (name, *c)) == 0)
 	continue;
-      if (n < 0)		/* exact match */
-	return (c);
       if (found)
 	return (&ambiguous);
       found = c;
diff --git a/telnet/commands.c b/telnet/commands.c
index 9e04944f..feb80ab0 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)
@@ -1136,6 +1143,11 @@ setcmd (int argc, char *argv[])
       (*ct->handler) (argv[2]);
       printf ("%s set to \"%s\".\n", ct->name, (char *) ct->charp);
     }
+  else if (!ct->charp)
+    {
+      fprintf (stderr, "'%s': invalid argument ('set ?' for help).\n",
+	       argv[1]);
+    }
   else
     {
       if (strcmp ("off", argv[2]))
@@ -1222,6 +1234,12 @@ unsetcmd (int argc, char *argv[])
 	  (*ct->handler) (0);
 	  printf ("%s reset to \"%s\".\n", ct->name, (char *) ct->charp);
 	}
+      else if (!ct->charp)
+	{
+	  fprintf (stderr, "'%s': invalid argument ('unset ?' for help).\n",
+		   name);
+	  return 0;
+	}
       else
 	{
 	  *(ct->charp) = _POSIX_VDISABLE;
@@ -2931,7 +2949,7 @@ static char crmodhelp[] = "deprecated command -- use 'toggle crmod' instead";
 static char escapehelp[] = "deprecated command -- use 'set escape' instead";
 
 static Command cmdtab2[] = {
-  {"help", 0, help, 0},
+  {"help", helphelp, help, 0},
   {"escape", escapehelp, setescape, 0},
   {"crmod", crmodhelp, togcrmod, 0},
   {NULL, NULL, NULL, 0}
@@ -3090,7 +3108,7 @@ help (int argc, char *argv[])
 	printf ("?Ambiguous help command %s\n", arg);
       else if (c == (Command *) 0)
 	printf ("?Invalid help command %s\n", arg);
-      else
+      else if (c->help)
 	printf ("%s\n", c->help);
     }
   return 0;
-- 
Object-oriented design is the roman numerals of computing.
                        -- Rob Pike
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.