mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-06 09:35:20 +00:00
Prefer /etc/os-release for Linux os_version (#2667)
This commit is contained in:
parent
5bb5ae1030
commit
df25f27efb
@ -8,6 +8,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include <boost/xpressive/xpressive.hpp>
|
||||
@ -23,38 +24,80 @@ namespace xp = boost::xpressive;
|
||||
namespace osquery {
|
||||
namespace tables {
|
||||
|
||||
#if defined(REDHAT_BASED)
|
||||
const std::string kLinuxOSRelease = "/etc/redhat-release";
|
||||
const std::string kLinuxOSRegex =
|
||||
"(?P<name>[\\w+\\s]+) .* "
|
||||
"(?P<major>[0-9]+)\\.(?P<minor>[0-9]+)\\.?(?P<patch>\\w+)?";
|
||||
#elif defined(DEBIAN)
|
||||
const std::string kLinuxOSRelease = "/etc/os-release";
|
||||
const std::string kLinuxOSRegex =
|
||||
"PRETTY_NAME=\"(?P<name>[\\w \\/]*) "
|
||||
"(?P<major>[0-9]+)[\\.]{0,1}(?P<minor>[0-9]*)[\\.]{0,1}(?P<patch>[0-9]*).*"
|
||||
"\"";
|
||||
#else
|
||||
const std::string kLinuxOSRelease = "/etc/os-release";
|
||||
#ifdef UBUNTU_XENIAL
|
||||
const std::string kLinuxOSRegex =
|
||||
"VERSION=\"(?P<major>[0-9]+)\\.(?P<minor>[0-9]+)[\\.]{0,1}(?P<patch>[0-9]+)"
|
||||
"?.* \\((?P<name>[\\w ]*)\\)\"$";
|
||||
#else
|
||||
const std::string kLinuxOSRegex =
|
||||
"VERSION=\"(?P<major>[0-9]+)\\.(?P<minor>[0-9]+)[\\.]{0,1}(?P<patch>[0-9]+)"
|
||||
"?.*, (?P<name>[\\w ]*)\"$";
|
||||
#endif
|
||||
#endif
|
||||
const std::string kOSRelease = "/etc/os-release";
|
||||
const std::string kRedhatRelease = "/etc/redhat-release";
|
||||
|
||||
QueryData genOSVersion(QueryContext& context) {
|
||||
const std::map<std::string, std::string> kOSReleaseColumns = {
|
||||
{"NAME", "name"},
|
||||
{"VERSION", "version"},
|
||||
{"BUILD_ID", "build"},
|
||||
{"ID", "platform"},
|
||||
{"ID_LIKE", "platform_like"},
|
||||
{"VERSION_CODENAME", "codename"},
|
||||
{"VERSION_ID", "_id"},
|
||||
};
|
||||
|
||||
QueryData genOSRelease() {
|
||||
// This will parse /etc/os-version according to the systemd manual.
|
||||
std::string content;
|
||||
if (!forensicReadFile(kLinuxOSRelease, content).ok()) {
|
||||
if (!readFile(kOSRelease, content).ok()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
Row r;
|
||||
auto rx = xp::sregex::compile(kLinuxOSRegex);
|
||||
for (const auto& line : osquery::split(content, "\n")) {
|
||||
auto fields = osquery::split(line, "=", 1);
|
||||
if (fields.size() != 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto column = std::ref(kOSReleaseColumns.at("VERSION_CODENAME"));
|
||||
if (kOSReleaseColumns.count(fields[0]) != 0) {
|
||||
column = std::ref(kOSReleaseColumns.at(fields[0]));
|
||||
} else if (fields[0].find("CODENAME") == std::string::npos) {
|
||||
// Some distros may attach/invent their own CODENAME field.
|
||||
continue;
|
||||
}
|
||||
|
||||
r[column] = std::move(fields[1]);
|
||||
if (!r.at(column).empty() && r.at(column)[0] == '"') {
|
||||
// This is quote-enclosed string, make it pretty!
|
||||
r[column] = r[column].substr(1, r.at(column).size() - 2);
|
||||
}
|
||||
|
||||
if (column.get() == "_id") {
|
||||
auto parts = osquery::split(r.at(column), ".", 2);
|
||||
switch (parts.size()) {
|
||||
case 3:
|
||||
r["patch"] = parts[2];
|
||||
case 2:
|
||||
r["minor"] = parts[1];
|
||||
case 1:
|
||||
r["major"] = parts[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {r};
|
||||
}
|
||||
|
||||
QueryData genOSVersion(QueryContext& context) {
|
||||
if (isReadable(kOSRelease)) {
|
||||
return genOSRelease();
|
||||
}
|
||||
|
||||
std::string content;
|
||||
if (!isReadable(kRedhatRelease) || !readFile(kRedhatRelease, content).ok()) {
|
||||
// This is an unknown Linux OS.
|
||||
return {};
|
||||
}
|
||||
|
||||
Row r;
|
||||
// This is an older version of a Redhat-based OS.
|
||||
auto rx = xp::sregex::compile(
|
||||
"(?P<name>[\\w+\\s]+) .* "
|
||||
"(?P<major>[0-9]+)\\.(?P<minor>[0-9]+)\\.?(?P<patch>\\w+)?");
|
||||
xp::smatch matches;
|
||||
for (const auto& line : osquery::split(content, "\n")) {
|
||||
if (xp::regex_search(line, matches, rx)) {
|
||||
@ -67,6 +110,9 @@ QueryData genOSVersion(QueryContext& context) {
|
||||
}
|
||||
}
|
||||
|
||||
r["version"] = content;
|
||||
r["platform_like"] = "rhel";
|
||||
|
||||
// No build name.
|
||||
r["build"] = "";
|
||||
return {r};
|
||||
|
@ -26,21 +26,12 @@ class SystemsTablesTests : public testing::Test {};
|
||||
TEST_F(SystemsTablesTests, test_os_version) {
|
||||
auto results = SQL("select * from os_version");
|
||||
|
||||
// Issue #2564: There is no os_version on Windows.
|
||||
if (!isPlatform(PlatformType::TYPE_WINDOWS)) {
|
||||
EXPECT_EQ(results.rows().size(), 1U);
|
||||
EXPECT_EQ(results.rows().size(), 1U);
|
||||
|
||||
// Make sure major and minor have data (a missing value of -1 is an error).
|
||||
EXPECT_FALSE(results.rows()[0].at("major").empty());
|
||||
|
||||
// Debian does not define a minor.
|
||||
#if !defined(DEBIAN)
|
||||
EXPECT_FALSE(results.rows()[0].at("minor").empty());
|
||||
#endif
|
||||
|
||||
// The OS name should be filled in too.
|
||||
EXPECT_FALSE(results.rows()[0].at("name").empty());
|
||||
}
|
||||
// Make sure major and minor have data (a missing value of -1 is an error).
|
||||
EXPECT_FALSE(results.rows()[0].at("major").empty());
|
||||
// The OS name should be filled in too.
|
||||
EXPECT_FALSE(results.rows()[0].at("name").empty());
|
||||
}
|
||||
|
||||
TEST_F(SystemsTablesTests, test_process_info) {
|
||||
|
@ -2,10 +2,14 @@ table_name("os_version")
|
||||
description("A single row containing the operating system name and version.")
|
||||
schema([
|
||||
Column("name", TEXT, "Distribution or product name"),
|
||||
Column("version", TEXT, "Pretty, suitable for presentation, OS version"),
|
||||
Column("major", INTEGER, "Major release version"),
|
||||
Column("minor", INTEGER, "Minor release version"),
|
||||
Column("patch", INTEGER, "Optional patch release"),
|
||||
Column("build", TEXT, "Optional build-specific or variant string"),
|
||||
Column("platform", TEXT, "OS Platform or ID"),
|
||||
Column("platform_like", TEXT, "Closely related platforms"),
|
||||
Column("codename", TEXT, "OS version codename"),
|
||||
])
|
||||
implementation("system/os_version@genOSVersion")
|
||||
fuzz_paths([
|
||||
|
Loading…
Reference in New Issue
Block a user