diff --git a/build_dependencies.sh b/build_dependencies.sh index 86d6c353..b890ec13 100755 --- a/build_dependencies.sh +++ b/build_dependencies.sh @@ -10,7 +10,7 @@ cd ${GITHUB_WORKSPACE} #1. Install Dependencies and packages apt update -apt install -y ninja-build meson curl libsoup2.4-dev libxml2-dev libglib2.0-dev gobject-introspection libgirepository1.0-dev libgtk-3-dev valac pandoc +apt install -y git python3 python3-pip cmake ninja-build meson curl libsoup2.4-dev libxml2-dev libglib2.0-dev gobject-introspection libgirepository1.0-dev libgtk-3-dev libcurl4-openssl-dev libcunit1-dev valac pandoc pip install jsonref ############################ @@ -28,17 +28,25 @@ cd .. rm -rf iarmbus ThunderTools Thunder entservices-apis entservices-testframework gssdp +THUNDER_TOOLS_COMMIT_SHA="d5dd83c7c19c49c7f25c558c126500bd2d64f7a4" +THUNDER_COMMIT_SHA="2c0fcc5529e7da734be558ca6efa05d934dcce31" git clone https://github.com/rdkcentral/iarmbus.git export IARMBUS_PATH=$GITHUB_WORKSPACE/iarmbus -git clone --branch R4.4.3 https://github.com/rdkcentral/ThunderTools.git +git clone --branch R4_4-RDK https://github.com/rdkcentral/ThunderTools.git +cd ThunderTools +git checkout $THUNDER_TOOLS_COMMIT_SHA +cd .. -git clone --branch R4.4.1 https://github.com/rdkcentral/Thunder.git +git clone --branch R4_4-RDK https://github.com/rdkcentral/Thunder.git +cd Thunder +git checkout $THUNDER_COMMIT_SHA +cd .. -git clone --branch main https://github.com/rdkcentral/entservices-apis.git +git clone --branch develop https://github.com/rdkcentral/entservices-apis.git -git clone https://$GITHUB_TOKEN@github.com/rdkcentral/entservices-testframework.git +git clone --branch 2.0.0 https://github.com/rdkcentral/entservices-testframework.git git clone --branch gssdp-1.2.3 https://gitlab.gnome.org/GNOME/gssdp.git @@ -60,7 +68,6 @@ cd - echo "======================================================================================" echo "buliding thunderTools" cd ThunderTools -patch -p1 < $GITHUB_WORKSPACE/entservices-testframework/patches/00010-R4.4-Add-support-for-project-dir.patch cd - @@ -79,10 +86,6 @@ echo "========================================================================== echo "buliding thunder" cd Thunder -patch -p1 < $GITHUB_WORKSPACE/entservices-testframework/patches/Use_Legact_Alt_Based_On_ThunderTools_R4.4.3.patch -patch -p1 < $GITHUB_WORKSPACE/entservices-testframework/patches/error_code_R4_4.patch -patch -p1 < $GITHUB_WORKSPACE/entservices-testframework/patches/1004-Add-support-for-project-dir.patch -patch -p1 < $GITHUB_WORKSPACE/entservices-testframework/patches/RDKEMW-733-Add-ENTOS-IDS.patch cd - cmake -G Ninja -S Thunder -B build/Thunder \ diff --git a/server/plat/gdial.cpp b/server/plat/gdial.cpp index 4876b746..c37c81dc 100644 --- a/server/plat/gdial.cpp +++ b/server/plat/gdial.cpp @@ -513,6 +513,23 @@ map parse_query(const char* query_string) { return ret; } +static bool is_authorized_system_action(const map& parsed_query) { + const char *system_key = getenv("SYSTEM_SLEEP_REQUEST_KEY"); + auto supplied = parsed_query.find("key"); + if (!system_key || system_key[0] == '\0' || supplied == parsed_query.end()) { + return false; + } + const string expected(system_key); + if (expected.size() != supplied->second.size()) { + return false; + } + unsigned char difference = 0; + for (size_t i = 0; i < expected.size(); ++i) { + difference |= static_cast(expected[i] ^ supplied->second[i]); + } + return difference == 0; +} + int gdial_os_application_start(const char *app_name, const char *payload, const char *query_string, const char *additional_data_url, int *instance_id) { GDIAL_LOGTRACE("Entering ..."); GDIAL_LOGINFO("App launch req: appName[%s] query[%s], payload[%s], additionalDataUrl [%s] instance[%p]", @@ -521,9 +538,8 @@ int gdial_os_application_start(const char *app_name, const char *payload, const if (strcmp(app_name,"system") == 0) { auto parsed_query{parse_query(query_string)}; if (parsed_query["action"] == "sleep") { - const char *system_key = getenv("SYSTEM_SLEEP_REQUEST_KEY"); - if (system_key && parsed_query["key"] != system_key) { - GDIAL_LOGINFO("system app request to change device to sleep mode, key comparison failed: user provided '%s'", parsed_query["key"].c_str()); + if (!is_authorized_system_action(parsed_query)) { + GDIAL_LOGINFO("system app request to change device to sleep mode, authorization failed"); GDIAL_LOGTRACE("Exiting ..."); return GDIAL_APP_ERROR_INTERNAL; } @@ -533,9 +549,8 @@ int gdial_os_application_start(const char *app_name, const char *payload, const return GDIAL_APP_ERROR_NONE; } else if (parsed_query["action"] == "togglepower") { - const char *system_key = getenv("SYSTEM_SLEEP_REQUEST_KEY"); - if (system_key && parsed_query["key"] != system_key) { - GDIAL_LOGINFO("system app request to toggle the power state, key comparison failed: user provided '%s'", parsed_query["key"].c_str()); + if (!is_authorized_system_action(parsed_query)) { + GDIAL_LOGINFO("system app request to toggle the power state, authorization failed"); GDIAL_LOGTRACE("Exiting ..."); return GDIAL_APP_ERROR_INTERNAL; } diff --git a/tests/test_security_system_actions.py b/tests/test_security_system_actions.py new file mode 100644 index 00000000..f379ccf4 --- /dev/null +++ b/tests/test_security_system_actions.py @@ -0,0 +1,15 @@ +import pathlib +import unittest + + +class SystemActionGuardrail(unittest.TestCase): + def test_power_actions_fail_closed(self): + source = (pathlib.Path(__file__).parents[1] / "server/plat/gdial.cpp").read_text() + self.assertIn("if (!system_key || system_key[0] == '\\0' || supplied == parsed_query.end())", source) + self.assertEqual(source.count("if (!is_authorized_system_action(parsed_query))"), 2) + self.assertNotIn("user provided '%s'", source) + self.assertIn("difference |= static_cast", source) + + +if __name__ == "__main__": + unittest.main()