]> The Tcpdump Group git mirrors - tcpdump/commitdiff
C compilers can, and some do, optimize away pointer underflow checks.
authorGuy Harris <[email protected]>
Mon, 2 Mar 2015 21:25:12 +0000 (13:25 -0800)
committerGuy Harris <[email protected]>
Mon, 2 Mar 2015 21:25:12 +0000 (13:25 -0800)
Cast the pointers to uintptr_t; use AC_TYPE_UINTPTR_T to get uintptr_t
defined on older platforms that don't define it themselves.

config.h.in
configure
configure.in
netdissect.h

index 11ce977b5347e826e96db9ad4e03fdfb9e1d3d68..914289a8f9fcb8fb5586f2790130abc13aa44fe4 100644 (file)
 /* Define to 1 if you have the <sys/types.h> header file. */
 #undef HAVE_SYS_TYPES_H
 
+/* Define to 1 if the system has the type `uintptr_t'. */
+#undef HAVE_UINTPTR_T
+
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
 /* Define to the type of an unsigned integer type of width exactly 8 bits if
    such a type exists and the standard includes do not define it. */
 #undef uint8_t
+
+/* Define to the type of an unsigned integer type wide enough to hold a
+   pointer, if such a type exists, and if the system does not define it. */
+#undef uintptr_t
index 293edb14c12ef9ee3b9da82ce81f165f57462d49..43b3068aab43eef0a043c7237ffd4f83f6bc25e3 100755 (executable)
--- a/configure
+++ b/configure
@@ -6997,6 +6997,48 @@ _ACEOF
   esac
 
 
+#
+# Make sure we have a definition for C99's uintptr_t (regardless of
+# whether the environment is a C99 environment or not).
+#
+
+  ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default"
+if test "x$ac_cv_type_uintptr_t" = xyes; then :
+
+$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h
+
+else
+  for ac_type in 'unsigned int' 'unsigned long int' \
+       'unsigned long long int'; do
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+cat >>confdefs.h <<_ACEOF
+#define uintptr_t $ac_type
+_ACEOF
+
+         ac_type=
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+       test -z "$ac_type" && break
+     done
+fi
+
+
+
 #
 # Define the old BSD specified-width types in terms of the C99 types;
 # we may need them with libpcap include files.
index 1f10dc5e7e9e3c03d6459243d81b2a7e180118bf..a629559ed1cbe2a61b2682a59fdcab445b2b8d1c 100644 (file)
@@ -968,6 +968,12 @@ AC_TYPE_UINT16_T
 AC_TYPE_UINT32_T
 AC_TYPE_UINT64_T
 
+#
+# Make sure we have a definition for C99's uintptr_t (regardless of
+# whether the environment is a C99 environment or not).
+#
+AC_TYPE_UINTPTR_T
+
 #
 # Define the old BSD specified-width types in terms of the C99 types;
 # we may need them with libpcap include files.
index 515d839d733b1bcd7f2a0d668218bbdb374ac623..4580e73dd26fda80b911028d96d97f01637a0d93 100644 (file)
@@ -258,9 +258,21 @@ struct netdissect_options {
  * "l" isn't so large that "ndo->ndo_snapend - (l)" underflows.
  *
  * The check is for <= rather than < because "l" might be 0.
+ *
+ * We cast the pointers to uintptr_t to make sure that the compiler
+ * doesn't optimize away any of these tests (which it is allowed to
+ * do, as adding an integer to, or subtracting an integer from, a
+ * pointer assumes that the pointer is a pointer to an element of an
+ * array and that the result of the addition or subtraction yields a
+ * pointer to another member of the array, so that, for example, if
+ * you subtract a positive integer from a pointer, the result is
+ * guaranteed to be less than the original pointer value). See
+ *
+ *     http://www.kb.cert.org/vuls/id/162289
  */
-#define ND_TTEST2(var, l) (ndo->ndo_snapend - (l) <= ndo->ndo_snapend && \
-                       (const u_char *)&(var) <= ndo->ndo_snapend - (l))
+#define ND_TTEST2(var, l) \
+       ((uintptr_t)ndo->ndo_snapend - (l) <= (uintptr_t)ndo->ndo_snapend && \
+           (uintptr_t)&(var) <= (uintptr_t)ndo->ndo_snapend - (l))
 
 /* True if "var" was captured */
 #define ND_TTEST(var) ND_TTEST2(var, sizeof(var))