]> granicus.if.org Git - procps-ng/commitdiff
library: protect against possible 'refcount' underflow
authorJim Warner <james.warner@comcast.net>
Tue, 22 Nov 2016 15:10:10 +0000 (10:10 -0500)
committerCraig Small <csmall@enc.com.au>
Wed, 7 Dec 2016 11:06:59 +0000 (22:06 +1100)
In each module employing a priming read at 'new' time,
should that read fail, a call to 'unref' will be made.

However, there is a hidden dependency that these calls
must never occur before the context 'refcount' was set
due to the way an 'unref' conditional was constructed.

So this commit just ensures that 'unref' will function
as expected, even if called with a 'refcount' of zero.

Signed-off-by: Jim Warner <james.warner@comcast.net>
proc/diskstats.c
proc/meminfo.c
proc/pids.c
proc/slabinfo.c
proc/stat.c
proc/vmstat.c

index 2aafa3d4d5d75cd49f45fc2cd95033af49ebfa0a..ff5fcddf894df747f03d87e734adb4c44eb564ef 100644 (file)
@@ -800,7 +800,8 @@ PROCPS_EXPORT int procps_diskstats_unref (
         return -EINVAL;
 
     (*info)->refcount--;
-    if ((*info)->refcount == 0) {
+
+    if ((*info)->refcount < 1) {
         if ((*info)->diskstats_fp) {
             fclose((*info)->diskstats_fp);
             (*info)->diskstats_fp = NULL;
@@ -828,7 +829,6 @@ PROCPS_EXPORT int procps_diskstats_unref (
 
         free(*info);
         *info = NULL;
-
         return 0;
     }
     return (*info)->refcount;
index 53d4e46f23239f455f3bd237827897c8a7a2db8d..549b03405df6fc91ceab7b4bf43a2c3434c35287 100644 (file)
@@ -778,14 +778,16 @@ PROCPS_EXPORT int procps_meminfo_unref (
 {
     if (info == NULL || *info == NULL)
         return -EINVAL;
+
     (*info)->refcount--;
 
-    if ((*info)->refcount == 0) {
+    if ((*info)->refcount < 1) {
         if ((*info)->extents)
             meminfo_extents_free_all((*info));
         if ((*info)->items)
             free((*info)->items);
         hdestroy_r(&(*info)->hashtab);
+
         free(*info);
         *info = NULL;
         return 0;
index 446add3fbacdbb64b926f1ac2d9aa7f195018d3e..1a0d0b3db92dc4b5f9497fad8c7681bef1a077f0 100644 (file)
@@ -1180,7 +1180,8 @@ PROCPS_EXPORT int procps_pids_unref (
         return -EINVAL;
 
     (*info)->refcount--;
-    if ((*info)->refcount == 0) {
+
+    if ((*info)->refcount < 1) {
 #ifdef UNREF_RPTHASH
         pids_unref_rpthash(*info);
 #endif
index 02f84280d94f1bec6b3acb293937098639eea108..97933128c57f27fe3eeaf6fc70121daeab2bb138 100644 (file)
@@ -843,7 +843,8 @@ PROCPS_EXPORT int procps_slabinfo_unref (
         return -EINVAL;
 
     (*info)->refcount--;
-    if ((*info)->refcount == 0) {
+
+    if ((*info)->refcount < 1) {
         if ((*info)->slabinfo_fp) {
             fclose((*info)->slabinfo_fp);
             (*info)->slabinfo_fp = NULL;
@@ -867,7 +868,6 @@ PROCPS_EXPORT int procps_slabinfo_unref (
 
         free(*info);
         *info = NULL;
-
         return 0;
     }
     return (*info)->refcount;
index 4d0989a529d3a4f05a273d5b5bacb0a4339cdf0b..9eccb1337b02fe518c9c28938b52f22b34c3dc6e 100644 (file)
@@ -901,9 +901,10 @@ PROCPS_EXPORT int procps_stat_unref (
 {
     if (info == NULL || *info == NULL)
         return -EINVAL;
+
     (*info)->refcount--;
 
-    if ((*info)->refcount == 0) {
+    if ((*info)->refcount < 1) {
         if ((*info)->cpus.anchor)
             free((*info)->cpus.anchor);
         if ((*info)->cpus.result.stacks)
index 5cd49c3d4e045ec717f945ae8e0d267f1072cbec..e012777bcd0d3ddb4ccceb01c9976580e220d267 100644 (file)
@@ -1162,14 +1162,16 @@ PROCPS_EXPORT int procps_vmstat_unref (
 {
     if (info == NULL || *info == NULL)
         return -EINVAL;
+
     (*info)->refcount--;
 
-    if ((*info)->refcount == 0) {
+    if ((*info)->refcount < 1) {
         if ((*info)->extents)
             vmstat_extents_free_all((*info));
         if ((*info)->items)
             free((*info)->items);
         hdestroy_r(&(*info)->hashtab);
+
         free(*info);
         *info = NULL;
         return 0;