Bläddra i källkod

Merge pull request #1147 from open62541/feature/fuzz_multiple_packages

Support fuzzing of concatenated packages
Stefan Profanter 7 år sedan
förälder
incheckning
15a928e167

+ 5 - 0
CMakeLists.txt

@@ -105,6 +105,11 @@ mark_as_advanced(UA_ENABLE_NONSTANDARD_UDP)
 option(UA_BUILD_EXAMPLES "Build example servers and clients" OFF)
 option(UA_BUILD_UNIT_TESTS "Build the unit tests" OFF)
 option(UA_BUILD_FUZZING "Build the fuzzing executables" OFF)
+mark_as_advanced(UA_BUILD_FUZZING)
+if (UA_BUILD_FUZZING)
+    # oss-fuzz already defines this by default
+    add_definitions(-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
+endif()
 option(UA_BUILD_OSS_FUZZ "Special build switch used in oss-fuzz" OFF)
 mark_as_advanced(UA_BUILD_OSS_FUZZ)
 option(UA_DEBUG_DUMP_PKGS "Dump every package received by the server as hexdump format" OFF)

+ 4 - 0
src/server/ua_server_binary.c

@@ -421,6 +421,7 @@ processMSG(UA_Server *server, UA_SecureChannel *channel,
     /* Set an anonymous, inactive session for services that need no session */
     UA_Session anonymousSession;
     if(!session) {
+		#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
         if(sessionRequired) {
             UA_LOG_INFO_CHANNEL(server->config.logger, channel,
                                 "Service request %i without a valid session",
@@ -429,12 +430,14 @@ processMSG(UA_Server *server, UA_SecureChannel *channel,
             return sendServiceFault(channel, msg, requestPos, responseType,
                                     requestId, UA_STATUSCODE_BADSESSIONIDINVALID);
         }
+		#endif
         UA_Session_init(&anonymousSession);
         anonymousSession.sessionId = UA_NODEID_GUID(0, UA_GUID_NULL);
         anonymousSession.channel = channel;
         session = &anonymousSession;
     }
 
+	#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
     /* Trying to use a non-activated session? */
     if(sessionRequired && !session->activated) {
         UA_LOG_INFO_SESSION(server->config.logger, session,
@@ -446,6 +449,7 @@ processMSG(UA_Server *server, UA_SecureChannel *channel,
         return sendServiceFault(channel, msg, requestPos, responseType,
                                 requestId, UA_STATUSCODE_BADSESSIONNOTACTIVATED);
     }
+	#endif
 
     /* The session is bound to another channel */
     if(session->channel != channel) {

+ 7 - 1
src/ua_securechannel.c

@@ -422,8 +422,10 @@ sendChunkSymmetric(UA_ChunkInfo* ci, UA_Byte **buf_pos, const UA_Byte **buf_end)
     if(ci->chunksSoFar > connection->remoteConf.maxChunkCount &&
        connection->remoteConf.maxChunkCount != 0)
         ci->errorCode = UA_STATUSCODE_BADRESPONSETOOLARGE;
-    if(ci->errorCode != UA_STATUSCODE_GOOD)
+    if(ci->errorCode != UA_STATUSCODE_GOOD) {
+        connection->releaseSendBuffer(channel->connection, &ci->messageBuffer);
         return ci->errorCode;
+    }
 
     /* Pad the message. The bytes for the padding and signature were removed
      * from buf_end before encoding the payload. So we don't check here. */
@@ -802,11 +804,13 @@ checkAsymHeader(UA_SecureChannel *const channel,
 static UA_StatusCode
 checkSymHeader(UA_SecureChannel *const channel,
                const UA_UInt32 tokenId) {
+    #ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
     if(tokenId != channel->securityToken.tokenId) {
         if(tokenId != channel->nextSecurityToken.tokenId)
             return UA_STATUSCODE_BADSECURECHANNELTOKENUNKNOWN;
         return UA_SecureChannel_revolveTokens(channel);
     }
+    #endif
 
     return UA_STATUSCODE_GOOD;
 }
@@ -823,10 +827,12 @@ UA_SecureChannel_processChunk(UA_SecureChannel *channel, UA_ByteString *chunk,
     if(retval != UA_STATUSCODE_GOOD)
         return retval;
 
+    #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION)
     /* The wrong ChannelId. Non-opened channels have the id zero. */
     if(messageHeader.secureChannelId != channel->securityToken.channelId &&
        channel->state != UA_SECURECHANNELSTATE_FRESH)
         return UA_STATUSCODE_BADSECURECHANNELIDINVALID;
+    #endif
 
     UA_MessageType messageType = (UA_MessageType)
         (messageHeader.messageHeader.messageTypeAndChunkType & UA_BITMASK_MESSAGETYPE);

+ 2 - 2
tests/fuzz/CMakeLists.txt

@@ -20,8 +20,8 @@ if (NOT UA_BUILD_OSS_FUZZ)
         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O1 -fsanitize=address")
         set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O1 -fsanitize=address")
     else()
-        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp")
-        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp")
+        set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-omit-frame-pointer -gline-tables-only -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp")
+        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer -gline-tables-only -fsanitize=address -fsanitize-address-use-after-scope -fsanitize-coverage=trace-pc-guard,trace-cmp")
     endif()
     set(LIBS Fuzzer)
     set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})

+ 1 - 0
tests/fuzz/fuzz_binary_message.cc

@@ -28,6 +28,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
     UA_Server_processBinaryMessage(server, &c, &msg);
 	// if we got an invalid chunk, the message is not deleted, so delete it here
     UA_ByteString_deleteMembers(&msg);
+	UA_Server_run_shutdown(server);
     UA_Server_delete(server);
     UA_ServerConfig_delete(config);
     UA_Connection_deleteMembers(&c);

+ 0 - 2
tests/testing_networklayers.c

@@ -26,12 +26,10 @@ dummySend(UA_Connection *connection, UA_ByteString *buf) {
 
 static void
 dummyReleaseRecvBuffer(UA_Connection *connection, UA_ByteString *buf) {
-    UA_ByteString_deleteMembers(buf);
 }
 
 static void
 dummyClose(UA_Connection *connection) {
-    return;
 }
 
 UA_Connection createDummyConnection(void) {