From d731ab45831cfc2104b17b3a623e0c89c3174145 Mon Sep 17 00:00:00 2001 From: rl1987 Date: Mon, 25 Feb 2019 19:07:47 +0200 Subject: [PATCH 01/11] Check that all valid values of int and unsigned int can be put into void pointer --- changes/ticket29537 | 3 ++ src/test/include.am | 1 + src/test/test.h | 1 + src/test/test_ptr_slow.c | 67 ++++++++++++++++++++++++++++++++++++++++ src/test/test_slow.c | 1 + 5 files changed, 73 insertions(+) create mode 100644 changes/ticket29537 create mode 100644 src/test/test_ptr_slow.c diff --git a/changes/ticket29537 b/changes/ticket29537 new file mode 100644 index 0000000000..048e13c65f --- /dev/null +++ b/changes/ticket29537 @@ -0,0 +1,3 @@ + o Testing: + - Check that all valid values of `int` and `unsigned int` can be + represented by `void *`. Resolves issue 29537. diff --git a/src/test/include.am b/src/test/include.am index d585c2a38a..e6cebe1d1a 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -211,6 +211,7 @@ src_test_test_slow_SOURCES += \ src/test/test_crypto_slow.c \ src/test/test_process_slow.c \ src/test/test_prob_distr.c \ + src/test/test_ptr_slow.c \ src/test/testing_common.c \ src/test/testing_rsakeys.c \ src/ext/tinytest.c diff --git a/src/test/test.h b/src/test/test.h index 2564432985..9d9184e2aa 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -278,6 +278,7 @@ extern struct testcase_t x509_tests[]; extern struct testcase_t slow_crypto_tests[]; extern struct testcase_t slow_process_tests[]; +extern struct testcase_t slow_ptr_tests[]; extern struct testgroup_t testgroups[]; diff --git a/src/test/test_ptr_slow.c b/src/test/test_ptr_slow.c new file mode 100644 index 0000000000..a5914c9120 --- /dev/null +++ b/src/test/test_ptr_slow.c @@ -0,0 +1,67 @@ +/* Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "orconfig.h" +#include "core/or/or.h" +#include "test/test.h" + +#include +#include + +/** Check that all values of int can be cast to void * and back. */ +static void +test_int_voidstar_interop(void *arg) +{ + int a; + (void)arg; + + for (a = INT_MIN; a < INT_MAX; a++) { + intptr_t ap = (intptr_t)a; + void *b = (void *)ap; + intptr_t c = (intptr_t)b; + void *d = (void *)c; + + tt_assert(ap == c); + tt_assert(b == d); + } + + done: + return; +} + +/** Check that all values of unsigned int can be cast to void * and back. */ +static void +test_uint_voidstar_interop(void *arg) +{ + unsigned int a; + (void)arg; + + for (a = 0; a < UINT_MAX; a++) { + intptr_t ap = (intptr_t)a; + void *b = (void *)ap; + intptr_t c = (intptr_t)b; + void *d = (void *)c; + + tt_assert(ap == c); + tt_assert(b == d); + } + + done: + return; +} + +struct testcase_t slow_ptr_tests[] = { + { .name = "int_voidstar_interop", + .fn = test_int_voidstar_interop, + .flags = 0, + .setup = NULL, + .setup_data = NULL }, + { .name = "uint_voidstar_interop", + .fn = test_uint_voidstar_interop, + .flags = 0, + .setup = NULL, + .setup_data = NULL }, + END_OF_TESTCASES +}; diff --git a/src/test/test_slow.c b/src/test/test_slow.c index c3e7edd408..d4d5b755a5 100644 --- a/src/test/test_slow.c +++ b/src/test/test_slow.c @@ -22,6 +22,7 @@ struct testgroup_t testgroups[] = { { "slow/crypto/", slow_crypto_tests }, { "slow/process/", slow_process_tests }, { "slow/prob_distr/", slow_stochastic_prob_distr_tests }, + { "slow/ptr/", slow_ptr_tests }, END_OF_GROUPS }; From 052ec08a085d69ac2ffb3475e61631b0aef26562 Mon Sep 17 00:00:00 2001 From: rl1987 Date: Tue, 12 Mar 2019 12:01:26 +0200 Subject: [PATCH 02/11] Refrain from doing exhaustive iteration over all values of integers --- src/test/test_ptr_slow.c | 59 ++++++++++++++++++++++++++-------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/src/test/test_ptr_slow.c b/src/test/test_ptr_slow.c index a5914c9120..632a304177 100644 --- a/src/test/test_ptr_slow.c +++ b/src/test/test_ptr_slow.c @@ -10,46 +10,65 @@ #include #include -/** Check that all values of int can be cast to void * and back. */ +/** Assert that a can be cast to void * and back. */ +static void +assert_int_voidptr_roundtrip(int a) +{ + intptr_t ap = (intptr_t)a; + void *b = (void *)ap; + intptr_t c = (intptr_t)b; + void *d = (void *)c; + + tt_assert(ap == c); + tt_assert(b == d); + + done: + return; +} + static void test_int_voidstar_interop(void *arg) { int a; (void)arg; - for (a = INT_MIN; a < INT_MAX; a++) { - intptr_t ap = (intptr_t)a; - void *b = (void *)ap; - intptr_t c = (intptr_t)b; - void *d = (void *)c; - - tt_assert(ap == c); - tt_assert(b == d); + for (a = 0; a <= 1024; a++) { + assert_int_voidptr_roundtrip(a); } + for (a = INT_MAX-1024; a < INT_MAX; a++) { + assert_int_voidptr_roundtrip(a); + } +} + +static void +assert_uint_voidptr_roundtrip(unsigned int a) +{ + intptr_t ap = (intptr_t)a; + void *b = (void *)ap; + intptr_t c = (intptr_t)b; + void *d = (void *)c; + + tt_assert(ap == c); + tt_assert(b == d); + done: return; } -/** Check that all values of unsigned int can be cast to void * and back. */ static void test_uint_voidstar_interop(void *arg) { unsigned int a; (void)arg; - for (a = 0; a < UINT_MAX; a++) { - intptr_t ap = (intptr_t)a; - void *b = (void *)ap; - intptr_t c = (intptr_t)b; - void *d = (void *)c; - - tt_assert(ap == c); - tt_assert(b == d); + for (a = 0; a <= 1024; a++) { + assert_uint_voidptr_roundtrip(a); } - done: - return; + for (a = UINT_MAX-1024; a < UINT_MAX; a++) { + assert_uint_voidptr_roundtrip(a); + } } struct testcase_t slow_ptr_tests[] = { From e52653e01a2ce6655975c2f893a1d1ff7bef2af7 Mon Sep 17 00:00:00 2001 From: rl1987 Date: Tue, 12 Mar 2019 12:14:22 +0200 Subject: [PATCH 03/11] USe uintptr_t for unsigned ints --- src/test/test_ptr_slow.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/test_ptr_slow.c b/src/test/test_ptr_slow.c index 632a304177..f064a3e7c2 100644 --- a/src/test/test_ptr_slow.c +++ b/src/test/test_ptr_slow.c @@ -44,9 +44,9 @@ test_int_voidstar_interop(void *arg) static void assert_uint_voidptr_roundtrip(unsigned int a) { - intptr_t ap = (intptr_t)a; + uintptr_t ap = (uintptr_t)a; void *b = (void *)ap; - intptr_t c = (intptr_t)b; + uintptr_t c = (uintptr_t)b; void *d = (void *)c; tt_assert(ap == c); From 0bc9ed9d38cb29783d000b6e22677ae16727976b Mon Sep 17 00:00:00 2001 From: rl1987 Date: Wed, 20 Mar 2019 18:54:11 +0200 Subject: [PATCH 04/11] Move casts to separate C file to prevent compiler from optimising them away --- src/test/include.am | 2 ++ src/test/ptr_helpers.c | 50 ++++++++++++++++++++++++++++++++++++++++ src/test/ptr_helpers.h | 18 +++++++++++++++ src/test/test_ptr_slow.c | 13 ++++++----- 4 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 src/test/ptr_helpers.c create mode 100644 src/test/ptr_helpers.h diff --git a/src/test/include.am b/src/test/include.am index e6cebe1d1a..700107d6ce 100644 --- a/src/test/include.am +++ b/src/test/include.am @@ -211,6 +211,7 @@ src_test_test_slow_SOURCES += \ src/test/test_crypto_slow.c \ src/test/test_process_slow.c \ src/test/test_prob_distr.c \ + src/test/ptr_helpers.c \ src/test/test_ptr_slow.c \ src/test/testing_common.c \ src/test/testing_rsakeys.c \ @@ -315,6 +316,7 @@ noinst_HEADERS+= \ src/test/log_test_helpers.h \ src/test/rend_test_helpers.h \ src/test/test.h \ + src/test/ptr_helpers.h \ src/test/test_helpers.h \ src/test/test_dir_common.h \ src/test/test_connection.h \ diff --git a/src/test/ptr_helpers.c b/src/test/ptr_helpers.c new file mode 100644 index 0000000000..296238feeb --- /dev/null +++ b/src/test/ptr_helpers.c @@ -0,0 +1,50 @@ +/* Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "ptr_helpers.h" + +/** + * Cast (inptr_t value) to a void pointer. + */ +void * +cast_intptr_to_voidstar(intptr_t x) +{ + void *r = (void *)x; + + return r; +} + +/** + * Cast x (void pointer) to inptr_t value. + */ +intptr_t +cast_voidstar_to_intptr(void *x) +{ + intptr_t r = (intptr_t)x; + + return r; +} + +/** + * Cast x (uinptr_t value) to void pointer. + */ +void * +cast_uintptr_to_voidstar(uintptr_t x) +{ + void *r = (void *)x; + + return r; +} + +/** + * Cast x (void pointer) to uinptr_t value. + */ +uintptr_t +cast_voidstar_to_uintptr(void *x) +{ + uintptr_t r = (uintptr_t)x; + + return r; +} diff --git a/src/test/ptr_helpers.h b/src/test/ptr_helpers.h new file mode 100644 index 0000000000..fe2c8c9705 --- /dev/null +++ b/src/test/ptr_helpers.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2001-2004, Roger Dingledine. + * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. + * Copyright (c) 2007-2019, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include + +void * +cast_intptr_to_voidstar(intptr_t x); + +intptr_t +cast_voidstar_to_intptr(void *x); + +void * +cast_uintptr_to_voidstar(uintptr_t x); + +uintptr_t +cast_voidstar_to_uintptr(void *x); diff --git a/src/test/test_ptr_slow.c b/src/test/test_ptr_slow.c index f064a3e7c2..07481fb1ec 100644 --- a/src/test/test_ptr_slow.c +++ b/src/test/test_ptr_slow.c @@ -6,6 +6,7 @@ #include "orconfig.h" #include "core/or/or.h" #include "test/test.h" +#include "test/ptr_helpers.h" #include #include @@ -15,9 +16,9 @@ static void assert_int_voidptr_roundtrip(int a) { intptr_t ap = (intptr_t)a; - void *b = (void *)ap; - intptr_t c = (intptr_t)b; - void *d = (void *)c; + void *b = cast_intptr_to_voidstar(ap); + intptr_t c = cast_voidstar_to_intptr(b); + void *d = cast_intptr_to_voidstar(c); tt_assert(ap == c); tt_assert(b == d); @@ -45,9 +46,9 @@ static void assert_uint_voidptr_roundtrip(unsigned int a) { uintptr_t ap = (uintptr_t)a; - void *b = (void *)ap; - uintptr_t c = (uintptr_t)b; - void *d = (void *)c; + void *b = cast_uintptr_to_voidstar(ap); + uintptr_t c = cast_voidstar_to_uintptr(b); + void *d = cast_uintptr_to_voidstar(c); tt_assert(ap == c); tt_assert(b == d); From 280109473fe30d1e67f8db09ce279cc1f714a682 Mon Sep 17 00:00:00 2001 From: rl1987 Date: Wed, 20 Mar 2019 19:00:03 +0200 Subject: [PATCH 05/11] Check more values of int --- src/test/test_ptr_slow.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/test/test_ptr_slow.c b/src/test/test_ptr_slow.c index 07481fb1ec..5b366b7d38 100644 --- a/src/test/test_ptr_slow.c +++ b/src/test/test_ptr_slow.c @@ -33,7 +33,11 @@ test_int_voidstar_interop(void *arg) int a; (void)arg; - for (a = 0; a <= 1024; a++) { + for (a = -1024; a <= 1024; a++) { + assert_int_voidptr_roundtrip(a); + } + + for (a = INT_MIN; a <= INT_MIN+1024; a++) { assert_int_voidptr_roundtrip(a); } From 72e0dc0822deb8587b3cae2edf584ece13cb6bb8 Mon Sep 17 00:00:00 2001 From: rl1987 Date: Wed, 20 Mar 2019 19:06:40 +0200 Subject: [PATCH 06/11] Check roundtrip for each bit of {unsigned} int values --- src/test/test_ptr_slow.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/test/test_ptr_slow.c b/src/test/test_ptr_slow.c index 5b366b7d38..0142fd1c8a 100644 --- a/src/test/test_ptr_slow.c +++ b/src/test/test_ptr_slow.c @@ -44,6 +44,12 @@ test_int_voidstar_interop(void *arg) for (a = INT_MAX-1024; a < INT_MAX; a++) { assert_int_voidptr_roundtrip(a); } + + a = 1; + for (unsigned long i = 0; i < sizeof(int) * 8; i++) { + assert_int_voidptr_roundtrip(a); + a = (a << 1); + } } static void @@ -74,6 +80,12 @@ test_uint_voidstar_interop(void *arg) for (a = UINT_MAX-1024; a < UINT_MAX; a++) { assert_uint_voidptr_roundtrip(a); } + + a = 1; + for (unsigned long i = 0; i < sizeof(int) * 8; i++) { + assert_uint_voidptr_roundtrip(a); + a = (a << 1); + } } struct testcase_t slow_ptr_tests[] = { From 13b28063f9f2a3d2a587eabac358452a42277052 Mon Sep 17 00:00:00 2001 From: rl1987 Date: Fri, 22 Mar 2019 12:57:58 +0200 Subject: [PATCH 07/11] Compile time check for being able to fit {unsigned} int inside void pointer --- configure.ac | 1 + src/test/test_ptr_slow.c | 9 +++++++++ 2 files changed, 10 insertions(+) diff --git a/configure.ac b/configure.ac index 6036cdffe5..8ac2d71e4f 100644 --- a/configure.ac +++ b/configure.ac @@ -1588,6 +1588,7 @@ AC_CHECK_MEMBERS([struct timeval.tv_sec], , , AC_CHECK_SIZEOF(char) AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(unsigned int) AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(long long) AC_CHECK_SIZEOF(__int64) diff --git a/src/test/test_ptr_slow.c b/src/test/test_ptr_slow.c index 0142fd1c8a..37560d4359 100644 --- a/src/test/test_ptr_slow.c +++ b/src/test/test_ptr_slow.c @@ -11,6 +11,15 @@ #include #include +#if SIZEOF_INT > SIZEOF_VOID_P +#error "sizeof(int) > sizeof(void *) - Tor cannot be built on this platform!" +#endif + +#if SIZEOF_UNSIGNED_INT > SIZEOF_VOID_P +#error "sizeof(unsigned int) > sizeof(void *) - Tor cannot be built on this \ +platform!" +#endif + /** Assert that a can be cast to void * and back. */ static void assert_int_voidptr_roundtrip(int a) From 7b30f8dc8c93ac215a1e7330fee1baa5f1437a98 Mon Sep 17 00:00:00 2001 From: rl1987 Date: Fri, 22 Mar 2019 13:04:06 +0200 Subject: [PATCH 08/11] Write missing function comments --- src/test/test_ptr_slow.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/test/test_ptr_slow.c b/src/test/test_ptr_slow.c index 37560d4359..2d4fc9d4dd 100644 --- a/src/test/test_ptr_slow.c +++ b/src/test/test_ptr_slow.c @@ -36,6 +36,7 @@ assert_int_voidptr_roundtrip(int a) return; } +/** Test for possibility of casting `int` to `void *` and back. */ static void test_int_voidstar_interop(void *arg) { @@ -61,6 +62,7 @@ test_int_voidstar_interop(void *arg) } } +/** Assert that a can be cast to void * and back. */ static void assert_uint_voidptr_roundtrip(unsigned int a) { @@ -76,6 +78,7 @@ assert_uint_voidptr_roundtrip(unsigned int a) return; } +/** Test for possibility of casting `int` to `void *` and back. */ static void test_uint_voidstar_interop(void *arg) { From 9529d99982eb64998e12db7704fa977bf02f541c Mon Sep 17 00:00:00 2001 From: rl1987 Date: Sun, 24 Mar 2019 09:25:30 +0200 Subject: [PATCH 09/11] Tweak changes file --- changes/ticket29537 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/changes/ticket29537 b/changes/ticket29537 index 048e13c65f..afe2308205 100644 --- a/changes/ticket29537 +++ b/changes/ticket29537 @@ -1,3 +1,3 @@ o Testing: - - Check that all valid values of `int` and `unsigned int` can be - represented by `void *`. Resolves issue 29537. + - Check that representative subsets of values of `int` and `unsigned int` + can be represented by `void *`. Resolves issue 29537. From 68260e85b5fd4f5e0bb87a4c58b187a8309b0cb5 Mon Sep 17 00:00:00 2001 From: rl1987 Date: Mon, 25 Mar 2019 10:17:30 +0200 Subject: [PATCH 10/11] Move sizeof check to torint.h --- src/lib/cc/torint.h | 9 +++++++++ src/test/test_ptr_slow.c | 9 --------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/lib/cc/torint.h b/src/lib/cc/torint.h index c9b2d329f2..9a66aada18 100644 --- a/src/lib/cc/torint.h +++ b/src/lib/cc/torint.h @@ -125,4 +125,13 @@ typedef int32_t ssize_t; /** Any size_t larger than this amount is likely to be an underflow. */ #define SIZE_T_CEILING ((size_t)(SSIZE_MAX-16)) +#if SIZEOF_INT > SIZEOF_VOID_P +#error "sizeof(int) > sizeof(void *) - Tor cannot be built on this platform!" +#endif + +#if SIZEOF_UNSIGNED_INT > SIZEOF_VOID_P +#error "sizeof(unsigned int) > sizeof(void *) - Tor cannot be built on this \ +platform!" +#endif + #endif /* !defined(TOR_TORINT_H) */ diff --git a/src/test/test_ptr_slow.c b/src/test/test_ptr_slow.c index 2d4fc9d4dd..76bdbf1891 100644 --- a/src/test/test_ptr_slow.c +++ b/src/test/test_ptr_slow.c @@ -11,15 +11,6 @@ #include #include -#if SIZEOF_INT > SIZEOF_VOID_P -#error "sizeof(int) > sizeof(void *) - Tor cannot be built on this platform!" -#endif - -#if SIZEOF_UNSIGNED_INT > SIZEOF_VOID_P -#error "sizeof(unsigned int) > sizeof(void *) - Tor cannot be built on this \ -platform!" -#endif - /** Assert that a can be cast to void * and back. */ static void assert_int_voidptr_roundtrip(int a) From 4e6ba575a66108f38a55cffdb197352757f77d78 Mon Sep 17 00:00:00 2001 From: rl1987 Date: Tue, 26 Mar 2019 09:49:32 +0200 Subject: [PATCH 11/11] Add header guards to ptr_helpers.h --- src/test/ptr_helpers.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/test/ptr_helpers.h b/src/test/ptr_helpers.h index fe2c8c9705..67776b1006 100644 --- a/src/test/ptr_helpers.h +++ b/src/test/ptr_helpers.h @@ -3,6 +3,9 @@ * Copyright (c) 2007-2019, The Tor Project, Inc. */ /* See LICENSE for licensing information */ +#ifndef TOR_PTR_HELPERS_H +#define TOR_PTR_HELPERS_H + #include void * @@ -16,3 +19,5 @@ cast_uintptr_to_voidstar(uintptr_t x); uintptr_t cast_voidstar_to_uintptr(void *x); + +#endif