Browse Source

add support for -fsanitize=undefined and -fsanitize=address
Remove undefined behavior in the encoding layer (was not problematic on all current architectures)

Julius Pfrommer 9 years ago
parent
commit
99ce9e249c
3 changed files with 57 additions and 84 deletions
  1. 43 18
      CMakeLists.txt
  2. 13 65
      src/ua_types_encoding_binary.c
  3. 1 1
      tests/CMakeLists.txt

+ 43 - 18
CMakeLists.txt

@@ -52,38 +52,56 @@ if(NOT CMAKE_BUILD_TYPE)
     set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build." FORCE)
 endif()
 
+# Collect libraries
+list(APPEND open62541_LIBRARIES "")
+
 # compiler flags
 if(CMAKE_COMPILER_IS_GNUCC OR "x${CMAKE_C_COMPILER_ID}" STREQUAL "xClang")
     add_definitions(-std=c99 -pipe -Wall -Wextra -Werror -Wformat -Wno-unused-parameter
                     -Wno-unused-function -Wno-unused-label -Wpointer-arith -Wreturn-type -Wsign-compare -Wmultichar
                     -Wcast-qual -Wmissing-prototypes -Wstrict-prototypes #-Wshadow #-Wconversion
                     -Winit-self -Wuninitialized -Wformat-security -Wformat-nonliteral)
-    # binary size reduction settings
+
+  # library linking
+  set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # cmake sets -rdynamic by default
+  if(NOT WIN32 AND NOT CYGWIN)
+	add_definitions(-fvisibility=hidden -fPIC)
+    if(NOT APPLE)
+      set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,-z,norelro -Wl,--hash-style=gnu -Wl,--build-id=none")
+    endif()
+  endif()
+
+  # Debug
+  if(CMAKE_BUILD_TYPE STREQUAL "Debug")
+	#add_definitions(-fsanitize=address)
+    #list(APPEND open62541_LIBRARIES asan)
+
+	#add_definitions(-fsanitize=undefined)
+    #list(APPEND open62541_LIBRARIES ubsan)
+
+  elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel" OR
+         CMAKE_BUILD_TYPE STREQUAL "Release")
     add_definitions(-ffunction-sections -fdata-sections -fno-stack-protector -fno-unwind-tables
                     -fno-asynchronous-unwind-tables -fno-math-errno -fmerge-all-constants -fno-ident)
-  if(APPLE)
+    set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -s")
+    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -s")
+    if(APPLE)
       set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,-dead_strip")
       set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-dead_strip")
-  else()
+    else()
       set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,--gc-sections")
       set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections")
-  endif()
-  set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") # cmake sets -rdynamic by default
-	if(NOT WIN32 AND NOT CYGWIN)
-	    add_definitions(-fvisibility=hidden -fPIC)
-      if(NOT APPLE)
+      if(NOT WIN32 AND NOT CYGWIN)
         # these settings reduce the binary size by ~2kb
         set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -Wl,-z,norelro -Wl,--hash-style=gnu -Wl,--build-id=none")
       endif()
