Bug#222073: bug found... it is in libgtop

bugs.debian.org@mukesh.agrawals.org, 222073@bugs.debian.org bugs.debian.org@mukesh.agrawals.org, 222073@bugs.debian.org
Wed, 8 Dec 2004 18:50:56 -0500 (EST)


I went hunting for the bug, and found it is actually in libgtop.

libgtop incorrectly parses /proc/<pid>/maps files. The bug is in
sysdeps/linux/procmap.c, in the glibtop_get_proc_map_s function.

Here is the errant code:

 		fn [0] = fgetc (maps);

 		if (fn [0] != '\n' && fn [0] != EOF) {

 			fscanf (maps, "%*[ ]%[^\n]\n", fn);

 		} else fn [0] = 0;

At this point, glibtop_get_proc_map_s has read all of the fields from
the current entry in /proc/<pid>/maps, except for the filename. (These
fields are start, end, flags, offset, dev_major, dev_minor, and inode.)

The function reads on more character, and if it is not a newline, or EOF,
sucks up any whitespace, and reads the rest of the line as the name of the
mapped file.

The problem is that, at least with my kernel version (2.6.4) the format of
the maps entry is

for regular mappings:
 	<other fields><space><space><space><space><space><space><filename>
for anonymous mappings:
 	<other fields><space>\n

So the function reads the space into fn[0], then decides that since fn[0]
is not a newline or EOF, there must be a valid filename in the entry. In
fact, the next character is a newline, and there is no valid filename. The
fscanf will read no valid fields, and leave fn unmodified.

So the filename associated with this entry will be whatever the
previous entry's filename was, except that the first character will be
overwritten with a space.

(Too bad they didn't the author didn't check the return value of fscanf...
That would have caught this bug.)

The quick fix would be to call fgetc twice -- one to suck up the
always-present space, and then a second time to implement the current
check. I don't know, however, if this would work with other kernel
versions.

A better solution might be found by consulting pmap.c in procps.

This bug is present in both libgtop 1.0.13-8, and libgtop2 2.6.0-4.
(Including the diffs.)