Browse Source

If node references itself deleting it resulted in an endless loop

https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4593

Credit to oss-fuzz
Stefan Profanter 7 years ago
parent
commit
d553fc7d98
1 changed files with 6 additions and 3 deletions
  1. 6 3
      src/server/ua_services_nodemanagement.c

+ 6 - 3
src/server/ua_services_nodemanagement.c

@@ -80,12 +80,12 @@ checkParentReference(UA_Server *server, UA_Session *session, UA_NodeClass nodeCl
     if(referenceType->nodeClass != UA_NODECLASS_REFERENCETYPE) {
     if(referenceType->nodeClass != UA_NODECLASS_REFERENCETYPE) {
         UA_LOG_INFO_SESSION(server->config.logger, session,
         UA_LOG_INFO_SESSION(server->config.logger, session,
                             "AddNodes: Reference type to the parent invalid");
                             "AddNodes: Reference type to the parent invalid");
-		UA_Nodestore_release(server, (const UA_Node*)referenceType);
+        UA_Nodestore_release(server, (const UA_Node*)referenceType);
         return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
         return UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
     }
     }
 
 
-	UA_Boolean referenceTypeIsAbstract = referenceType->isAbstract;
-	UA_Nodestore_release(server, (const UA_Node*)referenceType);
+    UA_Boolean referenceTypeIsAbstract = referenceType->isAbstract;
+    UA_Nodestore_release(server, (const UA_Node*)referenceType);
     /* Check that the reference type is not abstract */
     /* Check that the reference type is not abstract */
     if(referenceTypeIsAbstract == true) {
     if(referenceTypeIsAbstract == true) {
         UA_LOG_INFO_SESSION(server->config.logger, session,
         UA_LOG_INFO_SESSION(server->config.logger, session,
@@ -1131,6 +1131,9 @@ removeChildren(UA_Server *server, UA_Session *session,
     /* Remove every child */
     /* Remove every child */
     for(size_t i = 0; i < br.referencesSize; ++i) {
     for(size_t i = 0; i < br.referencesSize; ++i) {
         UA_ReferenceDescription *rd = &br.references[i];
         UA_ReferenceDescription *rd = &br.references[i];
+        // check for self-reference to avoid endless loop
+        if (UA_NodeId_equal(&node->nodeId, &rd->nodeId.nodeId))
+            continue;
         item.nodeId = rd->nodeId.nodeId;
         item.nodeId = rd->nodeId.nodeId;
         UA_StatusCode retval;
         UA_StatusCode retval;
         deleteNodeOperation(server, session, &item, &retval);
         deleteNodeOperation(server, session, &item, &retval);