]> granicus.if.org Git - gc/commitdiff
Workaround 'array compared to 0', 'untrusted loop bound' false defects
authorIvan Maidanski <ivmai@mail.ru>
Mon, 22 May 2017 22:01:08 +0000 (01:01 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Tue, 23 May 2017 22:31:07 +0000 (01:31 +0300)
(Cherry-pick commit 36038e1 from 'master' branch.)

* dyn_load.c [SOLARISDL && !USE_PROC_FOR_LIBRARIES]
(GC_FirstDLOpenedLinkMap): Wrap access to dynStructureAddr (which value
obtained from a weak symbol) into COVERT_DATAFLOW() in comparison to 0.
* dyn_load.c [HAVE_DL_ITERATE_PHDR && !DL_ITERATE_PHDR_STRONG]
(GC_register_main_static_data): Wrap access to dl_iterate_phdr weak
symbol into COVERT_DATAFLOW() in comparison to 0.
* dyn_load.c [HAVE_DL_ITERATE_PHDR] (GC_FirstDLOpenedLinkMap): Wrap
access to _DYNAMIC weak symbol into COVERT_DATAFLOW() in comparison to 0.
* include/private/gc_priv.h (TRUSTED_STRING): Pass the argument through
COVERT_DATAFLOW.
* include/private/gcconfig.h (COVERT_DATAFLOW): New macro.
* os_dep.c [SEARCH_FOR_DATA_START] (GC_init_linux_data_start): Wrap
access to __data_start and GC_data_start into COVERT_DATAFLOW() in
comparison to 0.
* tests/disclaim_bench.c: Update comment for include gc_priv.h.
* tests/disclaim_bench.c (main): Pass the integer value obtained from
command-line argument (and which is used as a loop boundary) through
COVERT_DATAFLOW().
* tests/test_cpp.cc (main): Likewise.

dyn_load.c
include/private/gc_priv.h
include/private/gcconfig.h
os_dep.c
tests/disclaim_bench.c
tests/test_cpp.cc

index 124f6848e9d40e090eb30431858a866d2c223770..8813e03bd953a90fd43e5f3764223466b2f5ab00 100644 (file)
@@ -185,7 +185,7 @@ GC_FirstDLOpenedLinkMap(void)
         dynStructureAddr = &_DYNAMIC;
 #   endif
 
-    if (dynStructureAddr == 0) {
+    if (0 == COVERT_DATAFLOW(dynStructureAddr)) {
         /* _DYNAMIC symbol not resolved. */
         return(0);
     }
@@ -564,7 +564,7 @@ GC_INNER GC_bool GC_register_main_static_data(void)
     /* zero (otherwise a compiler might issue a warning).               */
     return FALSE;
 # else
-    return (dl_iterate_phdr == 0); /* implicit conversion to function ptr */
+    return 0 == COVERT_DATAFLOW(dl_iterate_phdr);
 # endif
 }
 
@@ -694,7 +694,7 @@ GC_FirstDLOpenedLinkMap(void)
 {
     static struct link_map *cachedResult = 0;
 
-    if (0 == (ptr_t)_DYNAMIC) {
+    if (0 == COVERT_DATAFLOW(_DYNAMIC)) {
         /* _DYNAMIC symbol not resolved. */
         return(0);
     }
index 4afd8eca15bde05b351cc92bc7af7bbea20ab6d5..f750a3db6d813c0c3bb63fd0dda70f35aa577577 100644 (file)
@@ -601,7 +601,7 @@ GC_EXTERN GC_warn_proc GC_current_warn_proc;
 /* A tagging macro (for a code static analyzer) to indicate that the    */
 /* string obtained from an untrusted source (e.g., argv[], getenv) is   */
 /* safe to use in a vulnerable operation (e.g., open, exec).            */
-#define TRUSTED_STRING(s) (s)
+#define TRUSTED_STRING(s) (char*)COVERT_DATAFLOW(s)
 
 /* Get environment entry */
 #ifdef GC_READ_ENV_FILE
index 12f0e0113151afae6d56eae76ac56a346adf93aa..77bc00af07367f3e512eb51886c6a84e7a972c60 100644 (file)
 #   include <stddef.h>  /* For size_t etc. */
 # endif
 
+#ifdef LINT2
+  /* A macro (based on a tricky expression) to prevent false warnings   */
+  /* like "Array compared to 0", "Comparison of identical expressions", */
+  /* "Untrusted loop bound" output by some static code analysis tools.  */
+  /* The argument should not be a literal value.  The result is         */
+  /* converted to word type.  (Actually, GC_word is used instead of     */
+  /* word type as the latter might be undefined at the place of use.)   */
+# define COVERT_DATAFLOW(w) (~(GC_word)(w)^(~(GC_word)0))
+#else
+# define COVERT_DATAFLOW(w) ((GC_word)(w))
+#endif
+
 /* Machine dependent parameters.  Some tuning parameters can be found   */
 /* near the top of gc_private.h.                                        */
 
index 960826bb49c39ca33184d4774bb65cc948df6a19..84f9e8b084ae80867dfc3e451ad9f8cf0b02a9aa 100644 (file)
--- a/os_dep.c
+++ b/os_dep.c
@@ -439,12 +439,12 @@ GC_INNER char * GC_get_maps(void)
 #         endif
         } else
 #     endif
-      /* else */ if ((ptr_t)__data_start != 0) {
+      /* else */ if (COVERT_DATAFLOW(__data_start) != 0) {
         GC_data_start = (ptr_t)(__data_start);
       } else {
         GC_data_start = (ptr_t)(data_start);
       }
-      if (GC_data_start != NULL) {
+      if (COVERT_DATAFLOW(GC_data_start) != 0) {
         if ((word)GC_data_start > (word)data_end)
           ABORT_ARG2("Wrong __data_start/_end pair",
                      ": %p .. %p", (void *)GC_data_start, (void *)data_end);
index 7ae1f3e5095509e0927594fe3f0437034b536856..cf9523245500b6943b2115cd269eca5be0ec4c6a 100644 (file)
@@ -24,7 +24,7 @@
 
 /* Include gc_priv.h is done after including GC public headers, so      */
 /* that GC_BUILD has no effect on the public prototypes.                */
-#include "private/gc_priv.h" /* for CLOCK_TYPE and GC_random */
+#include "private/gc_priv.h" /* for CLOCK_TYPE, COVERT_DATAFLOW, GC_random */
 
 #ifdef LINT2
 # undef rand
@@ -112,7 +112,7 @@ int main(int argc, char **argv)
         return 1;
     }
     if (argc == 2) {
-        model_min = model_max = atoi(argv[1]);
+        model_min = model_max = (int)COVERT_DATAFLOW(atoi(argv[1]));
         if (model_min < 0 || model_max > 2)
             exit(2);
     }
index 55c7778bc3763e6f6dd6dbd6c0089188fa6e7f0b..4e912edea50aebff99628eefb2c139e63f6ddc99 100644 (file)
@@ -274,11 +274,7 @@ void* Undisguise( GC_word i ) {
       x = 0;
 #   endif
     if (argc != 2
-        || (n = atoi(argv[1])) <= 0
-#       ifdef LINT2
-          || n >= (int)(~0U >> 1) - 1
-#       endif
-       ) {
+        || (n = (int)COVERT_DATAFLOW(atoi(argv[1]))) <= 0) {
       GC_printf("usage: test_cpp number-of-iterations\n"
                 "Assuming 10 iters\n");
       n = 10;