From 92fefd09ba02435b576b884c504c5d0b88eef4c7 Mon Sep 17 00:00:00 2001 From: Thomas Faber Date: Sun, 26 Jul 2015 08:03:02 +0000 Subject: [PATCH] [PSDK] - Add support for intsafe signed Add functions - Guard signed math in ENABLE_INTSAFE_SIGNED_FUNCTIONS CORE-9947 #resolve svn path=/trunk/; revision=68573 --- reactos/include/psdk/intsafe.h | 56 +++++++++++++++++++++++++++++++ rostests/kmtests/rtl/RtlIntSafe.c | 32 ++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/reactos/include/psdk/intsafe.h b/reactos/include/psdk/intsafe.h index db8a6e6d3cc..e30cb1182af 100644 --- a/reactos/include/psdk/intsafe.h +++ b/reactos/include/psdk/intsafe.h @@ -433,6 +433,7 @@ DEFINE_SAFE_CONVERT_STOS(LongPtrToShort, LONG_PTR, SHORT) DEFINE_SAFE_CONVERT_STOS(LongPtrToInt, LONG_PTR, INT) DEFINE_SAFE_CONVERT_STOS(LongPtrToLong, LONG_PTR, LONG) DEFINE_SAFE_CONVERT_STOS(LongPtrToIntPtr, LONG_PTR, INT_PTR) +DEFINE_SAFE_CONVERT_STOS(LongLongToInt, LONGLONG, INT) DEFINE_SAFE_CONVERT_STOS(LongLongToLong, LONGLONG, LONG) DEFINE_SAFE_CONVERT_STOS(LongLongToIntPtr, LONGLONG, INT_PTR) DEFINE_SAFE_CONVERT_STOS(LongLongToLongPtr, LONGLONG, LONG_PTR) @@ -582,6 +583,55 @@ DEFINE_SAFE_SUB(SizeTSub, size_t) DEFINE_SAFE_SUB(SIZETSub, SIZE_T) DEFINE_SAFE_SUB(ULongLongSub, ULONGLONG) +#ifdef ENABLE_INTSAFE_SIGNED_FUNCTIONS +_Must_inspect_result_ +__forceinline +INTSAFE_RESULT +INTSAFE_NAME(LongLongAdd)( + _In_ LONGLONG Augend, + _In_ LONGLONG Addend, + _Out_ _Deref_out_range_(==, Augend + Addend) LONGLONG* pResult) +{ + LONGLONG Result = Augend + Addend; + + /* The only way the result can overflow, is when the sign of the augend + and the addend are the same. In that case the result is expected to + have the same sign as the two, otherwise it overflowed. + Sign equality is checked with a binary xor operation. */ + if ( ((Augend ^ Addend) >= 0) && ((Augend ^ Result) < 0) ) + { + *pResult = LONGLONG_ERROR; + return INTSAFE_E_ARITHMETIC_OVERFLOW; + } + else + { + *pResult = Result; + return INTSAFE_SUCCESS; + } +} + + +#define DEFINE_SAFE_ADD_S(_Name, _Type1, _Type2, _Convert) \ +C_ASSERT(sizeof(_Type2) > sizeof(_Type1)); \ +_Must_inspect_result_ \ +__forceinline \ +INTSAFE_RESULT \ +INTSAFE_NAME(_Name)( \ + _In_ _Type1 Augend, \ + _In_ _Type1 Addend, \ + _Out_ _Deref_out_range_(==, Augend + Addend) _Type1* pOutput) \ +{ \ + return INTSAFE_NAME(_Convert)(((_Type2)Augend) + ((_Type2)Addend), pOutput); \ +} + +DEFINE_SAFE_ADD_S(Int8Add, INT8, SHORT, ShortToInt8) +DEFINE_SAFE_ADD_S(ShortAdd, SHORT, INT, IntToShort) +DEFINE_SAFE_ADD_S(IntAdd, INT, LONGLONG, LongLongToInt) +DEFINE_SAFE_ADD_S(LongAdd, LONG, LONGLONG, LongLongToLong) +#ifndef _WIN64 +DEFINE_SAFE_ADD_S(IntPtrAdd, INT_PTR, LONGLONG, LongLongToIntPtr) +DEFINE_SAFE_ADD_S(LongPtrAdd, LONG_PTR, LONGLONG, LongLongToLongPtr) +#endif _Must_inspect_result_ __forceinline @@ -611,6 +661,7 @@ INTSAFE_NAME(LongLongSub)( #define DEFINE_SAFE_SUB_S(_Name, _Type1, _Type2, _Convert) \ +C_ASSERT(sizeof(_Type2) > sizeof(_Type1)); \ _Must_inspect_result_ \ __forceinline \ INTSAFE_RESULT \ @@ -628,6 +679,7 @@ DEFINE_SAFE_SUB_S(IntPtrSub, INT_PTR, LONGLONG, LongLongToIntPtr) DEFINE_SAFE_SUB_S(LongPtrSub, LONG_PTR, LONGLONG, LongLongToLongPtr) #endif +#endif /* ENABLE_INTSAFE_SIGNED_FUNCTIONS */ _Must_inspect_result_ __forceinline @@ -741,6 +793,8 @@ DEFINE_SAFE_MULT_U16(UShortMult, USHORT, ULongToUShort) #define RtlUInt16Mult RtlUShortMult #define RtlWordMult RtlUShortMult #ifdef _WIN64 +#define RtlIntPtrAdd RtlLongLongAdd +#define RtlLongPtrAdd RtlLongLongAdd #define RtlIntPtrSub RtlLongLongSub #define RtlLongPtrSub RtlLongLongSub #define RtlSizeTMult RtlULongLongMult @@ -769,6 +823,8 @@ DEFINE_SAFE_MULT_U16(UShortMult, USHORT, ULongToUShort) #define UInt16Mult UShortMult #define WordMult UShortMult #ifdef _WIN64 +#define IntPtrAdd LongLongAdd +#define LongPtrAdd LongLongAdd #define IntPtrSub LongLongSub #define LongPtrSub LongLongSub #define SizeTMult ULongLongMult diff --git a/rostests/kmtests/rtl/RtlIntSafe.c b/rostests/kmtests/rtl/RtlIntSafe.c index 0a9632de03e..1e59b873b38 100644 --- a/rostests/kmtests/rtl/RtlIntSafe.c +++ b/rostests/kmtests/rtl/RtlIntSafe.c @@ -111,4 +111,36 @@ START_TEST(RtlIntSafe) TEST_ADD(UInt8, UINT8, uint, UINT8_MAX - 1, 1, UINT8_MAX, STATUS_SUCCESS); TEST_ADD(UInt8, UINT8, uint, UINT8_MAX, 1, (UINT8)-1, STATUS_INTEGER_OVERFLOW); TEST_ADD(UInt8, UINT8, uint, UINT8_MAX, UINT8_MAX, (UINT8)-1, STATUS_INTEGER_OVERFLOW); + + TEST_ADD(Int8, INT8, int, 0, 0, 0, STATUS_SUCCESS); + TEST_ADD(Int8, INT8, int, 5, 5, 10, STATUS_SUCCESS); + TEST_ADD(Int8, INT8, int, 0, INT8_MAX, INT8_MAX, STATUS_SUCCESS); + TEST_ADD(Int8, INT8, int, INT8_MAX, 0, INT8_MAX, STATUS_SUCCESS); + TEST_ADD(Int8, INT8, int, INT8_MAX - 1, 1, INT8_MAX, STATUS_SUCCESS); + TEST_ADD(Int8, INT8, int, INT8_MAX, 1, (INT8)-1, STATUS_INTEGER_OVERFLOW); + TEST_ADD(Int8, INT8, int, INT8_MAX, INT8_MAX, (INT8)-1, STATUS_INTEGER_OVERFLOW); + TEST_ADD(Int8, INT8, int, 0, -1, -1, STATUS_SUCCESS); + TEST_ADD(Int8, INT8, int, -1, 0, -1, STATUS_SUCCESS); + TEST_ADD(Int8, INT8, int, 0, INT8_MIN, INT8_MIN, STATUS_SUCCESS); + TEST_ADD(Int8, INT8, int, INT8_MIN, 0, INT8_MIN, STATUS_SUCCESS); + TEST_ADD(Int8, INT8, int, INT8_MAX, INT8_MIN, (INT8)-1, STATUS_SUCCESS); + TEST_ADD(Int8, INT8, int, INT8_MIN, -1, (INT8)-1, STATUS_INTEGER_OVERFLOW); + TEST_ADD(Int8, INT8, int, INT8_MIN, INT8_MIN, (INT8)-1, STATUS_INTEGER_OVERFLOW); + + TEST_ADD(LongLong, LONGLONG, longlong, 0, 0, 0, STATUS_SUCCESS); + TEST_ADD(LongLong, LONGLONG, longlong, 5, 5, 10, STATUS_SUCCESS); + TEST_ADD(LongLong, LONGLONG, longlong, 0, LONGLONG_MAX, LONGLONG_MAX, STATUS_SUCCESS); + TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MAX, 0, LONGLONG_MAX, STATUS_SUCCESS); + TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MAX - 1, 1, LONGLONG_MAX, STATUS_SUCCESS); + TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MAX, 1, (LONGLONG)-1, STATUS_INTEGER_OVERFLOW); + TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MAX, INT8_MAX, (LONGLONG)-1, STATUS_INTEGER_OVERFLOW); + TEST_ADD(LongLong, LONGLONG, longlong, 0, -1, -1, STATUS_SUCCESS); + TEST_ADD(LongLong, LONGLONG, longlong, -1, 0, -1, STATUS_SUCCESS); + TEST_ADD(LongLong, LONGLONG, longlong, 0, LONGLONG_MIN, LONGLONG_MIN, STATUS_SUCCESS); + TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MIN, 0, LONGLONG_MIN, STATUS_SUCCESS); + TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MAX, LONGLONG_MIN, (LONGLONG)-1, STATUS_SUCCESS); + TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MIN, -1, (LONGLONG)-1, STATUS_INTEGER_OVERFLOW); + TEST_ADD(LongLong, LONGLONG, longlong, LONGLONG_MIN, LONGLONG_MIN, (LONGLONG)-1, STATUS_INTEGER_OVERFLOW); + TEST_ADD(LongLong, LONGLONG, longlong, ULONG_MAX, 1, 0x100000000LL, STATUS_SUCCESS); + TEST_ADD(LongLong, LONGLONG, longlong, ULONG_MAX, ULONG_MAX, 0x1fffffffeLL, STATUS_SUCCESS); }