@@ -340,6 +340,25 @@ namespace usbguard
340
340
if (enumeration_count < 0 ) {
341
341
throw Exception (" UEventDeviceManager" , " present devices" , " failed to enumerate" );
342
342
}
343
+
344
+ // We keep track of the uevents received during the scanning and process
345
+ // them ad-hoc at the end. This is to avoid any inconsistent state while
346
+ // enumerating the devices.
347
+ _enumeration = false ;
348
+ processBacklog ();
349
+ }
350
+
351
+ void UEventDeviceManager::processBacklog ()
352
+ {
353
+ USBGUARD_LOG (Debug) << " Processing backlog: _backlog.size() = " << _backlog.size ();
354
+ try {
355
+ for (auto & it : _backlog) {
356
+ ueventProcessUEvent (std::move (it));
357
+ }
358
+ }
359
+ catch (...) {
360
+ USBGUARD_LOG (Warning) << " ueventProcessBacklog: error processing uevent data" ;
361
+ }
343
362
}
344
363
345
364
void UEventDeviceManager::scan (const std::string& devpath)
@@ -565,16 +584,16 @@ namespace usbguard
565
584
* Try to parse uevent from the buffer and process it.
566
585
*/
567
586
try {
568
- const UEvent uevent = UEvent::fromString (buffer, /* attributes_only=*/ false , /* trace=*/ false );
569
- ueventProcessUEvent (uevent);
587
+ UEvent uevent = UEvent::fromString (buffer, /* attributes_only=*/ false , /* trace=*/ false );
588
+ ueventProcessUEvent (std::move ( uevent) );
570
589
}
571
590
catch (...) {
572
591
USBGUARD_LOG (Warning) << " ueventProcessRead: received invalid uevent data" ;
573
592
USBGUARD_LOG (Debug) << " ueventProcessRead: uevent_data=" << base64Encode (buffer);
574
593
}
575
594
}
576
595
577
- void UEventDeviceManager::ueventProcessUEvent (const UEvent& uevent)
596
+ void UEventDeviceManager::ueventProcessUEvent (UEvent uevent)
578
597
{
579
598
const std::string subsystem = uevent.getAttribute (" SUBSYSTEM" );
580
599
const std::string devtype = uevent.getAttribute (" DEVTYPE" );
@@ -594,20 +613,23 @@ namespace usbguard
594
613
}
595
614
596
615
const std::string sysfs_devpath = uevent.getAttribute (" DEVPATH" );
597
- ueventProcessAction (action, sysfs_devpath);
616
+
617
+ if (_enumeration) {
618
+ _backlog.emplace_back (std::move (uevent));
619
+ }
620
+ else {
621
+ ueventProcessAction (action, sysfs_devpath);
622
+ }
598
623
}
599
624
600
625
void UEventDeviceManager::ueventProcessAction (const std::string& action, const std::string& sysfs_devpath)
601
626
{
602
- bool enumeration_notify = false ;
603
627
604
628
try {
605
- std::unique_lock<std::mutex> lock (_enumeration_mutex);
606
629
uint32_t id = 0 ;
607
630
const bool known_path = knownSysfsPath (sysfs_devpath, &id);
608
631
609
632
if (action == " add" || action == " change" ) {
610
- lock.unlock ();
611
633
612
634
if (known_path && id > 0 ) {
613
635
processDevicePresence (id);
@@ -637,19 +659,10 @@ namespace usbguard
637
659
USBGUARD_LOG (Debug) << " Enumeration notify: sysfs_devpath=" << sysfs_devpath
638
660
<< " _enumeration=" << _enumeration
639
661
<< " known_path=" << known_path;
640
-
641
- if (known_path) {
642
- enumeration_notify = true ;
643
- }
644
662
}
645
663
}
646
664
else if (action == " remove" ) {
647
- lock.unlock ();
648
665
processDeviceRemoval (sysfs_devpath);
649
-
650
- if (known_path) {
651
- enumeration_notify = true ;
652
- }
653
666
}
654
667
else if (action == " bind" || action == " unbind" ) {
655
668
USBGUARD_LOG (Debug) << action << " =" << sysfs_devpath;
@@ -669,10 +682,6 @@ namespace usbguard
669
682
DeviceException (" unknown exception" );
670
683
}
671
684
672
- if (_enumeration && enumeration_notify) {
673
- _enumeration_complete.notify_one ();
674
- USBGUARD_LOG (Debug) << " Notified enumeration routine after sysfs_path=" << sysfs_devpath;
675
- }
676
685
}
677
686
678
687
bool UEventDeviceManager::ueventEnumerateComparePath (const std::pair<std::string, std::string>& a,
@@ -788,19 +797,8 @@ namespace usbguard
788
797
SysFSDevice device (sysfs_relative_path);
789
798
790
799
if (device.getUEvent ().getAttribute (" DEVTYPE" ) == " usb_device" ) {
791
- std::unique_lock<std::mutex> lock (_enumeration_mutex);
792
800
learnSysfsPath (sysfs_relative_path);
793
- device.setAttribute (" uevent" , " add" );
794
-
795
- if (!_enumeration_complete.wait_for (lock, std::chrono::seconds (2 ),
796
- [this , sysfs_relative_path]() {
797
- uint32_t id = 0 ;
798
- const bool known = knownSysfsPath (sysfs_relative_path, &id);
799
- USBGUARD_LOG (Debug) << " cv: known=" << known << " id=" << id;
800
- return id != 0 ;
801
- })) {
802
- throw Exception (" UEventDeviceManager" , sysfs_absolute_path, " enumeration timeout" );
803
- }
801
+ ueventProcessAction (" add" , sysfs_relative_path);
804
802
return 1 ;
805
803
}
806
804
else {
0 commit comments