summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--config.h.in7
-rwxr-xr-xconfigure42
-rw-r--r--configure.in6
-rw-r--r--netdissect.h16
4 files changed, 69 insertions, 2 deletions
diff --git a/config.h.in b/config.h.in
index 11ce977b..914289a8 100644
--- a/config.h.in
+++ b/config.h.in
@@ -217,6 +217,9 @@
/* 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
@@ -388,3 +391,7 @@
/* 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
diff --git a/configure b/configure
index 293edb14..43b3068a 100755
--- a/configure
+++ b/configure
@@ -6998,6 +6998,48 @@ _ACEOF
#
+# 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.
#
diff --git a/configure.in b/configure.in
index 1f10dc5e..a629559e 100644
--- a/configure.in
+++ b/configure.in
@@ -969,6 +969,12 @@ 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.
#
diff --git a/netdissect.h b/netdissect.h
index 515d839d..4580e73d 100644
--- a/netdissect.h
+++ b/netdissect.h
@@ -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))