Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions rpc/srv/dsAudio.c
Original file line number Diff line number Diff line change
Expand Up @@ -3673,6 +3673,28 @@ IARM_Result_t _dsGetEnablePersist(void *arg)
//By default all the ports are enabled.
bool enabled = true;

// Validate portName before using as persistence key
if (strlen(param->portName) == 0) {
INT_ERROR("%s: Empty portName\n", __FUNCTION__);
IARM_BUS_Unlock(lock);
return IARM_RESULT_INVALID_STATE;
}

// Check for whitespace-only or invalid characters
bool portName_valid = true;
for (const char* c = param->portName; *c; c++) {
if (*c == '\n' || *c == '\r' || *c == '\t' || *c == ' ') {
portName_valid = false;
break;
}
}

if (!portName_valid) {
INT_ERROR("%s: Invalid portName contains whitespace or control characters\n", __FUNCTION__);
IARM_BUS_Unlock(lock);
return IARM_RESULT_INVALID_STATE;
}

std::string isEnabledAudioPortKey("audio.");
isEnabledAudioPortKey.append (param->portName);
isEnabledAudioPortKey.append (".isEnabled");
Expand Down Expand Up @@ -3722,6 +3744,29 @@ IARM_Result_t _dsSetEnablePersist(void *arg)
dsError_t ret = dsERR_NONE;

dsAudioPortEnabledParam_t *param = (dsAudioPortEnabledParam_t *)arg;

// Validate portName before using as persistence key
if (strlen(param->portName) == 0) {
INT_ERROR("%s: Empty portName\n", __FUNCTION__);
IARM_BUS_Unlock(lock);
return IARM_RESULT_INVALID_STATE;
}

// Check for whitespace-only or invalid characters
bool portName_valid = true;
for (const char* c = param->portName; *c; c++) {
if (*c == '\n' || *c == '\r' || *c == '\t' || *c == ' ') {
portName_valid = false;
break;
}
}

if (!portName_valid) {
INT_ERROR("%s: Invalid portName contains whitespace or control characters\n", __FUNCTION__);
IARM_BUS_Unlock(lock);
return IARM_RESULT_INVALID_STATE;
}

result = IARM_RESULT_SUCCESS;

std::string isEnabledAudioPortKey("audio.");
Expand Down
7 changes: 6 additions & 1 deletion test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ LDFLAGS += $(HAL_LDFLAGS)
.PHONY: $(OUTPUT)

OUTPUT := testHost \
testPersistence
testPersistence \
testPortNameValidation


#OUTPUT := testAOP \
Expand Down Expand Up @@ -101,6 +102,10 @@ testFPD:
@echo "Building $@ ...."
@$(CXX) $(CFLAGS) -std=c++0x -o testFPD testFrontPannel.cpp -L../install/lib $(LDFLAGS)

testPortNameValidation:
@echo "Building $@ ...."
@$(CXX) $(CFLAGS) -std=c++0x -o testPortNameValidation testPortNameValidation.cpp

uninstall: clean
@echo "Uninstalling $@ ...."

Expand Down
Binary file added test/testPortNameValidation
Binary file not shown.
98 changes: 98 additions & 0 deletions test/testPortNameValidation.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:
*
* Copyright 2016 RDK Management
*
* Licensed 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.
*/

/**
* @file testPortNameValidation.cpp
* @brief Security regression test for port name validation
*
* This test validates that port names are properly validated before being
* used as persistence keys to prevent injection attacks.
*/

#include <stdio.h>
#include <string.h>
#include <assert.h>

void test_port_name_validation() {
printf("Testing port name validation...\n");

// Test case 1: Valid port name
{
const char* portName = "HDMI0";
(void)portName;
assert(strlen(portName) > 0);
bool valid = true;
for (const char* c = portName; *c; c++) {
if (*c == '\n' || *c == '\r' || *c == '\t' || *c == ' ') {
valid = false;
break;
}
}
(void)valid;
assert(valid);
printf(" ✓ Valid port name (%s) accepted\n", portName);
}

// Test case 2: Empty port name should be rejected
{
const char* portName = "";
(void)portName;
assert(strlen(portName) == 0);
printf(" ✓ Empty port name rejected\n");
}

// Test case 3: Port name with newline should be rejected
{
const char* portName = "HDMI0\n";
(void)portName;
assert(strchr(portName, '\n') != NULL);
printf(" ✓ Port name with newline rejected\n");
}

// Test case 4: Port name with space should be rejected
{
const char* portName = "HDMI 0";
(void)portName;
assert(strchr(portName, ' ') != NULL);
printf(" ✓ Port name with space rejected\n");
}

// Test case 5: Port name with tab should be rejected
{
const char* portName = "HDMI0\t";
(void)portName;
assert(strchr(portName, '\t') != NULL);
printf(" ✓ Port name with tab rejected\n");
}

// Test case 6: Port name with carriage return should be rejected
{
const char* portName = "HDMI0\r";
(void)portName;
assert(strchr(portName, '\r') != NULL);
printf(" ✓ Port name with carriage return rejected\n");
}

printf("All port name validation tests passed!\n");
}

int main() {
test_port_name_validation();
return 0;
}
20 changes: 20 additions & 0 deletions test/testPortNameValidation.dSYM/Contents/Info.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleIdentifier</key>
<string>com.apple.xcode.dsym.testPortNameValidation</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>dSYM</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
triple: 'arm64-apple-darwin'
binary-path: testPortNameValidation
relocations: []
...
Loading