https://bugs.gentoo.org/969065

From fd702c02497b2f398e739e3119bed0b23dd7aa7b Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Tue, 20 Jan 2026 01:10:36 -0800
Subject: [PATCH] Fix injection bug with bogus user names

Problem reported by Kyu Neushwaistein.
* telnetd/utility.c (_var_short_name):
Ignore user names that start with '-' or contain shell metacharacters.

Signed-off-by: Simon Josefsson <simon@josefsson.org>
---
 telnetd/utility.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/telnetd/utility.c b/telnetd/utility.c
index b486226e..c02cd0e6 100644
--- a/telnetd/utility.c
+++ b/telnetd/utility.c
@@ -1733,7 +1733,14 @@ _var_short_name (struct line_expander *exp)
       return user_name ? xstrdup (user_name) : NULL;
 
     case 'U':
-      return getenv ("USER") ? xstrdup (getenv ("USER")) : xstrdup ("");
+      {
+	/* Ignore user names starting with '-' or containing shell
+	   metachars, as they can cause trouble.  */
+	char const *u = getenv ("USER");
+	return xstrdup ((u && *u != '-'
+			 && !u[strcspn (u, "\t\n !\"#$&'()*;<=>?[\\^`{|}~")])
+			? u : "");
+      }
 
     default:
       exp->state = EXP_STATE_ERROR;
From ccba9f748aa8d50a38d7748e2e60362edd6a32cc Mon Sep 17 00:00:00 2001
From: Simon Josefsson <simon@josefsson.org>
Date: Tue, 20 Jan 2026 14:02:39 +0100
Subject: [PATCH] telnetd: Sanitize all variable expansions

* telnetd/utility.c (sanitize): New function.
(_var_short_name): Use it for all variables.
---
 telnetd/utility.c | 32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/telnetd/utility.c b/telnetd/utility.c
index c02cd0e6..b21ad961 100644
--- a/telnetd/utility.c
+++ b/telnetd/utility.c
@@ -1684,6 +1684,17 @@ static void _expand_cond (struct line_expander *exp);
 static void _skip_block (struct line_expander *exp);
 static void _expand_block (struct line_expander *exp);
 
+static char *
+sanitize (const char *u)
+{
+  /* Ignore values starting with '-' or containing shell metachars, as
+     they can cause trouble.  */
+  if (u && *u != '-' && !u[strcspn (u, "\t\n !\"#$&'()*;<=>?[\\^`{|}~")])
+    return u;
+  else
+    return "";
+}
+
 /* Expand a variable referenced by its short one-symbol name.
    Input: exp->cp points to the variable name.
    FIXME: not implemented */
@@ -1710,13 +1721,13 @@ _var_short_name (struct line_expander *exp)
       return xstrdup (timebuf);
 
     case 'h':
-      return xstrdup (remote_hostname);
+      return xstrdup (sanitize (remote_hostname));
 
     case 'l':
-      return xstrdup (local_hostname);
+      return xstrdup (sanitize (local_hostname));
 
     case 'L':
-      return xstrdup (line);
+      return xstrdup (sanitize (line));
 
     case 't':
       q = strchr (line + 1, '/');
@@ -1724,23 +1735,16 @@ _var_short_name (struct line_expander *exp)
 	q++;
       else
 	q = line;
-      return xstrdup (q);
+      return xstrdup (sanitize (q));
 
     case 'T':
-      return terminaltype ? xstrdup (terminaltype) : NULL;
+      return terminaltype ? xstrdup (sanitize (terminaltype)) : NULL;
 
     case 'u':
-      return user_name ? xstrdup (user_name) : NULL;
+      return user_name ? xstrdup (sanitize (user_name)) : NULL;
 
     case 'U':
-      {
-	/* Ignore user names starting with '-' or containing shell
-	   metachars, as they can cause trouble.  */
-	char const *u = getenv ("USER");
-	return xstrdup ((u && *u != '-'
-			 && !u[strcspn (u, "\t\n !\"#$&'()*;<=>?[\\^`{|}~")])
-			? u : "");
-      }
+      return xstrdup (sanitize (getenv ("USER")));
 
     default:
       exp->state = EXP_STATE_ERROR;
