pmap: Fix extended mode in one_proc().

Check the return value of sscanf() to make sure that all input items are
properly initialized.

In extended mode (x_option), one_proc() loads the values of start and
perms during one iteration of the while loop, and displays them during
one of the following iterations, but start and perms are variables local
to the while loop: move them out of the while loop, to the beginning of
the function.

Also, display a mapping only if cp2 is properly initialized; otherwise
(for example), mappings that do not belong to a selected range are
displayed, and with a NULL mapping name:

$ pmap -x -A 6FFF00000000,7FFF00000000 $$
...
Address           Kbytes     RSS   Dirty Mode  Mapping
000055b3d1e9b000       0     912       0  r-xp (null)
000055b3d2194000       0      16      16  r--p (null)
000055b3d2198000       0      36      36  rw-p (null)
...
This commit is contained in:
Qualys Security Advisory 1970-01-01 00:00:00 +00:00 committed by Craig Small
parent 6e4eade3d4
commit 8476e6f4f9

21
pmap.c
View File

@ -509,14 +509,17 @@ loop_end:
/* We don't free() the list, it's used for all PIDs passed as arguments */ /* We don't free() the list, it's used for all PIDs passed as arguments */
} }
static int one_proc(proc_t * p) static int one_proc(const proc_t * p)
{ {
char buf[32]; char buf[32];
FILE *fp; FILE *fp;
unsigned long total_shared = 0ul; unsigned long total_shared = 0ul;
unsigned long total_private_readonly = 0ul; unsigned long total_private_readonly = 0ul;
unsigned long total_private_writeable = 0ul; unsigned long total_private_writeable = 0ul;
unsigned KLONG start = 0;
unsigned KLONG diff = 0; unsigned KLONG diff = 0;
unsigned KLONG end = 0;
char perms[32] = "";
const char *cp2 = NULL; const char *cp2 = NULL;
unsigned long long rss = 0ull; unsigned long long rss = 0ull;
unsigned long long private_dirty = 0ull; unsigned long long private_dirty = 0ull;
@ -584,10 +587,8 @@ static int one_proc(proc_t * p)
} }
while (fgets(mapbuf, sizeof mapbuf, fp)) { while (fgets(mapbuf, sizeof mapbuf, fp)) {
char perms[32];
/* to clean up unprintables */ /* to clean up unprintables */
char *tmp; char *tmp;
unsigned KLONG start, end;
unsigned long long file_offset, inode; unsigned long long file_offset, inode;
unsigned dev_major, dev_minor; unsigned dev_major, dev_minor;
unsigned long long smap_value; unsigned long long smap_value;
@ -613,8 +614,8 @@ static int one_proc(proc_t * p)
continue; continue;
} }
if (strcmp("Swap", smap_key) == 0) { if (strcmp("Swap", smap_key) == 0) {
/*doesn't matter as long as last */ /* doesn't matter as long as last */
printf("%0*" KLF "x %*lu %*llu %*llu %*s %s\n", if (cp2) printf("%0*" KLF "x %*lu %*llu %*llu %*s %s\n",
maxw1, start, maxw1, start,
maxw2, (unsigned long)(diff >> 10), maxw2, (unsigned long)(diff >> 10),
maxw3, rss, maxw3, rss,
@ -623,16 +624,18 @@ static int one_proc(proc_t * p)
cp2); cp2);
/* reset some counters */ /* reset some counters */
rss = shared_dirty = private_dirty = 0ull; rss = shared_dirty = private_dirty = 0ull;
diff = 0; start = diff = end = 0;
perms[0] = '\0';
cp2 = NULL;
continue; continue;
} }
} }
/* Other keys or not a key-value pair */ /* Other keys or not a key-value pair */
continue; continue;
} }
sscanf(mapbuf, "%" KLF "x-%" KLF "x %31s %llx %x:%x %llu", &start, if (sscanf(mapbuf, "%" KLF "x-%" KLF "x %31s %llx %x:%x %llu", &start,
&end, perms, &file_offset, &dev_major, &dev_minor, &end, perms, &file_offset, &dev_major, &dev_minor, &inode) != 7)
&inode); continue;
if (end - 1 < range_low) if (end - 1 < range_low)
continue; continue;