chiark / gitweb /
bootchart: fix a potential buffer overrun
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 30 Mar 2013 23:34:23 +0000 (19:34 -0400)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 31 Mar 2013 18:34:08 +0000 (14:34 -0400)
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.

src/bootchart/bootchart.c
src/bootchart/store.c

index 052e6370c98ebe83a8e76853b13e2aefaba87111..208c4528e76f127683abb014c566e50081efb84b 100644 (file)
@@ -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 */
index 343365e6126e1d948489c30bc478b1bbddfbda19..b2652c8d936fc0145cf274502308de102e5815be 100644 (file)
@@ -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];