#628005 netstat -p parses commandline wrong

Package:
net-tools
Source:
net-tools
Description:
NET-3 networking toolkit
Submitter:
Jörg Sommer
Date:
2011-09-21 00:45:03 UTC
Severity:
normal
#628005#5
Date:
2011-05-26 10:50:20 UTC
From:
To:
Hi,

dictd sets the commandline to »dictd 1.12.0: 0/0« and netstat -tlp says:

tcp        0      0 localhost:dict          *:*                     LISTEN      1351/0

The command name is wrong.

Here is script to reproduce it:

% perl -W <<\__EOP
use IO::Socket;

my $s = new IO::Socket::INET(
  LocalHost => 'localhost',
  LocalPort => '32221',
  Proto => 'tcp',
  Listen => 1,
  Reuse => 1)
  || die "Could not create socket: $!\n";

$0 = 'xxx 1.2.3: 0/0';

system("netstat -ntpl 2>/dev/null |grep 32221; cat /proc/$$/cmdline");
print "\n";
__EOP
tcp        0      0 127.0.0.1:32221         0.0.0.0:*               LISTEN      7816/0
xxx 1.2.3: 0/0

Bye, Jörg

#628005#10
Date:
2011-09-21 00:43:12 UTC
From:
To:
Remember that NUL is the word separator in process command lines.
(Apply "hexdump -C /proc/23456/cmdline".)

Netstat is conceived to print the command name, not the title,
thus displaying a single string of __printable__ characters.
Technical disection if the source code will reveal a call to
strrchr() inside netstat.c/prg_cache_load(), which will
stop looking further than the first NUL character, and
which in fact appear soon enough.

Something like the difference reproduced below, would indeed
produce what the bug reporter desires, but I see very little
reason to commend such a change. It discloses too much info
for the general process.
--- netstat.c.debian +++ netstat.c @@ -405,6 +405,7 @@ static void prg_cache_load(void) continue; if (!cmdlp) { + int j; if (procfdlen - PATH_FD_SUFFl + PATH_CMDLINEl >= sizeof(line) - 5) continue; @@ -419,6 +420,9 @@ static void prg_cache_load(void) continue; if (cmdllen < sizeof(cmdlbuf) - 1) cmdlbuf[cmdllen]='\0'; + for (j = 0; j < cmdllen; ++j) + if (cmdlbuf[j] == '\0') + cmdlbuf[j] = ' '; if ((cmdlp = strrchr(cmdlbuf, '/'))) cmdlp++; else