forked from pool/s390-tools
72 lines
2.7 KiB
Diff
72 lines
2.7 KiB
Diff
|
Subject: mon_procd: fix parsing of /proc/<pid>/stat
|
||
|
From: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||
|
|
||
|
Description: mon_procd: fix parsing of /proc/<pid>/stat
|
||
|
Symptom: Wrong data from /proc/<pid>/stat for processes that contain
|
||
|
a ")" in their name.
|
||
|
Problem: The output of /proc/<pid>/stat will show the process name in
|
||
|
parentheses. The parsing code in read_stat() tries to filter
|
||
|
out the parentheses, which will go wrong when the process name
|
||
|
itself also contains parentheses, e.g. in an output like this:
|
||
|
"2421 ((sd-pam)) S 2420 2420 2420 ..."
|
||
|
In this case, the first closing parentheses will be taken as
|
||
|
end marker, and the sscanf() on the remaining string will
|
||
|
silently fail, leaving its values in uninitialized state and
|
||
|
producing wrong data.
|
||
|
Solution: Use strrchr() instead of strchr() to find the last closing
|
||
|
parentheses. Also add return value checking for sscanf() and
|
||
|
initialize the values to 0.
|
||
|
Reproduction: Use mon_procd on a system with running processes that have a
|
||
|
")" in their name, like "(sd-pam)".
|
||
|
Upstream-ID: -
|
||
|
Problem-ID: 169483
|
||
|
|
||
|
Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
|
||
|
---
|
||
|
mon_tools/mon_procd.c | 13 ++++++++-----
|
||
|
1 file changed, 8 insertions(+), 5 deletions(-)
|
||
|
|
||
|
--- a/mon_tools/mon_procd.c
|
||
|
+++ b/mon_tools/mon_procd.c
|
||
|
@@ -594,17 +594,18 @@ static void cal_task_pcpu(struct task_t
|
||
|
*/
|
||
|
static int read_stat(struct task_t *task)
|
||
|
{
|
||
|
- int ppid, tty, proc;
|
||
|
- unsigned long flags, pri, nice;
|
||
|
- unsigned long long maj_flt, utime, stime, cutime, cstime;
|
||
|
+ unsigned long long maj_flt = 0, utime = 0, stime = 0, cutime = 0,
|
||
|
+ cstime = 0;
|
||
|
+ unsigned long flags = 0, pri = 0, nice = 0;
|
||
|
char *cmd_start, *cmd_end, *cmdlenp, *cmdp;
|
||
|
+ int ppid = 0, tty = 0, proc = 0, rc;
|
||
|
|
||
|
snprintf(fname, sizeof(fname), "/proc/%u/stat", task->pid);
|
||
|
if (read_file(fname, buf, sizeof(buf) - 1) == -1)
|
||
|
return 0;
|
||
|
|
||
|
cmd_start = strchr(buf, '(') + 1;
|
||
|
- cmd_end = strchr(cmd_start, ')');
|
||
|
+ cmd_end = strrchr(cmd_start, ')');
|
||
|
name_lens.cmd_len = cmd_end - cmd_start;
|
||
|
cmdlenp = mon_record + sizeof(struct monwrite_hdr);
|
||
|
cmdlenp += sizeof(struct procd_hdr);
|
||
|
@@ -625,7 +626,7 @@ static int read_stat(struct task_t *task
|
||
|
memcpy(cmdlenp, &name_lens.cmd_len, sizeof(__u16));
|
||
|
|
||
|
cmd_end += 2;
|
||
|
- sscanf(cmd_end,
|
||
|
+ rc = sscanf(cmd_end,
|
||
|
"%c %d %*d %*d %d %*d "
|
||
|
"%lu %*s %*s %Lu %*s "
|
||
|
"%Lu %Lu %Lu %Lu "
|
||
|
@@ -642,6 +643,8 @@ static int read_stat(struct task_t *task
|
||
|
&utime, &stime, &cutime, &cstime,
|
||
|
&pri, &nice,
|
||
|
&proc);
|
||
|
+ if (rc != 12)
|
||
|
+ syslog(LOG_ERR, "bad data in %s \n", fname);
|
||
|
task->ppid = (__u32)ppid;
|
||
|
task->tty = (__u16)tty;
|
||
|
task->flags = (__u32)flags;
|