/* * 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 #include #include "osquery/events/linux/udev.h" namespace osquery { namespace tables { const std::string kPCIKeySlot = "PCI_SLOT_NAME"; const std::string kPCIKeyClass = "ID_PCI_CLASS_FROM_DATABASE"; const std::string kPCIKeyVendor = "ID_VENDOR_FROM_DATABASE"; const std::string kPCIKeyModel = "ID_MODEL_FROM_DATABASE"; const std::string kPCIKeyID = "PCI_ID"; const std::string kPCIKeyDriver = "DRIVER"; QueryData genPCIDevices(QueryContext& context) { QueryData results; auto delUdev = [](udev* u) { udev_unref(u); }; std::unique_ptr udev_handle(udev_new(), delUdev); if (udev_handle.get() == nullptr) { VLOG(1) << "Could not get udev handle"; return results; } // Perform enumeration/search. auto delUdevEnum = [](udev_enumerate* e) { udev_enumerate_unref(e); }; std::unique_ptr enumerate( udev_enumerate_new(udev_handle.get()), delUdevEnum); if (enumerate.get() == nullptr) { VLOG(1) << "Could not get udev_enumerate handle"; return results; } udev_enumerate_add_match_subsystem(enumerate.get(), "pci"); udev_enumerate_scan_devices(enumerate.get()); // Get list entries and iterate over entries. struct udev_list_entry *device_entries, *entry; device_entries = udev_enumerate_get_list_entry(enumerate.get()); auto delUdevDevice = [](udev_device* d) { udev_device_unref(d); }; udev_list_entry_foreach(entry, device_entries) { const char* path = udev_list_entry_get_name(entry); std::unique_ptr device( udev_device_new_from_syspath(udev_handle.get(), path), delUdevDevice); if (device.get() == nullptr) { VLOG(1) << "Could not get device"; return results; } Row r; r["pci_slot"] = UdevEventPublisher::getValue(device.get(), kPCIKeySlot); r["pci_class"] = UdevEventPublisher::getValue(device.get(), kPCIKeyClass); r["driver"] = UdevEventPublisher::getValue(device.get(), kPCIKeyDriver); r["vendor"] = UdevEventPublisher::getValue(device.get(), kPCIKeyVendor); r["model"] = UdevEventPublisher::getValue(device.get(), kPCIKeyModel); // VENDOR:MODEL ID is in the form of HHHH:HHHH. std::vector ids; auto device_id = UdevEventPublisher::getValue(device.get(), kPCIKeyID); boost::split(ids, device_id, boost::is_any_of(":")); if (ids.size() == 2) { r["vendor_id"] = ids[0]; r["model_id"] = ids[1]; } // Set invalid vendor/model IDs to 0. if (r["vendor_id"].size() == 0) { r["vendor_id"] = "0"; } if (r["model_id"].size() == 0) { r["model_id"] = "0"; } results.push_back(r); } return results; } } }