Skip to content

Commit

Permalink
Avoid segment fault in ASIC/SDK health event handling when vendor SAI…
Browse files Browse the repository at this point in the history
… passes an invalid timestamp

Signed-off-by: Stephen Sun <[email protected]>
  • Loading branch information
stephenxs committed Jan 1, 2025
1 parent eae729e commit f1ca314
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 25 deletions.
11 changes: 10 additions & 1 deletion orchagent/switchorch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1115,8 +1115,17 @@ void SwitchOrch::onSwitchAsicSdkHealthEvent(sai_object_id_t switch_id,
const string &severity_str = switch_asic_sdk_health_event_severity_reverse_map.at(severity);
const string &category_str = switch_asic_sdk_health_event_category_reverse_map.at(category);
string description_str;
const std::time_t &t = (std::time_t)timestamp.tv_sec;
std::time_t t = (std::time_t)timestamp.tv_sec;
const std::time_t now = std::time(0);
const double year_in_seconds = 86400 * 365;
stringstream time_ss;

if (difftime(t, now) > year_in_seconds)
{
SWSS_LOG_ERROR("Invalid timestamp second %lu in received ASIC/SDK health event, reset to current time", timestamp.tv_sec);
t = now;
}

time_ss << std::put_time(std::localtime(&t), "%Y-%m-%d %H:%M:%S");

switch (data.data_type)
Expand Down
69 changes: 45 additions & 24 deletions tests/mock_tests/switchorch_ut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,44 @@ namespace switchorch_test
gSwitchOrch = new SwitchOrch(m_app_db.get(), switch_tables, stateDbSwitchTable);
}

void checkAsicSdkHealthEvent(const sai_timespec_t &timestamp, const string &expected_key="")
{
initSwitchOrch();

sai_switch_health_data_t data;
memset(&data, 0, sizeof(data));
data.data_type = SAI_HEALTH_DATA_TYPE_GENERAL;
vector<uint8_t> data_from_sai({100, 101, 115, 99, 114, 105, 112, 116, 105, 245, 111, 110, 245, 10, 123, 125, 100, 100});
sai_u8_list_t description;
description.list = data_from_sai.data();
description.count = (uint32_t)(data_from_sai.size() - 2);
on_switch_asic_sdk_health_event(gSwitchId,
SAI_SWITCH_ASIC_SDK_HEALTH_SEVERITY_FATAL,
timestamp,
SAI_SWITCH_ASIC_SDK_HEALTH_CATEGORY_FW,
data,
description);

string key;
if (expected_key.empty())
{
vector<string> keys;
gSwitchOrch->m_asicSdkHealthEventTable->getKeys(keys);
key = keys[0];
}
else
{
key = expected_key;
}
string value;
gSwitchOrch->m_asicSdkHealthEventTable->hget(key, "category", value);
ASSERT_EQ(value, "firmware");
gSwitchOrch->m_asicSdkHealthEventTable->hget(key, "severity", value);
ASSERT_EQ(value, "fatal");
gSwitchOrch->m_asicSdkHealthEventTable->hget(key, "description", value);
ASSERT_EQ(value, "description\n{}");
}

void TearDown() override
{
::testing_db::reset();
Expand Down Expand Up @@ -289,30 +327,13 @@ namespace switchorch_test

TEST_F(SwitchOrchTest, SwitchOrchTestHandleEvent)
{
initSwitchOrch();

sai_timespec_t timestamp = {.tv_sec = 1701160447, .tv_nsec = 538710245};
sai_switch_health_data_t data;
memset(&data, 0, sizeof(data));
data.data_type = SAI_HEALTH_DATA_TYPE_GENERAL;
vector<uint8_t> data_from_sai({100, 101, 115, 99, 114, 105, 112, 116, 105, 245, 111, 110, 245, 10, 123, 125, 100, 100});
sai_u8_list_t description;
description.list = data_from_sai.data();
description.count = (uint32_t)(data_from_sai.size() - 2);
on_switch_asic_sdk_health_event(gSwitchId,
SAI_SWITCH_ASIC_SDK_HEALTH_SEVERITY_FATAL,
timestamp,
SAI_SWITCH_ASIC_SDK_HEALTH_CATEGORY_FW,
data,
description);

string key = "2023-11-28 08:34:07";
string value;
gSwitchOrch->m_asicSdkHealthEventTable->hget(key, "category", value);
ASSERT_EQ(value, "firmware");
gSwitchOrch->m_asicSdkHealthEventTable->hget(key, "severity", value);
ASSERT_EQ(value, "fatal");
gSwitchOrch->m_asicSdkHealthEventTable->hget(key, "description", value);
ASSERT_EQ(value, "description\n{}");
checkAsicSdkHealthEvent(timestamp, "2023-11-28 08:34:07");
}

TEST_F(SwitchOrchTest, SwitchOrchTestHandleEventInvalidTimeStamp)
{
sai_timespec_t timestamp = {.tv_sec = 172479515853275099, .tv_nsec = 538710245};
checkAsicSdkHealthEvent(timestamp);
}
}

0 comments on commit f1ca314

Please sign in to comment.