From dfd6be8623787cb98c8b8cda0a07a9077aed679f Mon Sep 17 00:00:00 2001 From: robert Date: Tue, 8 Nov 2022 19:29:19 +0000 Subject: [PATCH] enable udev support; if libudev-openbsd is installed, chromium will use its monitoring capabilities so that e.g. fido(4) keys can be plugged in anytime during an authentication process instead of enumerating devices once on startup --- www/chromium/Makefile | 4 +- .../patch-components_storage_monitor_BUILD_gn | 9 + .../patches/patch-device_gamepad_BUILD_gn | 12 + .../patches/patch-services_device_BUILD_gn | 12 + .../patch-services_device_hid_BUILD_gn | 6 +- ...ch-services_device_hid_hid_service_fido_cc | 223 +++++++++--------- ...atch-services_device_public_mojom_BUILD_gn | 12 + .../patch-services_device_serial_BUILD_gn | 21 +- .../patch-services_device_usb_usb_service_cc | 19 +- .../patches/patch-third_party_libusb_BUILD_gn | 8 +- 10 files changed, 199 insertions(+), 127 deletions(-) create mode 100644 www/chromium/patches/patch-device_gamepad_BUILD_gn create mode 100644 www/chromium/patches/patch-services_device_BUILD_gn create mode 100644 www/chromium/patches/patch-services_device_public_mojom_BUILD_gn diff --git a/www/chromium/Makefile b/www/chromium/Makefile index 6fb672404dd..585f1e9569e 100644 --- a/www/chromium/Makefile +++ b/www/chromium/Makefile @@ -9,7 +9,7 @@ COMMENT= Chromium browser V= 107.0.5304.87 DISTNAME= chromium-${V} -REVISION= 1 +REVISION= 2 DISTFILES+= ${CHROMIUM_DISTFILES} \ ${PROFILE_DISTFILES}:0 \ @@ -165,7 +165,7 @@ GN_ARGS= enable_nacl=false \ extra_cppflags=\"-idirafter ${LOCALBASE}/include -idirafter ${X11BASE}/include\" \ fatal_linker_warnings=false \ use_custom_libcxx=false \ - use_udev=false + use_udev=true # notyet GN_ARGS+= use_vaapi=false diff --git a/www/chromium/patches/patch-components_storage_monitor_BUILD_gn b/www/chromium/patches/patch-components_storage_monitor_BUILD_gn index 1635c99608e..40dc87adcaf 100644 --- a/www/chromium/patches/patch-components_storage_monitor_BUILD_gn +++ b/www/chromium/patches/patch-components_storage_monitor_BUILD_gn @@ -1,6 +1,15 @@ Index: components/storage_monitor/BUILD.gn --- components/storage_monitor/BUILD.gn.orig +++ components/storage_monitor/BUILD.gn +@@ -71,7 +71,7 @@ static_library("storage_monitor") { + deps += [ "//services/device/public/mojom" ] + } + } else if (is_linux || is_chromeos_lacros) { +- if (use_udev) { ++ if (use_udev && !is_bsd) { + sources += [ + "mtab_watcher_linux.cc", + "mtab_watcher_linux.h", @@ -175,7 +175,7 @@ source_set("unit_tests") { "storage_monitor_chromeos_unittest.cc", ] diff --git a/www/chromium/patches/patch-device_gamepad_BUILD_gn b/www/chromium/patches/patch-device_gamepad_BUILD_gn new file mode 100644 index 00000000000..db87d32c84b --- /dev/null +++ b/www/chromium/patches/patch-device_gamepad_BUILD_gn @@ -0,0 +1,12 @@ +Index: device/gamepad/BUILD.gn +--- device/gamepad/BUILD.gn.orig ++++ device/gamepad/BUILD.gn +@@ -98,7 +98,7 @@ component("gamepad") { + "hid_writer_linux.cc", + "hid_writer_linux.h", + ] +- if (use_udev) { ++ if (use_udev && !is_bsd) { + sources += [ + "gamepad_device_linux.cc", + "gamepad_device_linux.h", diff --git a/www/chromium/patches/patch-services_device_BUILD_gn b/www/chromium/patches/patch-services_device_BUILD_gn new file mode 100644 index 00000000000..74854137605 --- /dev/null +++ b/www/chromium/patches/patch-services_device_BUILD_gn @@ -0,0 +1,12 @@ +Index: services/device/BUILD.gn +--- services/device/BUILD.gn.orig ++++ services/device/BUILD.gn +@@ -16,7 +16,7 @@ if (is_android) { + } + + is_serial_enabled_platform = +- is_win || ((is_linux || is_chromeos) && use_udev) || is_mac ++ is_win || ((!is_bsd && is_linux || is_chromeos) && use_udev) || is_mac + + source_set("lib") { + # This should be visible only to embedders of the Device Service, and the diff --git a/www/chromium/patches/patch-services_device_hid_BUILD_gn b/www/chromium/patches/patch-services_device_hid_BUILD_gn index d57ea1d190f..aa197b5efcc 100644 --- a/www/chromium/patches/patch-services_device_hid_BUILD_gn +++ b/www/chromium/patches/patch-services_device_hid_BUILD_gn @@ -1,10 +1,11 @@ Index: services/device/hid/BUILD.gn --- services/device/hid/BUILD.gn.orig +++ services/device/hid/BUILD.gn -@@ -35,6 +35,25 @@ source_set("hid") { +@@ -35,7 +35,26 @@ source_set("hid") { "//services/device/public/mojom", ] +- if ((is_linux || is_chromeos) && use_udev) { + if (is_openbsd) { + sources += [ + "hid_connection_fido.cc", @@ -24,6 +25,7 @@ Index: services/device/hid/BUILD.gn + ] + } + - if ((is_linux || is_chromeos) && use_udev) { ++ if ((is_linux || is_chromeos) && !is_bsd && use_udev) { sources += [ "hid_connection_linux.cc", + "hid_connection_linux.h", diff --git a/www/chromium/patches/patch-services_device_hid_hid_service_fido_cc b/www/chromium/patches/patch-services_device_hid_hid_service_fido_cc index 57175d87823..0eb9e8c70e6 100644 --- a/www/chromium/patches/patch-services_device_hid_hid_service_fido_cc +++ b/www/chromium/patches/patch-services_device_hid_hid_service_fido_cc @@ -1,7 +1,7 @@ Index: services/device/hid/hid_service_fido.cc --- services/device/hid/hid_service_fido.cc.orig +++ services/device/hid/hid_service_fido.cc -@@ -0,0 +1,392 @@ +@@ -0,0 +1,399 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. @@ -12,6 +12,7 @@ Index: services/device/hid/hid_service_fido.cc +#include +#include + ++#include +#include + +#include @@ -37,15 +38,10 @@ Index: services/device/hid/hid_service_fido.cc +#include "build/build_config.h" +#include "build/chromeos_buildflags.h" +#include "components/device_event_log/device_event_log.h" ++#include "device/udev_linux/scoped_udev.h" ++#include "device/udev_linux/udev_watcher.h" +#include "services/device/hid/hid_connection_fido.h" + -+// TODO(huangs): Enable for IS_CHROMEOS_LACROS. This will simplify crosapi so -+// that it won't need to pass HidManager around (crbug.com/1109621). -+#if BUILDFLAG(IS_CHROMEOS_ASH) -+#include "base/system/sys_info.h" -+#include "chromeos/dbus/permission_broker/permission_broker_client.h" // nogncheck -+#endif // BUILDFLAG(IS_CHROMEOS_ASH) -+ +namespace device { + +namespace { @@ -148,7 +144,7 @@ Index: services/device/hid/hid_service_fido.cc + base::ScopedFD fd; +}; + -+class HidServiceFido::BlockingTaskRunnerHelper { ++class HidServiceFido::BlockingTaskRunnerHelper : public UdevWatcher::Observer { + public: + BlockingTaskRunnerHelper(base::WeakPtr service) + : service_(std::move(service)), @@ -159,59 +155,22 @@ Index: services/device/hid/hid_service_fido.cc + BlockingTaskRunnerHelper(const BlockingTaskRunnerHelper&) = delete; + BlockingTaskRunnerHelper& operator=(const BlockingTaskRunnerHelper&) = delete; + -+ ~BlockingTaskRunnerHelper() = default; ++ ~BlockingTaskRunnerHelper() override { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ } + + void Start() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + -+ fido_dev_info_t *devlist = NULL; -+ fido_dev_t *dev = NULL; -+ size_t devlist_len = 0, i; -+ const char *path; -+ int r; -+ const int MAX_FIDO_DEVICES = 256; -+ -+ if ((devlist = fido_dev_info_new(MAX_FIDO_DEVICES)) == NULL) { -+ HID_LOG(ERROR) << "fido_dev_info_new failed"; -+ goto out; ++ void *library = dlopen("libudev.so", RTLD_NOW | RTLD_LOCAL); ++ if (library) { ++ dlclose(library); ++ watcher_ = UdevWatcher::StartWatching(this); ++ watcher_->EnumerateExistingDevices(); ++ } else { ++ HID_LOG(ERROR) << "No udev available, failling back to single enumeration"; ++ WalkFidoDevices(nullptr); + } -+ if ((r = fido_dev_info_manifest(devlist, MAX_FIDO_DEVICES, &devlist_len)) != -+ FIDO_OK) { -+ HID_LOG(ERROR) << "fido_dev_info_manifest: " << fido_strerr(r); -+ goto out; -+ } -+ -+ HID_LOG(EVENT) << "fido_dev_info_manifest found " << devlist_len -+ << " device(s)"; -+ -+ for (i = 0; i < devlist_len; i++) { -+ const fido_dev_info_t *di = fido_dev_info_ptr(devlist, i); -+ if (di == NULL) { -+ HID_LOG(ERROR) << "fido_dev_info_ptr " << i << " failed"; -+ continue; -+ } -+ if ((path = fido_dev_info_path(di)) == NULL) { -+ HID_LOG(ERROR) << "fido_dev_info_path " << i << " failed"; -+ continue; -+ } -+ HID_LOG(EVENT) << "trying device " << i << ": " << path; -+ if ((dev = fido_dev_new()) == NULL) { -+ HID_LOG(ERROR) << "fido_dev_new failed"; -+ continue; -+ } -+ if ((r = fido_dev_open(dev, path)) != FIDO_OK) { -+ HID_LOG(ERROR) << "fido_dev_open failed " << path; -+ fido_dev_free(&dev); -+ continue; -+ } -+ OnDeviceAdded(di); -+ fido_dev_close(dev); -+ fido_dev_free(&dev); -+ } -+ -+ out: -+ if (devlist != NULL) -+ fido_dev_info_free(&devlist, MAX_FIDO_DEVICES); + + task_runner_->PostTask( + FROM_HERE, @@ -219,37 +178,122 @@ Index: services/device/hid/hid_service_fido.cc + } + + private: -+ void OnDeviceAdded(const fido_dev_info_t *di) { -+ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -+ base::ScopedBlockingCall scoped_blocking_call( -+ FROM_HERE, base::BlockingType::MAY_BLOCK); ++ void WalkFidoDevices(const char *name) { ++ fido_dev_info_t *devlist = NULL; ++ fido_dev_t *dev = NULL; ++ size_t devlist_len = 0, i; ++ const char *path; ++ int r; ++ const int MAX_FIDO_DEVICES = 256; + ++ if ((devlist = fido_dev_info_new(MAX_FIDO_DEVICES)) == NULL) { ++ HID_LOG(ERROR) << "fido_dev_info_new failed"; ++ goto out; ++ } ++ if ((r = fido_dev_info_manifest(devlist, MAX_FIDO_DEVICES, &devlist_len)) != ++ FIDO_OK) { ++ HID_LOG(ERROR) << "fido_dev_info_manifest: " << fido_strerr(r); ++ goto out; ++ } ++ ++ HID_LOG(EVENT) << "fido_dev_info_manifest found " << devlist_len ++ << " device(s)"; ++ ++ for (i = 0; i < devlist_len; i++) { ++ const fido_dev_info_t *di = fido_dev_info_ptr(devlist, i); ++ ++ if (di == NULL) { ++ HID_LOG(ERROR) << "fido_dev_info_ptr " << i << " failed"; ++ continue; ++ } ++ ++ if ((path = fido_dev_info_path(di)) == NULL) { ++ HID_LOG(ERROR) << "fido_dev_info_path " << i << " failed"; ++ continue; ++ } ++ ++ if (name != nullptr && !strcmp(path, name)) { ++ HID_LOG(EVENT) << "hotplug device " << i << ": " << path; ++ OnFidoDeviceAdded(di); ++ break; ++ } ++ ++ HID_LOG(EVENT) << "trying device " << i << ": " << path; ++ if ((dev = fido_dev_new()) == NULL) { ++ HID_LOG(ERROR) << "fido_dev_new failed"; ++ continue; ++ } ++ ++ if ((r = fido_dev_open(dev, path)) != FIDO_OK) { ++ HID_LOG(ERROR) << "fido_dev_open failed " << path; ++ fido_dev_free(&dev); ++ continue; ++ } ++ ++ fido_dev_close(dev); ++ fido_dev_free(&dev); ++ ++ OnFidoDeviceAdded(di); ++ } ++ out: ++ if (devlist != NULL) ++ fido_dev_info_free(&devlist, MAX_FIDO_DEVICES); ++ } ++ ++ void OnFidoDeviceAdded(const fido_dev_info_t *di) { + auto null_as_empty = [](const char *r) -> std::string { + return (r != nullptr) ? r : ""; + }; + std::string device_node(null_as_empty(fido_dev_info_path(di))); + std::vector report_descriptor( + kU2fReportDesc, kU2fReportDesc + sizeof(kU2fReportDesc)); -+ scoped_refptr device_info(new HidDeviceInfo( -+ device_node, /*physical_device_id=*/"", fido_dev_info_vendor(di), ++ ++ auto device_info = base::MakeRefCounted( ++ device_node, /*physical_device_id*/"", fido_dev_info_vendor(di), + fido_dev_info_product(di), null_as_empty(fido_dev_info_product_string(di)), + null_as_empty(fido_dev_info_manufacturer_string(di)), -+ device::mojom::HidBusType::kHIDBusTypeUSB, report_descriptor, -+ device_node)); -+ -+ task_runner_->PostTask(FROM_HERE, base::BindOnce(&HidServiceFido::AddDevice, -+ service_, device_info)); ++ device::mojom::HidBusType::kHIDBusTypeUSB, report_descriptor, ++ device_node); ++ ++ task_runner_->PostTask( ++ FROM_HERE, ++ base::BindOnce(&HidServiceFido::AddDevice, service_, device_info)); + } + -+ void OnDeviceRemoved(std::string device_node) { ++ // UdevWatcher::Observer ++ void OnDeviceAdded(ScopedUdevDevicePtr device) override { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::ScopedBlockingCall scoped_blocking_call( + FROM_HERE, base::BlockingType::MAY_BLOCK); -+ task_runner_->PostTask(FROM_HERE, base::BindOnce(&HidServiceFido::RemoveDevice, -+ service_, device_node)); ++ ++ const char* subsystem = udev_device_get_subsystem(device.get()); ++ if (!subsystem || strcmp(subsystem, "fido") != 0) ++ return; ++ ++ const char* device_path = udev_device_get_syspath(device.get()); ++ if (!device_path) ++ return; ++ ++ WalkFidoDevices(device_path); + } + ++ void OnDeviceRemoved(ScopedUdevDevicePtr device) override { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ base::ScopedBlockingCall scoped_blocking_call( ++ FROM_HERE, base::BlockingType::MAY_BLOCK); ++ ++ const char* device_path = udev_device_get_syspath(device.get()); ++ if (device_path) { ++ task_runner_->PostTask( ++ FROM_HERE, base::BindOnce(&HidServiceFido::RemoveDevice, service_, ++ std::string(device_path))); ++ } ++ } ++ ++ void OnDeviceChanged(ScopedUdevDevicePtr) override {} ++ + SEQUENCE_CHECKER(sequence_checker_); ++ std::unique_ptr watcher_; + + // This weak pointer is only valid when checked on this task runner. + base::WeakPtr service_; @@ -288,19 +332,6 @@ Index: services/device/hid/hid_service_fido.cc + } + scoped_refptr device_info = map_entry->second; + -+// TODO(huangs): Enable for IS_CHROMEOS_LACROS for crbug.com/1223456. -+#if BUILDFLAG(IS_CHROMEOS_ASH) -+ auto split_callback = base::SplitOnceCallback(std::move(callback)); -+ chromeos::PermissionBrokerClient::Get()->OpenPath( -+ device_info->device_node(), -+ base::BindOnce(&HidServiceFido::OnPathOpenComplete, -+ std::make_unique( -+ device_info, allow_protected_reports, -+ allow_fido_reports, std::move(split_callback.first))), -+ base::BindOnce(&HidServiceFido::OnPathOpenError, -+ device_info->device_node(), -+ std::move(split_callback.second))); -+#else + auto params = + std::make_unique(device_info, allow_protected_reports, + allow_fido_reports, std::move(callback)); @@ -309,30 +340,8 @@ Index: services/device/hid/hid_service_fido.cc + blocking_task_runner->PostTask( + FROM_HERE, base::BindOnce(&HidServiceFido::OpenOnBlockingThread, + std::move(params))); -+#endif // BUILDFLAG(IS_CHROMEOS_ASH) +} + -+#if BUILDFLAG(IS_CHROMEOS_ASH) -+ -+// static -+void HidServiceFido::OnPathOpenComplete(std::unique_ptr params, -+ base::ScopedFD fd) { -+ params->fd = std::move(fd); -+ FinishOpen(std::move(params)); -+} -+ -+// static -+void HidServiceFido::OnPathOpenError(const std::string& device_path, -+ ConnectCallback callback, -+ const std::string& error_name, -+ const std::string& error_message) { -+ HID_LOG(EVENT) << "Permission broker failed to open '" << device_path -+ << "': " << error_name << ": " << error_message; -+ std::move(callback).Run(nullptr); -+} -+ -+#else -+ +// static +void HidServiceFido::OpenOnBlockingThread( + std::unique_ptr params) { @@ -374,8 +383,6 @@ Index: services/device/hid/hid_service_fido.cc + std::move(params))); +} + -+#endif // BUILDFLAG(IS_CHROMEOS_ASH) -+ +// static +void HidServiceFido::FinishOpen(std::unique_ptr params) { + DCHECK(params->fd.is_valid()); diff --git a/www/chromium/patches/patch-services_device_public_mojom_BUILD_gn b/www/chromium/patches/patch-services_device_public_mojom_BUILD_gn new file mode 100644 index 00000000000..b058da21020 --- /dev/null +++ b/www/chromium/patches/patch-services_device_public_mojom_BUILD_gn @@ -0,0 +1,12 @@ +Index: services/device/public/mojom/BUILD.gn +--- services/device/public/mojom/BUILD.gn.orig ++++ services/device/public/mojom/BUILD.gn +@@ -91,7 +91,7 @@ mojom("device_service") { + disable_variants = true + + enabled_features = [] +- if ((is_linux || is_chromeos) && use_udev) { ++ if ((is_linux || is_chromeos) && !is_bsd && use_udev) { + enabled_features += [ "enable_input_device_manager" ] + } + diff --git a/www/chromium/patches/patch-services_device_serial_BUILD_gn b/www/chromium/patches/patch-services_device_serial_BUILD_gn index 945cbeff9d9..307fe9e4f0f 100644 --- a/www/chromium/patches/patch-services_device_serial_BUILD_gn +++ b/www/chromium/patches/patch-services_device_serial_BUILD_gn @@ -1,17 +1,12 @@ Index: services/device/serial/BUILD.gn --- services/device/serial/BUILD.gn.orig +++ services/device/serial/BUILD.gn -@@ -83,6 +83,13 @@ if (is_win || ((is_linux || is_chromeos) && use_udev) - ] - } +@@ -5,7 +5,7 @@ + import("//build/config/chromeos/ui_mode.gni") + import("//build/config/features.gni") -+ if (is_bsd) { -+ sources -= [ -+ "serial_device_enumerator_linux.cc", -+ "serial_device_enumerator_linux.h" -+ ] -+ } -+ - if (use_udev) { - deps += [ "//device/udev_linux" ] - } +-if (is_win || ((is_linux || is_chromeos) && use_udev) || is_mac) { ++if (is_win || ((!is_bsd && is_linux || is_chromeos) && use_udev) || is_mac) { + config("platform_support") { + visibility = [ ":serial" ] + if (is_win) { diff --git a/www/chromium/patches/patch-services_device_usb_usb_service_cc b/www/chromium/patches/patch-services_device_usb_usb_service_cc index 5053bb63124..bb6daa7447e 100644 --- a/www/chromium/patches/patch-services_device_usb_usb_service_cc +++ b/www/chromium/patches/patch-services_device_usb_usb_service_cc @@ -1,7 +1,15 @@ Index: services/device/usb/usb_service.cc --- services/device/usb/usb_service.cc.orig +++ services/device/usb/usb_service.cc -@@ -29,6 +29,10 @@ +@@ -22,13 +22,17 @@ + + #if BUILDFLAG(IS_ANDROID) + #include "services/device/usb/usb_service_android.h" +-#elif defined(USE_UDEV) ++#elif defined(USE_UDEV) && !BUILDFLAG(IS_BSD) + #include "services/device/usb/usb_service_linux.h" + #elif BUILDFLAG(IS_MAC) + #include "services/device/usb/usb_service_impl.h" #include "services/device/usb/usb_service_mac.h" #elif BUILDFLAG(IS_WIN) #include "services/device/usb/usb_service_win.h" @@ -12,6 +20,15 @@ Index: services/device/usb/usb_service.cc #endif namespace device { +@@ -51,7 +55,7 @@ constexpr base::TaskTraits UsbService::kBlockingTaskTr + std::unique_ptr UsbService::Create() { + #if BUILDFLAG(IS_ANDROID) + return base::WrapUnique(new UsbServiceAndroid()); +-#elif defined(USE_UDEV) ++#elif defined(USE_UDEV) && !BUILDFLAG(IS_BSD) + return base::WrapUnique(new UsbServiceLinux()); + #elif BUILDFLAG(IS_WIN) + return base::WrapUnique(new UsbServiceWin()); @@ -60,6 +64,8 @@ std::unique_ptr UsbService::Create() { return base::WrapUnique(new UsbServiceMac()); else diff --git a/www/chromium/patches/patch-third_party_libusb_BUILD_gn b/www/chromium/patches/patch-third_party_libusb_BUILD_gn index 47e38527a6b..d2c1ce46d6d 100644 --- a/www/chromium/patches/patch-third_party_libusb_BUILD_gn +++ b/www/chromium/patches/patch-third_party_libusb_BUILD_gn @@ -19,7 +19,7 @@ Index: third_party/libusb/BUILD.gn sources += [ "src/libusb/os/linux_usbfs.c", "src/libusb/os/linux_usbfs.h", -@@ -127,6 +127,16 @@ static_library("libusb") { +@@ -127,11 +127,21 @@ static_library("libusb") { ] } @@ -36,6 +36,12 @@ Index: third_party/libusb/BUILD.gn if (is_chromeos_ash) { defines += [ "USBI_TIMERFD_AVAILABLE" ] } + +- if (use_udev) { ++ if (use_udev && !is_bsd) { + sources += [ "src/libusb/os/linux_udev.cc" ] + defines += [ + "HAVE_LIBUDEV=1", @@ -140,7 +150,7 @@ static_library("libusb") { deps += [ "//build/linux/libudev" ] }