1616namespace osquery {
1717namespace tables {
1818
19+ // / A set of common IOKit properties used to store firmware versions.
20+ const std::set<std::string> kFirmwareProperties {
21+ " Firmware Revision" , " IOFirmwareVersion" , " FirmwareVersionString" ,
22+ };
23+
24+ /* *
25+ * @brief A callback for each entry in the IOKit registry.
26+ *
27+ * An enumerator should fill in the table's results.
28+ */
29+ using IOKitEnumerator = std::function<void (const io_service_t & device,
30+ const io_service_t & parent,
31+ const io_name_t plane,
32+ int depth,
33+ QueryData& results)>;
34+
35+ static inline void genFirmware (const void * key, const void * value, void * r) {
36+ auto * r2 = (Row*)r;
37+ if (key == nullptr || value == nullptr || r2->count (" version" ) != 0 ) {
38+ return ;
39+ }
40+
41+ auto prop = stringFromCFString ((CFStringRef)key);
42+ if (kFirmwareProperties .find (prop) != kFirmwareProperties .end ()) {
43+ (*r2)[" version" ] = prop;
44+ }
45+ }
46+
47+ void genIOKitFirmware (const io_service_t & device,
48+ const io_service_t & parent,
49+ const io_name_t plane,
50+ int depth,
51+ QueryData& results) {
52+ Row r;
53+ io_name_t name;
54+ auto kr = IORegistryEntryGetName (device, name);
55+ if (kr == KERN_SUCCESS) {
56+ r[" device" ] = std::string (name);
57+ }
58+
59+ CFMutableDictionaryRef details;
60+ IORegistryEntryCreateCFProperties (
61+ device, &details, kCFAllocatorDefault , kNilOptions );
62+ CFDictionaryApplyFunction (details, &genFirmware, &r);
63+ if (r.count (" version" ) != 0 ) {
64+ // If the version is filled in from the dictionary walk callback then
65+ // the value of the property name contains the firmware version.
66+ r[" version" ] = getIOKitProperty (details, r[" version" ]);
67+ r[" type" ] = getIOKitProperty (details, " IOProviderClass" );
68+ results.push_back (r);
69+ }
70+
71+ CFRelease (details);
72+ }
73+
1974void genIOKitDevice (const io_service_t & device,
2075 const io_service_t & parent,
2176 const io_name_t plane,
@@ -82,7 +137,8 @@ void genIOKitDevice(const io_service_t& device,
82137 results.push_back (r);
83138}
84139
85- void genIOKitDeviceChildren (const io_registry_entry_t & service,
140+ void genIOKitDeviceChildren (IOKitEnumerator enumerator,
141+ const io_registry_entry_t & service,
86142 const io_name_t plane,
87143 int depth,
88144 QueryData& results) {
@@ -95,38 +151,47 @@ void genIOKitDeviceChildren(const io_registry_entry_t& service,
95151 io_service_t device;
96152 while ((device = IOIteratorNext (it))) {
97153 // Use this entry as the parent, and generate a result row.
98- genIOKitDevice (device, service, plane, depth, results);
99- genIOKitDeviceChildren (device, plane, depth + 1 , results);
154+ enumerator (device, service, plane, depth, results);
155+ genIOKitDeviceChildren (enumerator, device, plane, depth + 1 , results);
100156 IOObjectRelease (device);
101157 }
102158
103159 IOObjectRelease (it);
104160}
105161
162+ QueryData genDeviceFirmware (QueryContext& context) {
163+ QueryData qd;
164+
165+ // Start with the services root node.
166+ auto service = IORegistryGetRootEntry (kIOMasterPortDefault );
167+ genIOKitDeviceChildren (&genIOKitFirmware, service, kIOServicePlane , 0 , qd);
168+ IOObjectRelease (service);
169+
170+ return qd;
171+ }
172+
106173QueryData genIOKitDeviceTree (QueryContext& context) {
107- QueryData results ;
174+ QueryData qd ;
108175
109176 // Get the IO registry root node.
110177 auto service = IORegistryGetRootEntry (kIOMasterPortDefault );
111-
112178 // Begin recursing along the IODeviceTree "plane".
113- genIOKitDeviceChildren (service, kIODeviceTreePlane , 0 , results);
114-
179+ genIOKitDeviceChildren (&genIOKitDevice, service, kIODeviceTreePlane , 0 , qd);
115180 IOObjectRelease (service);
116- return results;
181+
182+ return qd;
117183}
118184
119185QueryData genIOKitRegistry (QueryContext& context) {
120- QueryData results ;
186+ QueryData qd ;
121187
122188 // Get the IO registry root node.
123189 auto service = IORegistryGetRootEntry (kIOMasterPortDefault );
124-
125190 // Begin recursing along the IODeviceTree "plane".
126- genIOKitDeviceChildren (service, kIOServicePlane , 0 , results);
127-
191+ genIOKitDeviceChildren (&genIOKitDevice, service, kIOServicePlane , 0 , qd);
128192 IOObjectRelease (service);
129- return results;
193+
194+ return qd;
130195}
131196}
132197}
0 commit comments