Fix resource attribute cleanup function 47/23847/3
authorMats Wichmann <mats@linux.com>
Sat, 30 Dec 2017 18:16:45 +0000 (11:16 -0700)
committerMats Wichmann <mats@linux.com>
Wed, 7 Feb 2018 16:01:46 +0000 (16:01 +0000)
The internal cleanup function OCDeleteResourceAttributes does not
properly account for two of attribute names, which indicate the
matching value will be an OCStringLL, instead freeing them as if
they were strings.  This leads to a memory leak. valgrind on the
stack unittests was showing four side effects of these:

0x4     3 bytes in 1 blocks are definitely lost in loss record 3 of 988
0x5     3 bytes in 1 blocks are definitely lost in loss record 4 of 988
0x259   75 (16 direct, 59 indirect) bytes in 1 blocks are definitely lost in loss record 600 of 988
0x268   76 (16 direct, 60 indirect) bytes in 1 blocks are definitely lost in loss record 615 of 988

If you trace these back in the report they are attributable to
exactly the two tests which use the unhandled cases:

    OCStringLL *ld = NULL;
    OCResourcePayloadAddStringLL(&ld, "en");
    OCResourcePayloadAddStringLL(&ld, "Description");
    OCResourcePayloadAddStringLL(&ld, "de");
    OCResourcePayloadAddStringLL(&ld, "Beschriebung");
    EXPECT_EQ(OC_STACK_OK, OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_DESCRIPTION, ld));

and

    OCStringLL *dmn = NULL;
    OCResourcePayloadAddStringLL(&dmn, "en");
    OCResourcePayloadAddStringLL(&dmn, "Manufacturer");
    OCResourcePayloadAddStringLL(&dmn, "de");
    OCResourcePayloadAddStringLL(&dmn, "Hersteller");
    EXPECT_EQ(OC_STACK_OK, OCSetPropertyValue(PAYLOAD_TYPE_DEVICE, OC_RSRVD_DEVICE_MFG_NAME, dmn));

The fix is simply to detect these two cases and free them the
proper way.

Bug: https://jira.iotivity.org/browse/IOT-2950
Change-Id: Idf95552035fdbc725a3b7919bb1036e8885e66cd
Signed-off-by: Mats Wichmann <mats@linux.com>
resource/csdk/stack/src/ocstack.c

index 80e2154..c180f3b 100644 (file)
@@ -5437,7 +5437,9 @@ void OCDeleteResourceAttributes(OCAttribute *rsrcAttributes)
     for (OCAttribute *pointer = rsrcAttributes; pointer; pointer = next)
     {
         next = pointer->next;
-        if (pointer->attrName && 0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, pointer->attrName))
+        if (pointer->attrName && (0 == strcmp(OC_RSRVD_DATA_MODEL_VERSION, pointer->attrName) ||
+                                  0 == strcmp(OC_RSRVD_DEVICE_DESCRIPTION, pointer->attrName) ||
+                                  0 == strcmp(OC_RSRVD_DEVICE_MFG_NAME, pointer->attrName)))
         {
             OCFreeOCStringLL((OCStringLL *)pointer->attrValue);
         }