From 9a5602fbd822239fd94877ef768a87809afd5f35 Mon Sep 17 00:00:00 2001 From: PengZheng Date: Mon, 1 Jan 2024 12:41:29 +0800 Subject: [PATCH 1/4] [CID 335557]Fix use-after-free in http_admin --- bundles/http_admin/http_admin/src/websocket_admin.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/bundles/http_admin/http_admin/src/websocket_admin.c b/bundles/http_admin/http_admin/src/websocket_admin.c index 2cd8a4531..287796835 100644 --- a/bundles/http_admin/http_admin/src/websocket_admin.c +++ b/bundles/http_admin/http_admin/src/websocket_admin.c @@ -27,6 +27,7 @@ #include "websocket_admin.h" #include "celix_compiler.h" +#include "celix_stdlib_cleanup.h" #include "celix_utils_api.h" struct websocket_admin_manager { @@ -41,7 +42,7 @@ struct websocket_admin_manager { websocket_admin_manager_t *websocketAdmin_create(celix_bundle_context_t *context, struct mg_context *svr_ctx) { celix_status_t status; - websocket_admin_manager_t *admin = (websocket_admin_manager_t *) calloc(1, sizeof(websocket_admin_manager_t)); + celix_autofree websocket_admin_manager_t *admin = (websocket_admin_manager_t *) calloc(1, sizeof(websocket_admin_manager_t)); if (admin == NULL) { return NULL; @@ -53,10 +54,10 @@ websocket_admin_manager_t *websocketAdmin_create(celix_bundle_context_t *context if(status != CELIX_SUCCESS) { //No need to destroy other things - free(admin); + return NULL; } - return admin; + return celix_steal_ptr(admin); } void websocketAdmin_destroy(websocket_admin_manager_t *admin) { From ddefef83cdf7846c6d5183a8ecb54753f45ff6d9 Mon Sep 17 00:00:00 2001 From: PengZheng Date: Mon, 1 Jan 2024 12:44:44 +0800 Subject: [PATCH 2/4] Remove ip_utils and its tests. --- libs/utils/CMakeLists.txt | 5 - libs/utils/gtest/CMakeLists.txt | 1 - .../src/IpUtilsErrorInjectionTestSuite.cc | 47 ----- libs/utils/include_deprecated/ip_utils.h | 52 ------ libs/utils/private/test/ip_utils_test.cpp | 108 ----------- libs/utils/src/ip_utils.c | 170 ------------------ 6 files changed, 383 deletions(-) delete mode 100644 libs/utils/gtest/src/IpUtilsErrorInjectionTestSuite.cc delete mode 100644 libs/utils/include_deprecated/ip_utils.h delete mode 100644 libs/utils/private/test/ip_utils_test.cpp delete mode 100644 libs/utils/src/ip_utils.c diff --git a/libs/utils/CMakeLists.txt b/libs/utils/CMakeLists.txt index f9b012602..8438af2e7 100644 --- a/libs/utils/CMakeLists.txt +++ b/libs/utils/CMakeLists.txt @@ -40,7 +40,6 @@ if (UTILS) src/version_range.c src/properties.c src/utils.c - src/ip_utils.c src/filter.c src/celix_log_level.c src/celix_log_utils.c @@ -157,10 +156,6 @@ if (UTILS) target_include_directories(linked_list_test PRIVATE include_deprecated) target_link_libraries(linked_list_test utils_cut CppUTest pthread) - add_executable(ip_utils_test private/test/ip_utils_test.cpp) - target_include_directories(ip_utils_test PRIVATE include_deprecated) - target_link_libraries(ip_utils_test CppUTest utils_cut pthread) - add_test(NAME run_array_list_test COMMAND array_list_test) add_test(NAME run_hash_map_test COMMAND hash_map_test) add_test(NAME run_linked_list_test COMMAND linked_list_test) diff --git a/libs/utils/gtest/CMakeLists.txt b/libs/utils/gtest/CMakeLists.txt index 8b6381dc2..782554ad9 100644 --- a/libs/utils/gtest/CMakeLists.txt +++ b/libs/utils/gtest/CMakeLists.txt @@ -93,7 +93,6 @@ if (EI_TESTS) add_executable(test_utils_with_ei src/FileUtilsErrorInjectionTestSuite.cc src/ConvertUtilsErrorInjectionTestSuite.cc - src/IpUtilsErrorInjectionTestSuite.cc src/ArrayListErrorInjectionTestSuite.cc src/ErrErrorInjectionTestSuite.cc src/PropertiesErrorInjectionTestSuite.cc diff --git a/libs/utils/gtest/src/IpUtilsErrorInjectionTestSuite.cc b/libs/utils/gtest/src/IpUtilsErrorInjectionTestSuite.cc deleted file mode 100644 index 57a4c83cd..000000000 --- a/libs/utils/gtest/src/IpUtilsErrorInjectionTestSuite.cc +++ /dev/null @@ -1,47 +0,0 @@ -/* - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. - */ - -#include -#include -#include "ifaddrs_ei.h" -#include "ip_utils.h" -#include "celix_utils_ei.h" - -class IpUtilsWithErrorInjectionTestSuite : public ::testing::Test { -public: - IpUtilsWithErrorInjectionTestSuite() = default; - ~IpUtilsWithErrorInjectionTestSuite() override { - celix_ei_expect_getifaddrs(nullptr, 0, 0); - celix_ei_expect_celix_utils_strdup(nullptr, 0, 0); - } -}; - -TEST_F(IpUtilsWithErrorInjectionTestSuite, failToGetInterfaceAddresses) { - celix_ei_expect_getifaddrs((void *)&ipUtils_findIpBySubnet, 0, -1); - auto ipAddresses = ipUtils_findIpBySubnet("192.168.1.0/24"); - EXPECT_EQ(ipAddresses, nullptr); - EXPECT_EQ(errno, EMFILE); -} - -TEST_F(IpUtilsWithErrorInjectionTestSuite, failToDuplicateString) { - celix_ei_expect_celix_utils_strdup((void *) &ipUtils_findIpBySubnet, 0, nullptr); - auto ipAddresses = ipUtils_findIpBySubnet("192.168.1.0/24"); - EXPECT_EQ(ipAddresses, nullptr); - EXPECT_EQ(errno, ENOMEM); -} \ No newline at end of file diff --git a/libs/utils/include_deprecated/ip_utils.h b/libs/utils/include_deprecated/ip_utils.h deleted file mode 100644 index 75adcb595..000000000 --- a/libs/utils/include_deprecated/ip_utils.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/** - * ip_utils.h - * - * \date Jun 24, 2019 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#ifndef IP_UTILS_H_ -#define IP_UTILS_H_ - -#include - -#include "celix_errno.h" -#include "celix_utils_export.h" - -#ifdef __cplusplus -extern "C" { -#endif - -CELIX_UTILS_DEPRECATED_EXPORT unsigned int ipUtils_ipToUnsignedInt(char *ip); - -CELIX_UTILS_DEPRECATED_EXPORT char *ipUtils_unsignedIntToIp(unsigned int ip); - -CELIX_UTILS_DEPRECATED_EXPORT unsigned int ipUtils_prefixToBitmask(unsigned int prefix); - -CELIX_UTILS_DEPRECATED_EXPORT int ipUtils_netmaskToPrefix(const char *netmask); - -CELIX_UTILS_DEPRECATED_EXPORT char *ipUtils_findIpBySubnet(const char *ipWithPrefix); - -#ifdef __cplusplus -} -#endif -#endif /* IP_UTILS_H_ */ diff --git a/libs/utils/private/test/ip_utils_test.cpp b/libs/utils/private/test/ip_utils_test.cpp deleted file mode 100644 index 7b576b3af..000000000 --- a/libs/utils/private/test/ip_utils_test.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/** - * ip_utils_test.cpp - * - * \date Jun 24, 2019 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#include -#include -#include -#include - -#include "CppUTest/TestHarness.h" -#include "CppUTest/TestHarness_c.h" -#include "CppUTest/CommandLineTestRunner.h" - -extern "C" -{ -#include "ip_utils.h" -} - -int main(int argc, char** argv) { - MemoryLeakWarningPlugin::turnOffNewDeleteOverloads(); - return RUN_ALL_TESTS(argc, argv); -} - -static char* my_strdup(const char* s){ - if(s==NULL){ - return NULL; - } - - size_t len = strlen(s); - - char *d = (char*) calloc (len + 1,sizeof(char)); - - if (d == NULL){ - return NULL; - } - - strncpy (d,s,len); - return d; -} - -TEST_GROUP(ip_utils) { - void setup(void) { - } - - void teardown() { - } -}; - -TEST(ip_utils, ipToUnsignedInt){ - char *ip = my_strdup("192.168.1.64"); - - unsigned int expected = 3232235840; - unsigned int actual = ipUtils_ipToUnsignedInt(ip); - UNSIGNED_LONGS_EQUAL(expected, actual); - - free(ip); -} - -TEST(ip_utils, unsignedIntToIp){ - unsigned int ipAsUint = 3232235840; - - const char *expected = "192.168.1.64"; - char *actual = ipUtils_unsignedIntToIp(ipAsUint); - STRCMP_EQUAL(expected, actual); - free(actual); -} - -TEST(ip_utils, prefixToBitmask){ - unsigned int expected = 4294967264; - unsigned int actual = ipUtils_prefixToBitmask(27); - - UNSIGNED_LONGS_EQUAL(expected, actual); -} - -TEST(ip_utils, netmaskToPrefix){ - char *netmask = my_strdup("255.255.255.0"); - - int expected = 24; - int actual = ipUtils_netmaskToPrefix(netmask); - LONGS_EQUAL(expected, actual); - - free(netmask); - - actual = ipUtils_netmaskToPrefix("a.b.c.d"); - LONGS_EQUAL(-1, actual); -} diff --git a/libs/utils/src/ip_utils.c b/libs/utils/src/ip_utils.c deleted file mode 100644 index d168fa367..000000000 --- a/libs/utils/src/ip_utils.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -/** - * ip_utils.c - * - * \date Jun 24, 2019 - * \author Apache Celix Project Team - * \copyright Apache License, Version 2.0 - */ - -#include "ip_utils.h" -#include "celix_utils.h" - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -unsigned int ipUtils_ipToUnsignedInt(char *ip) { - unsigned int ipAsUint = 0; - - char *partOfIp = NULL, *savePtr = NULL; - char *input = strdup(ip); // Make a copy because otherwise strtok_r manipulates the input string - partOfIp = strtok_r(input, ".\0", &savePtr); ipAsUint += strtoul(partOfIp, NULL, 10) * (unsigned int) pow(256, 3); - partOfIp = strtok_r(NULL, ".\0", &savePtr); ipAsUint += strtoul(partOfIp, NULL, 10) * (unsigned int) pow(256, 2); - partOfIp = strtok_r(NULL, ".\0", &savePtr); ipAsUint += strtoul(partOfIp, NULL, 10) * (unsigned int) pow(256, 1); - partOfIp = strtok_r(NULL, ".\0", &savePtr); ipAsUint += strtoul(partOfIp, NULL, 10) * (unsigned int) pow(256, 0); - free(input); - - return ipAsUint; -} - -char *ipUtils_unsignedIntToIp(unsigned int ip) { - char *ipStr = calloc(16, sizeof(char)); - - int ipPart1 = ip / (int) pow(256, 3); ip -= ipPart1 * (int) pow(256, 3); - int ipPart2 = ip / (int) pow(256, 2); ip -= ipPart2 * (int) pow(256, 2); - int ipPart3 = ip / (int) pow(256, 1); ip -= ipPart3 * (int) pow(256, 1); - int ipPart4 = ip / (int) pow(256, 0); - - snprintf(ipStr, 16, "%d.%d.%d.%d", ipPart1, ipPart2, ipPart3, ipPart4); - - return ipStr; -} - -unsigned int ipUtils_prefixToBitmask(unsigned int prefix) { - return (0xFFFFFFFF << (32 - prefix)) & 0xFFFFFFFF; -} - -int ipUtils_netmaskToPrefix(const char *netmask) { - // Convert netmask to in_addr object - struct in_addr in; - int ret = inet_pton(AF_INET, netmask, &in); - if (ret != 1) { - return -1; - } - - // Now convert the mask to a prefix - int prefix = 0; - bool processed_one = false; - unsigned int i = ntohl(in.s_addr); - - while (i > 0) { - if (i & 1) { - prefix++; - processed_one = true; - } else { - if (processed_one) return -1; - } - - i >>= 1; - } - - return prefix; -} - -/** Finds an IP of the available network interfaces of the machine by specifying an CIDR subnet. - * - * @param ipWithPrefix IP with prefix, e.g. 192.168.1.0/24 - * @return ip In case a matching interface could be found, an allocated string containing the IP of the - * interface will be returned, e.g. 192.168.1.16. Memory for the new string can be freed with free(). - * When no matching interface is found NULL will be returned. - */ -char *ipUtils_findIpBySubnet(const char *ipWithPrefix) { - char *ip = NULL; - - char *input = celix_utils_strdup(ipWithPrefix); // Make a copy as otherwise strtok_r manipulates the input string - if (input == NULL) { - goto strdup_failed; - } - - char *savePtr; - char *inputIp = strtok_r(input, "/", &savePtr); - char *inputPrefixStr = strtok_r(NULL, "\0", &savePtr); - unsigned int inputPrefix = (unsigned int) strtoul(inputPrefixStr, NULL, 10); - - unsigned int ipAsUint = ipUtils_ipToUnsignedInt(inputIp); - unsigned int bitmask = ipUtils_prefixToBitmask(inputPrefix); - - unsigned int ipRangeStart = ipAsUint & bitmask; - unsigned int ipRangeStop = ipAsUint | ~bitmask; - - // Requested IP range is known now, now loop through network interfaces - struct ifaddrs *ifap, *ifa; - - if(getifaddrs (&ifap) == -1) { - goto getifaddrs_failed; - } - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - if (ifa->ifa_addr == NULL) - continue; - - if (ifa->ifa_addr->sa_family != AF_INET) - continue; - - // Retrieve IP address for interface - char if_addr[NI_MAXHOST]; - int rv = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), - if_addr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); - - if (rv != 0) { - printf("getnameinfo() failed: %s\n", gai_strerror(rv)); - continue; - } - - // Retrieve netmask - struct sockaddr_in *sa = (struct sockaddr_in *) ifa->ifa_netmask; - char *if_netmask = inet_ntoa(sa->sin_addr); - - unsigned int ifIpAsUint = ipUtils_ipToUnsignedInt(if_addr); - int ifPrefix = ipUtils_netmaskToPrefix(if_netmask); - if (ifPrefix == -1) { - break; - } - - if (ifIpAsUint >= ipRangeStart && ifIpAsUint <= ipRangeStop && inputPrefix >= ifPrefix) { - ip = strndup(if_addr, 1024); - break; - } - } - freeifaddrs(ifap); -getifaddrs_failed: - free(input); -strdup_failed: - return ip; -} From e76b5cf8126b3f9cafb32644a447ab8f4c705de8 Mon Sep 17 00:00:00 2001 From: PengZheng Date: Mon, 1 Jan 2024 12:50:52 +0800 Subject: [PATCH 3/4] Remove deleted test from ctest. --- libs/utils/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/utils/CMakeLists.txt b/libs/utils/CMakeLists.txt index 8438af2e7..47c4fb15c 100644 --- a/libs/utils/CMakeLists.txt +++ b/libs/utils/CMakeLists.txt @@ -159,7 +159,6 @@ if (UTILS) add_test(NAME run_array_list_test COMMAND array_list_test) add_test(NAME run_hash_map_test COMMAND hash_map_test) add_test(NAME run_linked_list_test COMMAND linked_list_test) - add_test(NAME run_ip_utils_test COMMAND ip_utils_test) setup_target_for_coverage(hash_map_test) setup_target_for_coverage(array_list_test) From 780e873235365632ea92e611d596b4ee50b32022 Mon Sep 17 00:00:00 2001 From: PengZheng Date: Mon, 1 Jan 2024 12:51:34 +0800 Subject: [PATCH 4/4] Remove deleted test from coverage. --- libs/utils/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/utils/CMakeLists.txt b/libs/utils/CMakeLists.txt index 47c4fb15c..de7286bb7 100644 --- a/libs/utils/CMakeLists.txt +++ b/libs/utils/CMakeLists.txt @@ -163,7 +163,6 @@ if (UTILS) setup_target_for_coverage(hash_map_test) setup_target_for_coverage(array_list_test) setup_target_for_coverage(linked_list_test) - setup_target_for_coverage(ip_utils_test) else () message(WARNING "Cannot find CppUTest, deprecated cpputest-based unit test will not be added") endif () #end CppUTest_FOUND