diff --git a/config.h.in b/config.h.in index 11ce977b5..914289a8f 100644 --- a/config.h.in +++ b/config.h.in @@ -217,6 +217,9 @@ /* Define to 1 if you have the 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 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 293edb14c..43b3068aa 100755 --- 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. diff --git a/configure.in b/configure.in index 1f10dc5e7..a629559ed 100644 --- a/configure.in +++ b/configure.in @@ -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. diff --git a/netdissect.h b/netdissect.h index 515d839d7..4580e73dd 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))