Skip to content

Commit 080833e

Browse files
authored
Fix hardware model and version on Lenovo (osquery#8534)
From Fleet: fleetdm/fleet#21648 This PR fixes an issue where Lenovo laptops report the hardware model and version incorrectly in the BIOS tables, resulting in incorrect values in the `hardware_model` and `hardware_version` columns of the `system_info` table. This issue affects both Windows and Linux. See fleetdm/fleet#21648 (comment) for examples of the undesirable output. The fixes in this PR are: * For Linux, swap the hardware_model and hardware_version values. The reported version is something like `ThinkPad L15 Gen 3` which is consistent with the kind of value typically reported as `hardware_model` from other vendors. The reported version is something like 21C8S3EA00 which appears to be a [product SKU](https://psref.lenovo.com/Detail/ThinkPad_L15_Gen_3_AMD?M=21C8S3EB00), which can serve as the "version" for this model. * For Windows, retrieve the model name from the Win32_ComputerSystemProduct WMI class, and move the reported `hardware_model` into `hardware_version` as above.
1 parent b875bf1 commit 080833e

File tree

2 files changed

+32
-0
lines changed

2 files changed

+32
-0
lines changed

osquery/tables/system/linux/system_info.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,20 @@ QueryData genSystemInfo(QueryContext& context) {
121121
r["hardware_model"] = dmiString(textAddrs, address[0x05], maxlen);
122122
r["hardware_version"] = dmiString(textAddrs, address[0x06], maxlen);
123123
r["hardware_serial"] = dmiString(textAddrs, address[0x07], maxlen);
124+
125+
// Check if this is a Lenovo model.
126+
std::string lcVendor = r["hardware_vendor"];
127+
std::transform(
128+
lcVendor.begin(), lcVendor.end(), lcVendor.begin(), ::tolower);
129+
// Lenovo puts the model in the "Version" string and the product SKU
130+
// in the "Model" string, so we'll switch them to be consistent with
131+
// other vendors.
132+
if (lcVendor == "lenovo") {
133+
std::string version = r["hardware_model"];
134+
r["hardware_model"] = r["hardware_version"];
135+
r["hardware_version"] = version;
136+
}
137+
124138
return;
125139
}
126140

osquery/tables/system/windows/system_info.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,24 @@ QueryData genSystemInfo(QueryContext& context) {
5656
r["cpu_physical_cores"] = INTEGER(numProcs);
5757
wmiResults[0].GetString("Manufacturer", r["hardware_vendor"]);
5858
wmiResults[0].GetString("Model", r["hardware_model"]);
59+
60+
// For Lenovo models, the hardware_model property is not set propertly.
61+
// Instead we can get the required info from the Win32_ComputerSystemProduct
62+
// table.
63+
std::string lcModel = r["hardware_vendor"];
64+
std::transform(lcModel.begin(), lcModel.end(), lcModel.begin(), ::tolower);
65+
if (lcModel == "lenovo") {
66+
std::string version = r["hardware_model"];
67+
const auto wmiSystemProductReq = WmiRequest::CreateWmiRequest(
68+
"select * from Win32_ComputerSystemProduct");
69+
if (wmiSystemProductReq.isValue() &&
70+
!wmiSystemProductReq->results().empty()) {
71+
const std::vector<WmiResultItem>& wmiProductResults =
72+
wmiSystemProductReq->results();
73+
wmiProductResults[0].GetString("Version", r["hardware_model"]);
74+
r["hardware_version"] = version;
75+
}
76+
}
5977
} else {
6078
r["cpu_logical_cores"] = "-1";
6179
r["cpu_sockets"] = "-1";

0 commit comments

Comments
 (0)