diff --git a/osquery/tables/system/darwin/smc_keys.cpp b/osquery/tables/system/darwin/smc_keys.cpp index 4cb5c1c8..687c4812 100644 --- a/osquery/tables/system/darwin/smc_keys.cpp +++ b/osquery/tables/system/darwin/smc_keys.cpp @@ -487,28 +487,19 @@ QueryData genSMCKeys(QueryContext &context) { return results; } -void genTemperature(const std::string &key, - const SMCHelper &smc, +void genTemperature(const Row &row, QueryData &results) { - QueryData key_data; - genSMCKey(key, smc, key_data); - - if (key_data.empty()) { - // The SMC search for key information failed. - return; - } - - auto &smcRow = key_data.back(); - if (smcRow["value"].empty()) { + auto &smcRow = row; + if (smcRow.at("value").empty()) { return; } Row r; - r["key"] = smcRow["key"]; - r["name"] = kSMCKeyDescriptions.at(smcRow["key"]); + r["key"] = smcRow.at("key"); + r["name"] = kSMCKeyDescriptions.at(smcRow.at("key")); - float celsiusValue = getConvertedValue(smcRow["type"], smcRow["value"]); - float fahrenheitValue = (celsiusValue * (9 / 5)) + 32; + float celsiusValue = getConvertedValue(smcRow.at("type"), smcRow.at("value")); + float fahrenheitValue = (celsiusValue * (9.0 / 5.0)) + 32; std::stringstream buff; std::stringstream buff2; @@ -533,40 +524,39 @@ QueryData getTemperatures(QueryContext &context) { EQUALS, ([&smc, &results](const std::string &expr) { if (kSMCTemperatureKeys.count(expr) > 0) { - genTemperature(expr, smc, results); + QueryData key_data; + genSMCKey(expr, smc, key_data); + if (!key_data.empty()) { + genTemperature(key_data.back(), results); + } } })); } else { // Perform a full scan of temperature keys. for (const auto &smcTempKey : kSMCTemperatureKeys) { - genTemperature(smcTempKey, smc, results); + QueryData key_data; + genSMCKey(smcTempKey, smc, key_data); + if (!key_data.empty()) { + genTemperature(key_data.back(), results); + } } } return results; } -void genVoltage(const std::string &key, - const SMCHelper &smc, - QueryData &results) { - QueryData key_data; - genSMCKey(key, smc, key_data); - - if (key_data.empty()) { - // The SMC search for key information failed. - return; - } - - auto &smcRow = key_data.back(); - if (smcRow["value"].empty()) { +void genVoltage(const Row &row, + QueryData &results) { + auto &smcRow = row; + if (smcRow.at("value").empty()) { return; } Row r; - r["key"] = smcRow["key"]; - r["name"] = kSMCKeyDescriptions.at(smcRow["key"]); + r["key"] = smcRow.at("key"); + r["name"] = kSMCKeyDescriptions.at(smcRow.at("key")); - float value = getConvertedValue(smcRow["type"], smcRow["value"]); + float value = getConvertedValue(smcRow.at("type"), smcRow.at("value")); std::stringstream buff; buff << std::fixed << std::setprecision(2) << value; @@ -588,13 +578,21 @@ QueryData getVoltages(QueryContext &context) { EQUALS, ([&smc, &results](const std::string &expr) { if (kSMCVoltageKeys.count(expr) > 0) { - genVoltage(expr, smc, results); + QueryData key_data; + genSMCKey(expr, smc, key_data); + if (!key_data.empty()) { + genVoltage(key_data.back(), results); + } } })); } else { // Perform a full scan of voltage keys. for (const auto &smcVoltageKey : kSMCVoltageKeys) { - genVoltage(smcVoltageKey, smc, results); + QueryData key_data; + genSMCKey(smcVoltageKey, smc, key_data); + if (!key_data.empty()) { + genVoltage(key_data.back(), results); + } } } diff --git a/osquery/tables/system/darwin/tests/smc_tests.cpp b/osquery/tables/system/darwin/tests/smc_tests.cpp new file mode 100644 index 00000000..897b990e --- /dev/null +++ b/osquery/tables/system/darwin/tests/smc_tests.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2014-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#include + +#include +#include + +#include "osquery/core/test_util.h" + +namespace osquery { +namespace tables { + +void genTemperature(const Row &row, + QueryData &results); +void genVoltage(const Row &row, + QueryData &results); + +class SmcTests : public testing::Test {}; + +TEST_F(SmcTests, test_gen_temperature) { + QueryData results; + // Generate a set of results/single row using an example smc temperature key. + Row param = { + {"key", "TC0E"}, + {"type", "sp78"}, + {"size", "2"}, + {"value", "3dd0"}, + {"hidden", "0"}, + }; + genTemperature(param, results); + + Row expected = { + {"key", "TC0E"}, + {"name", "CPU 1"}, + {"celsius", "60.8"}, + {"fahrenheit", "141.5"}, + }; + + // We could compare the entire map, but iterating the columns will produce + // better error text as most likely parsing for a certain column/type changed. + for (const auto& column : expected) { + EXPECT_EQ(results[0][column.first], column.second); + } +} + +TEST_F(SmcTests, test_gen_voltage) { + QueryData results; + // Generate a set of results/single row using an example smc voltage key. + Row param = { + {"key", "VC0C"}, + {"type", "sp5a"}, + {"size", "2"}, + {"value", "035b"}, + {"hidden", "0"}, + }; + genVoltage(param, results); + + Row expected = { + {"key", "VC0C"}, + {"name", "CPU Core 1"}, + {"value", "0.84"}, + }; + + // We could compare the entire map, but iterating the columns will produce + // better error text as most likely parsing for a certain column/type changed. + for (const auto& column : expected) { + EXPECT_EQ(results[0][column.first], column.second); + } +} + +} +}