diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2013-03-30 19:34:23 -0400 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2013-03-31 14:34:08 -0400 |
commit | 522cd7f18bf1e4a024d6771186a0149c5ca8109c (patch) | |
tree | 488e36ebe074c5b1caceb2dcdcfe472e2dbfb692 | |
parent | 4cd5f79d0bf9fb62636485dd36ee961774361c14 (diff) |
bootchart: fix a potential buffer overrun
If the configured number of samples was close to MAXSAMPLES,
the samples buffer could be overrun:
- by 1, because of off-by-one in the condition (samples > arg_samples_len),
and
- by many in case of an overrun, because the number of samples to
capture was increased, instead of being decreased.
Simplify things by converting to a normal for-loop.
In store.c: change buffer size from 4095 to 4096. 4095 is a strange
number.
-rw-r--r-- | src/bootchart/bootchart.c | 14 | ||||
-rw-r--r-- | src/bootchart/store.c | 2 |
2 files changed, 5 insertions, 11 deletions
diff --git a/src/bootchart/bootchart.c b/src/bootchart/bootchart.c index 052e6370c9..208c4528e7 100644 --- a/src/bootchart/bootchart.c +++ b/src/bootchart/bootchart.c @@ -288,7 +288,7 @@ int main(int argc, char *argv[]) { log_uptime(); /* main program loop */ - while (!exiting) { + for (samples = 0; !exiting && samples < arg_samples_len; samples++) { int res; double sample_stop; struct timespec req; @@ -315,7 +315,7 @@ int main(int argc, char *argv[]) { NULL); /* wait for /proc to become available, discarding samples */ - if (!(graph_start > 0.0)) + if (graph_start <= 0.0) log_uptime(); else log_sample(samples); @@ -334,7 +334,7 @@ int main(int argc, char *argv[]) { * we'll lose all the missed samples and overrun our total * time */ - if ((newint_ns > 0) || (newint_s > 0)) { + if (newint_ns > 0 || newint_s > 0) { req.tv_sec = newint_s; req.tv_nsec = newint_ns; @@ -350,14 +350,8 @@ int main(int argc, char *argv[]) { } else { overrun++; /* calculate how many samples we lost and scrap them */ - arg_samples_len = arg_samples_len + ((int)(newint_ns / interval)); + arg_samples_len -= (int)(newint_ns / interval); } - - samples++; - - if (samples > arg_samples_len) - break; - } /* do some cleanup, close fd's */ diff --git a/src/bootchart/store.c b/src/bootchart/store.c index 343365e612..b2652c8d93 100644 --- a/src/bootchart/store.c +++ b/src/bootchart/store.c @@ -114,7 +114,7 @@ static int pid_cmdline_strscpy(char *buffer, size_t buf_len, int pid) { void log_sample(int sample) { static int vmstat; static int schedstat; - char buf[4095]; + char buf[4096]; char key[256]; char val[256]; char rt[256]; |