]> git.itanic.dy.fi Git - rrdd/commitdiff
onewire_parser: Fix double free corruption
authorTimo Kokkonen <timo.t.kokkonen@iki.fi>
Wed, 26 Oct 2016 17:19:12 +0000 (20:19 +0300)
committerTimo Kokkonen <timo.t.kokkonen@iki.fi>
Wed, 26 Oct 2016 17:19:12 +0000 (20:19 +0300)
If there is a failure while reading a sensor value, the pointer
pointing to the destination buffer is undefined. In that case we might
be referring to a previously freed pointer and possibly corrupting
data somewhere else. The heap area might also be already allocated for
something else and freeing it here, making the heap area available to
yet another allocation and further corruptions. This leads to random
and hard to reproduce crashes in various unrelated components.

Fix the issue by initializing the pointer value with NULL. Also avoid
using it when we expect it to be NULL after a failure. Also we are not
passing the NULL pointer to free(), even though calling free on NULL
is bening.

Signed-off-by: Timo Kokkonen <timo.t.kokkonen@iki.fi>
onewire_parser.c

index f07f7d9d45e095943d2a65f39dce6da87ce62ec6..12e3f5bf09c440ab0cebf06af87c394c1fa6f8e9 100644 (file)
@@ -173,6 +173,7 @@ undefined:
                        int fail, j;
                        char *tmp2;
 
+                       tmp = NULL;
                        pr_info("Reading data for entry %s with offset of %.2f\n",
                                ow_path, offset);
 
@@ -186,7 +187,10 @@ undefined:
                        for (j = 0; j < ret && *tmp2 == ' '; j++)
                                tmp2++;
 
-                       fail = !strncmp(tmp2, "85", 2);
+                       if (ret > 0)
+                               fail = !strncmp(tmp2, "85", 2);
+                       else
+                               fail = 1;
 
                        /*
                         * In case of failure, retry with uncached
@@ -206,7 +210,8 @@ undefined:
                                goto undefined;
                        }
                        retries++;
-                       free(tmp);
+                       if (tmp)
+                               free(tmp);
                }
 
                /* The data from OWNET_read appears to not be NULL terminated */