-	endif()
-    if(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel" OR CMAKE_BUILD_TYPE STREQUAL "Release")
-        set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -s")
-        set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -s")
-    endif()
-    if(APPLE)
-        set(CMAKE_MACOSX_RPATH 1)
-        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_DARWIN_C_SOURCE=1")
     endif()
+  endif()
+  
+  if(APPLE)
+    set(CMAKE_MACOSX_RPATH 1)
+    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_DARWIN_C_SOURCE=1")
+  endif()
 elseif(MSVC)
     set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /MT")
     set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /MTd")
@@ -350,6 +368,7 @@ add_library(open62541 SHARED $<TARGET_OBJECTS:open62541-object>)
 add_library(open62541-static STATIC $<TARGET_OBJECTS:open62541-object>)
 target_compile_definitions(open62541 PRIVATE -DUA_DYNAMIC_LINKING)
 target_compile_definitions(open62541-static PRIVATE -DUA_DYNAMIC_LINKING)
+target_link_libraries(open62541-static ${open62541_LIBRARIES})
 if(WIN32)
   target_link_libraries(open62541 ws2_32)
   target_link_libraries(open62541-static ws2_32)
@@ -362,7 +381,8 @@ if(UA_BUILD_EXAMPLESERVER)
     if(UA_ENABLE_AMALGAMATION)
        ADD_DEPENDENCIES(server amalgamation)
     endif()
-    target_link_libraries(server open62541)
+    target_link_libraries(server ${open62541_LIBRARIES} open62541)
+    target_link_libraries(server_static ${open62541_LIBRARIES})
     if(WIN32)
         target_link_libraries(server_static ws2_32)
         target_link_libraries(server ws2_32)
@@ -377,6 +397,7 @@ if(UA_BUILD_EXAMPLESERVER)
 
     if(UA_ENABLE_NONSTANDARD_UDP)
       add_executable(exampleServerUDP $<TARGET_OBJECTS:open62541-object> examples/networklayer_udp.c examples/server_udp.c)
+      target_link_libraries(exampleServerUDP ${open62541_LIBRARIES} open62541)
       if(UA_ENABLE_MULTITHREADING)
   	    target_link_libraries(exampleServerUDP urcu-cds urcu urcu-common)
       endif()
@@ -403,9 +424,11 @@ if(UA_BUILD_EXAMPLECLIENT)
 	add_executable(client_static examples/client.c ${client_source})
     add_executable(client examples/client.c)
 	if(UA_ENABLE_AMALGAMATION)
+	   ADD_DEPENDENCIES(client_static amalgamation)
 	   ADD_DEPENDENCIES(client amalgamation)
 	endif()
-	target_link_libraries(client open62541)
+	target_link_libraries(client_static ${open62541_LIBRARIES})
+	target_link_libraries(client open62541 ${open62541_LIBRARIES})
     if(WIN32)
         target_link_libraries(client_static ws2_32)
         target_link_libraries(client ws2_32)
@@ -419,6 +442,7 @@ if(UA_BUILD_EXAMPLECLIENT)
     endif()
     if(UA_ENABLE_NONSTANDARD_STATELESS AND NOT UA_ENABLE_AMALGAMATION)
         add_executable(client_stateless examples/client_stateless.c ${client_source})
+	    target_link_libraries(client_stateless open62541 ${open62541_LIBRARIES})
         if(UA_ENABLE_MULTITHREADING)
             target_link_libraries(client_stateless urcu-cds urcu urcu-common pthread)
         endif()
@@ -436,6 +460,7 @@ if(UA_BUILD_EXAMPLES)
     #FIXME: we had problem with static linking for msvs, here a quick and dirty workaround
     #http://stackoverflow.com/questions/3704374/linking-error-lnk2019-in-msvc-unresolved-symbols-with-imp-prefix-but-shoul
     #http://stackoverflow.com/questions/1089828/same-header-file-for-both-dll-and-static-library
+	list(APPEND LIBS ${open62541_LIBRARIES})
     if(NOT WIN32)
 		list(APPEND LIBS pthread)
 		if (NOT APPLE)

+ 13 - 65
src/ua_types_encoding_binary.c

@@ -66,18 +66,12 @@ UInt16_encodeBinary(UA_UInt16 const *src, const UA_DataType *_,
                     UA_ByteString *dst, size_t *UA_RESTRICT offset) {
     if(*offset + sizeof(UA_UInt16) > dst->length)
         return UA_STATUSCODE_BADENCODINGERROR;
-#if defined(UA_NON_LITTLEENDIAN_ARCHITECTURE) && !defined(UA_ALIGNED_MEMORY_ACCESS)
+#ifdef UA_NON_LITTLEENDIAN_ARCHITECTURE
     UA_UInt16 le_uint16 = htole16(*src);
     src = &le_uint16;
 #endif
-
-#ifdef UA_ALIGNED_MEMORY_ACCESS
-    dst->data[(*offset)++] = (*src & 0x00FF) >> 0;
-    dst->data[(*offset)++] = (*src & 0xFF00) >> 8;
-#else
-    *(UA_UInt16*)&dst->data[*offset] = *src;
+    memcpy(&dst->data[*offset], src, sizeof(UA_UInt16));
     *offset += 2;
-#endif
     return UA_STATUSCODE_GOOD;
 }
 
@@ -91,15 +85,9 @@ UInt16_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
                     UA_UInt16 *dst, const UA_DataType *_) {
     if(*offset + sizeof(UA_UInt16) > src->length)
         return UA_STATUSCODE_BADDECODINGERROR;
-#ifdef UA_ALIGNED_MEMORY_ACCESS
-    *dst = (UA_UInt16) src->data[(*offset)++] << 0;
-    *dst |= (UA_UInt16) src->data[(*offset)++] << 8;
-#else
-    *dst = *((UA_UInt16*) &src->data[*offset]);
+    memcpy(dst, &src->data[*offset], sizeof(UA_UInt16));
     *offset += 2;
-#endif
-
-#if defined(UA_NON_LITTLEENDIAN_ARCHITECTURE) && !defined(UA_ALIGNED_MEMORY_ACCESS)
+#ifdef UA_NON_LITTLEENDIAN_ARCHITECTURE
     *dst = le16toh(*dst);
 #endif
     return UA_STATUSCODE_GOOD;
@@ -116,20 +104,12 @@ UInt32_encodeBinary(UA_UInt32 const *src, const UA_DataType *_,
                     UA_ByteString *dst, size_t *UA_RESTRICT offset) {
     if(*offset + sizeof(UA_UInt32) > dst->length)
         return UA_STATUSCODE_BADENCODINGERROR;
-#if defined(UA_NON_LITTLEENDIAN_ARCHITECTURE) && !defined(UA_ALIGNED_MEMORY_ACCESS)
+#ifdef UA_NON_LITTLEENDIAN_ARCHITECTURE
     UA_UInt32 le_uint32 = htole32(*src);
     src = &le_uint32;
 #endif
-
-#ifdef UA_ALIGNED_MEMORY_ACCESS
-    dst->data[(*offset)++] = (*src & 0x000000FF) >> 0;
-    dst->data[(*offset)++] = (*src & 0x0000FF00) >> 8;
-    dst->data[(*offset)++] = (*src & 0x00FF0000) >> 16;
-    dst->data[(*offset)++] = (*src & 0xFF000000) >> 24;
-#else
-    *(UA_UInt32*) &dst->data[*offset] = *src;
+    memcpy(&dst->data[*offset], src, sizeof(UA_UInt32));
     *offset += 4;
-#endif
     return UA_STATUSCODE_GOOD;
 }
 
@@ -149,17 +129,9 @@ UInt32_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
                     UA_UInt32 *dst, const UA_DataType *_) {
     if(*offset + sizeof(UA_UInt32) > src->length)
         return UA_STATUSCODE_BADDECODINGERROR;
-#ifdef UA_ALIGNED_MEMORY_ACCESS
-    *dst = (UA_UInt32)((UA_Byte)(src->data[(*offset)++] & 0xFF));
-    *dst |= (UA_UInt32)((UA_Byte)(src->data[(*offset)++] & 0xFF) << 8);
-    *dst |= (UA_UInt32)((UA_Byte)(src->data[(*offset)++] & 0xFF) << 16);
-    *dst |= (UA_UInt32)((UA_Byte)(src->data[(*offset)++] & 0xFF) << 24);
-#else
-    *dst = *((UA_UInt32*) &src->data[*offset]);
+    memcpy(dst, &src->data[*offset], sizeof(UA_UInt32));
     *offset += 4;
-#endif
-
-#if defined(UA_NON_LITTLEENDIAN_ARCHITECTURE) && !defined(UA_ALIGNED_MEMORY_ACCESS)
+#ifdef UA_NON_LITTLEENDIAN_ARCHITECTURE
     *dst = le32toh(*dst);
 #endif
     return UA_STATUSCODE_GOOD;
@@ -182,24 +154,12 @@ UInt64_encodeBinary(UA_UInt64 const *src, const UA_DataType *_,
                     UA_ByteString *dst, size_t *UA_RESTRICT offset) {
     if(*offset + sizeof(UA_UInt64) > dst->length)
         return UA_STATUSCODE_BADENCODINGERROR;
-#if defined(UA_NON_LITTLEENDIAN_ARCHITECTURE) && !defined(UA_ALIGNED_MEMORY_ACCESS)
+#ifdef UA_NON_LITTLEENDIAN_ARCHITECTURE
     UA_UInt64 le_uint64 = htole64(*src);
     src = &le_uint64;
 #endif
-
-#ifdef UA_ALIGNED_MEMORY_ACCESS
-    dst->data[(*offset)++] = (*src & 0x00000000000000FF) >> 0;
-    dst->data[(*offset)++] = (*src & 0x000000000000FF00) >> 8;
-    dst->data[(*offset)++] = (*src & 0x0000000000FF0000) >> 16;
-    dst->data[(*offset)++] = (*src & 0x00000000FF000000) >> 24;
-    dst->data[(*offset)++] = (*src & 0x000000FF00000000) >> 32;
-    dst->data[(*offset)++] = (*src & 0x0000FF0000000000) >> 40;
-    dst->data[(*offset)++] = (*src & 0x00FF000000000000) >> 48;
-    dst->data[(*offset)++] = (*src & 0xFF00000000000000) >> 56;
-#else
-    *(UA_UInt64*) &dst->data[*offset] = *src;
+    memcpy(&dst->data[*offset], src, sizeof(UA_UInt64));
     *offset += 8;
-#endif
     return UA_STATUSCODE_GOOD;
 }
 
@@ -219,21 +179,9 @@ UInt64_decodeBinary(UA_ByteString const *src, size_t *UA_RESTRICT offset,
                     UA_UInt64 *dst, const UA_DataType *_) {
     if(*offset + sizeof(UA_UInt64) > src->length)
         return UA_STATUSCODE_BADDECODINGERROR;
-#ifdef UA_ALIGNED_MEMORY_ACCESS
-    *dst  = (UA_UInt64) src->data[(*offset)++];
-    *dst |= (UA_UInt64) src->data[(*offset)++] << 8;
-    *dst |= (UA_UInt64) src->data[(*offset)++] << 16;
-    *dst |= (UA_UInt64) src->data[(*offset)++] << 24;
-    *dst |= (UA_UInt64) src->data[(*offset)++] << 32;
-    *dst |= (UA_UInt64) src->data[(*offset)++] << 40;
-    *dst |= (UA_UInt64) src->data[(*offset)++] << 48;
-    *dst |= (UA_UInt64) src->data[(*offset)++] << 56;
-#else
-    *dst = *((UA_UInt64*) &src->data[*offset]);
+    memcpy(dst, &src->data[*offset], sizeof(UA_UInt64));
     *offset += 8;
-#endif
-
-#if defined(UA_NON_LITTLEENDIAN_ARCHITECTURE) && !defined(UA_ALIGNED_MEMORY_ACCESS)
+#ifdef UA_NON_LITTLEENDIAN_ARCHITECTURE
     *dst = le64toh(*dst);
 #endif
     return UA_STATUSCODE_GOOD;
@@ -348,7 +296,7 @@ Array_encodeBinary(const void *src, size_t length, const UA_DataType *type,
     else if(src == UA_EMPTY_ARRAY_SENTINEL)
         signed_length = 0;
     UA_StatusCode retval = Int32_encodeBinary(&signed_length, NULL, dst, offset);
-    if(retval != UA_STATUSCODE_GOOD)
+    if(retval != UA_STATUSCODE_GOOD || length == 0)
         return retval;
 
 #ifndef UA_NON_LITTLEENDIAN_ARCHITECTURE

+ 1 - 1
tests/CMakeLists.txt

@@ -6,7 +6,7 @@ include_directories(${PROJECT_BINARY_DIR}/src_generated)
 find_package(Check REQUIRED)
 find_package(Threads REQUIRED)
 
-set(LIBS ${CHECK_LIBRARIES})
+set(LIBS ${CHECK_LIBRARIES} ${open62541_LIBRARIES})
 if(NOT WIN32)
   list(APPEND LIBS pthread m)
   if (NOT APPLE)