Hi!
On Tue, 2026-03-17 at 05:15:58 +0200, Justin Swartz wrote:
> I've identified two bugs in the debugging support provided by
> telnetd that may be combined to achieve local privilege escalation
> or arbitrary file corruption.
> INSECURE TEMPORARY FILE CREATION
>
> The first issue involves a hardcoded filename for the debug log
> initiated by telnetd/utility.c's debug_open():
>
> static int
> debug_open (void)
> {
> int um = umask (077);
> if (!debug_fp)
> debug_fp = fopen ("/tmp/telnet.debug", "a");
> umask (um);
> return debug_fp == NULL;
> }
>
> Relying on a predictable filename in a world-writable directory
> such as /tmp opens the door to symbolic link attacks.
>
> Assuming the file doesn't already exist, any unprivileged user can
> pre-emptively create a symbolic link named "/tmp/telnet.debug" and
> point it at a sensitive file owned by root, or whoever else might
> be responsible for spawning telnetd.
>
> If telnetd is executed with the -D flag, to enable debugging support,
> the daemon will blindly follow the symbolic link and append debugging
> output to whatever "/tmp/telnet.debug" points at.
While preparing a Debian inetutils revision to fix all the remaining
publicly reported security issues, I stumbled into what seems like a
worse problem from the described root cause.
A user can pre-create the file, and then keep a read file descriptor
to snoop any on-wire credentials. The changes in
<https://codeberg.org/inetutils/inetutils/pulls/20> do not help
because even changing the permissions (and the ownership which the PR
does not do), is not effective for an already open file descriptor.
> POTENTIAL MITIGATION
>
> While this sort of symbolic link attack in a sticky directory is
> usually mitigated by default on many Linux distributions that have
> fs.protected_symlinks=1 in their sysctl configuration, it's unwise
> to rely on operating system controls to mask defective application
> logic.
The problem above also affects Linux on its default configuration. I
guess it could be mitigated by creating an empty file owned by root
with 0600 permissions, at boot time (although I'd find that annoying
and my first reaction would be to assume it was a leftover file from
the daemon which didn't clean properly).
I don't think the proposal to dump the entire protocol into syslog
seem like a great idea either, which would require substantial
sanitization. Instead for Debian I went with a relatively simple
change from using «/tmp/telnet-debug» to «/run/telnet/debug.<PID>»,
and made telnetd print the pathname used on the telnet session.
I suppose an alternative could be to let the telnetd user specify a
filename to use. But the /run switch seems good enough to me.
Thanks,
Guillem