diff --git a/www/chromium/Makefile b/www/chromium/Makefile index 520947c339a6..c6bae9d7775a 100644 --- a/www/chromium/Makefile +++ b/www/chromium/Makefile @@ -1,354 +1,354 @@ PORTNAME= chromium -PORTVERSION= 107.0.5304.68 +PORTVERSION= 107.0.5304.87 CATEGORIES= www wayland MASTER_SITES= https://commondatastorage.googleapis.com/chromium-browser-official/ \ https://nerd.hu/distfiles/:external DISTFILES= ${DISTNAME}${EXTRACT_SUFX} \ chrome-linux-${PORTVERSION}-llvm13.profdata${EXTRACT_SUFX}:external MAINTAINER= chromium@FreeBSD.org COMMENT= Google web browser based on WebKit WWW= https://www.chromium.org/Home LICENSE= BSD3CLAUSE LGPL21 MPL11 LICENSE_COMB= multi ONLY_FOR_ARCHS= aarch64 amd64 i386 BUILD_DEPENDS= bash:shells/bash \ ${PYTHON_PKGNAMEPREFIX}Jinja2>0:devel/py-Jinja2@${PY_FLAVOR} \ ${PYTHON_PKGNAMEPREFIX}ply>0:devel/py-ply@${PY_FLAVOR} \ gperf:devel/gperf \ flock:sysutils/flock \ node:www/node \ xcb-proto>0:x11/xcb-proto \ ${LOCALBASE}/include/linux/videodev2.h:multimedia/v4l_compat \ ${LOCALBASE}/share/usbids/usb.ids:misc/usbids \ ${PYTHON_PKGNAMEPREFIX}html5lib>0:www/py-html5lib@${PY_FLAVOR} \ ${LOCALBASE}/include/va/va.h:multimedia/libva \ ${LOCALBASE}/libdata/pkgconfig/dri.pc:graphics/mesa-dri \ ${LOCALBASE}/libdata/pkgconfig/Qt5Core.pc:devel/qt5-core \ ${LOCALBASE}/libdata/pkgconfig/Qt5Widgets.pc:x11-toolkits/qt5-widgets LIB_DEPENDS= libatk-bridge-2.0.so:accessibility/at-spi2-atk \ libatspi.so:accessibility/at-spi2-core \ libspeechd.so:accessibility/speech-dispatcher \ libsnappy.so:archivers/snappy \ libFLAC.so:audio/flac \ libopus.so:audio/opus \ libspeex.so:audio/speex \ libdbus-1.so:devel/dbus \ libdbus-glib-1.so:devel/dbus-glib \ libevent.so:devel/libevent \ libicuuc.so:devel/icu \ libjsoncpp.so:devel/jsoncpp \ libpci.so:devel/libpci \ libnspr4.so:devel/nspr \ libre2.so:devel/re2 \ libcairo.so:graphics/cairo \ libdrm.so:graphics/libdrm \ libexif.so:graphics/libexif \ libpng.so:graphics/png \ libwebp.so:graphics/webp \ libopenh264.so:multimedia/openh264 \ libfreetype.so:print/freetype2 \ libharfbuzz.so:print/harfbuzz \ libharfbuzz-icu.so:print/harfbuzz-icu \ libgcrypt.so:security/libgcrypt \ libsecret-1.so:security/libsecret \ libnss3.so:security/nss \ libexpat.so:textproc/expat2 \ libfontconfig.so:x11-fonts/fontconfig \ libwayland-client.so:graphics/wayland \ libxkbcommon.so:x11/libxkbcommon \ libxshmfence.so:x11/libxshmfence RUN_DEPENDS= xdg-open:devel/xdg-utils \ noto-basic>0:x11-fonts/noto-basic USES= bison compiler:c++17-lang cpe desktop-file-utils gl gnome iconv jpeg \ localbase:ldflags ninja perl5 pkgconfig python:3.7+,build qt:5 shebangfix \ tar:xz xorg CPE_VENDOR= google CPE_PRODUCT= chrome USE_GL= gbm gl USE_GNOME= atk dconf gdkpixbuf2 glib20 gtk30 libxml2 libxslt USE_LDCONFIG= ${DATADIR} USE_PERL5= build USE_XORG= x11 xcb xcomposite xcursor xext xdamage xfixes xi \ xorgproto xrandr xrender xscrnsaver xtst USE_QT= buildtools:build SHEBANG_FILES= chrome/tools/build/linux/chrome-wrapper buildtools/linux64/clang-format MAKE_ARGS= -C out/${BUILDTYPE} ALL_TARGET= chrome BINARY_ALIAS= python3=${PYTHON_CMD} # TODO bz@ : install libwidevinecdm.so (see third_party/widevine/cdm/BUILD.gn) # # Run "./out/${BUILDTYPE}/gn args out/${BUILDTYPE} --list" for all variables. # Some parts don't have use_system_* flag, and can be turned on/off by using # replace_gn_files.py script, some parts just turned on/off for target host # OS "target_os == is_bsd", like libusb, libpci. GN_ARGS+= clang_use_chrome_plugins=false \ enable_hangout_services_extension=true \ enable_js_type_check=false \ enable_nacl=false \ enable_remoting=false \ fatal_linker_warnings=false \ icu_use_data_file=false \ is_clang=true \ optimize_webui=true \ toolkit_views=true \ treat_warnings_as_errors=false \ use_allocator="none" \ use_allocator_shim=false \ use_aura=true \ use_custom_libcxx=false \ use_gnome_keyring=false \ use_lld=true \ use_sysroot=false \ use_system_freetype=false \ use_system_harfbuzz=true \ use_system_libjpeg=true \ use_system_libwayland=true \ use_system_wayland_scanner=true \ use_system_libwayland_server=true \ use_udev=false \ extra_cxxflags="${CXXFLAGS}" \ extra_ldflags="${LDFLAGS}" # TODO: investigate building with these options: # use_system_minigbm GN_BOOTSTRAP_FLAGS= --no-clean --no-rebuild --skip-generate-buildfiles # FreeBSD Chromium Api Key # Set up Google API keys, see http://www.chromium.org/developers/how-tos/api-keys . # Note: these are for FreeBSD use ONLY. For your own distribution, # please get your own set of keys. GN_ARGS+= google_api_key="AIzaSyBsp9n41JLW8jCokwn7vhoaMejDFRd1mp8" SUB_FILES= chromium-browser.desktop chrome SUB_LIST+= COMMENT="${COMMENT}" OPTIONS_DEFINE= CODECS CUPS DEBUG DRIVER KERBEROS LTO TEST OPTIONS_DEFAULT= CODECS CUPS DRIVER KERBEROS SNDIO OPTIONS_EXCLUDE_aarch64=LTO OPTIONS_GROUP= AUDIO OPTIONS_GROUP_AUDIO= ALSA PULSEAUDIO SNDIO OPTIONS_RADIO= KERBEROS OPTIONS_RADIO_KERBEROS= HEIMDAL HEIMDAL_BASE MIT OPTIONS_SUB= yes CODECS_DESC= Compile and enable patented codecs like H.264 DRIVER_DESC= Install chromedriver HEIMDAL_BASE_DESC= Heimdal Kerberos (base) HEIMDAL_DESC= Heimdal Kerberos (security/heimdal) MIT_DESC= MIT Kerberos (security/krb5) ALSA_LIB_DEPENDS= libasound.so:audio/alsa-lib ALSA_RUN_DEPENDS= ${LOCALBASE}/lib/alsa-lib/libasound_module_pcm_oss.so:audio/alsa-plugins \ alsa-lib>=1.1.1_1:audio/alsa-lib ALSA_VARS= GN_ARGS+=use_alsa=true ALSA_VARS_OFF= GN_ARGS+=use_alsa=false CODECS_VARS= GN_ARGS+=ffmpeg_branding="Chrome" \ GN_ARGS+=proprietary_codecs=true CODECS_VARS_OFF= GN_ARGS+=ffmpeg_branding="Chromium" \ GN_ARGS+=proprietary_codecs=false CUPS_LIB_DEPENDS= libcups.so:print/cups CUPS_VARS= GN_ARGS+=use_cups=true CUPS_VARS_OFF= GN_ARGS+=use_cups=false DEBUG_BUILD_DEPENDS= esbuild:devel/esbuild DEBUG_VARS= BUILDTYPE=Debug \ GN_ARGS+=is_debug=true \ GN_ARGS+=is_component_build=false \ GN_ARGS+=symbol_level=1 \ GN_BOOTSTRAP_FLAGS+=--debug \ WANTSPACE="21 GB" DEBUG_VARS_OFF= BUILDTYPE=Release \ GN_ARGS+=blink_symbol_level=0 \ GN_ARGS+=is_debug=false \ GN_ARGS+=is_official_build=true \ GN_ARGS+=symbol_level=0 \ WANTSPACE="14 GB" DRIVER_MAKE_ARGS= chromedriver HEIMDAL_LIB_DEPENDS= libkrb.so.26:security/heimdal KERBEROS_VARS= GN_ARGS+=use_kerberos=true KERBEROS_VARS_OFF= GN_ARGS+=use_kerberos=false LTO_VARS= GN_ARGS+=use_thin_lto=true \ GN_ARGS+=thin_lto_enable_optimizations=true \ WANTSPACE="14 GB" LTO_VARS_OFF= GN_ARGS+=use_thin_lto=false MIT_LIB_DEPENDS= libkrb.so.3:security/krb5 PULSEAUDIO_LIB_DEPENDS= libpulse.so:audio/pulseaudio PULSEAUDIO_VARS= GN_ARGS+=use_pulseaudio=true PULSEAUDIO_VARS_OFF= GN_ARGS+=use_pulseaudio=false # With SNDIO=on we exclude audio_manager_linux from the build (see # media/audio/BUILD.gn) and use audio_manager_openbsd which does not # support falling back to ALSA or PulseAudio. SNDIO_PREVENTS= ALSA PULSEAUDIO SNDIO_LIB_DEPENDS= libsndio.so:audio/sndio SNDIO_VARS= GN_ARGS+=use_sndio=true SNDIO_VARS_OFF= GN_ARGS+=use_sndio=false .include "Makefile.tests" TEST_DISTFILES= ${PORTNAME}-${DISTVERSION}-testdata${EXTRACT_SUFX} \ test_fonts-336e775eec536b2d785cc80eff6ac39051931286.tar.gz:external TEST_ALL_TARGET= ${TEST_TARGETS} .include .include .if ${OSREL} == "12.3" BROKEN= does not compile, libc++ too old .endif .if ${PORT_OPTIONS:MHEIMDAL_BASE} && !exists(/usr/lib/libkrb5.so) IGNORE= you have selected HEIMDAL_BASE but do not have Heimdal installed in base .endif .if ${COMPILER_VERSION} != 130 LLVM_DEFAULT= 13 BUILD_DEPENDS+= clang${LLVM_DEFAULT}:devel/llvm${LLVM_DEFAULT} BINARY_ALIAS+= cpp=${LOCALBASE}/bin/clang-cpp${LLVM_DEFAULT} \ cc=${LOCALBASE}/bin/clang${LLVM_DEFAULT} \ c++=${LOCALBASE}/bin/clang++${LLVM_DEFAULT} \ ar=${LOCALBASE}/bin/llvm-ar${LLVM_DEFAULT} \ nm=${LOCALBASE}/bin/llvm-nm${LLVM_DEFAULT} \ ld=${LOCALBASE}/bin/ld.lld${LLVM_DEFAULT} .else BINARY_ALIAS+= ar=/usr/bin/llvm-ar \ nm=/usr/bin/llvm-nm .endif # swiftshader/lib/{libEGL.so,libGLESv2.so} is x86 only .if ${ARCH} == aarch64 PLIST_SUB+= NOT_AARCH64="@comment " .else PLIST_SUB+= NOT_AARCH64="" .endif # Allow relocations against read-only segments (override lld default) LDFLAGS_i386= -Wl,-znotext # TODO: -isystem, would be just as ugly as this approach, but more reliably # build would fail without C_INCLUDE_PATH/CPLUS_INCLUDE_PATH env var set. MAKE_ENV+= C_INCLUDE_PATH=${LOCALBASE}/include \ CPLUS_INCLUDE_PATH=${LOCALBASE}/include pre-everything:: @${ECHO_MSG} @${ECHO_MSG} "To build Chromium, you should have around 2GB of memory" @${ECHO_MSG} "and around ${WANTSPACE} of free disk space." @${ECHO_MSG} post-extract-TEST-on: @${MKDIR} ${WRKSRC}/third_party/test_fonts/test_fonts @${MV} ${WRKDIR}/test_fonts ${WRKSRC}/third_party/test_fonts/ pre-configure: # We used to remove bundled libraries to be sure that chromium uses # system libraries and not shipped ones. # cd ${WRKSRC} && ${PYTHON_CMD} \ #./build/linux/unbundle/remove_bundled_libraries.py [list of preserved] cd ${WRKSRC} && ${SETENV} ${CONFIGURE_ENV} ${PYTHON_CMD} \ ./build/linux/unbundle/replace_gn_files.py --system-libraries \ flac fontconfig freetype harfbuzz-ng icu libdrm libevent libpng \ libusb libwebp libxml libxslt openh264 opus snappy || ${FALSE} # Chromium uses an unreleased version of FFmpeg, so configure it .for brand in Chrome Chromium ${CP} -R \ ${WRKSRC}/third_party/ffmpeg/chromium/config/${brand}/linux/ \ ${WRKSRC}/third_party/ffmpeg/chromium/config/${brand}/freebsd .endfor do-configure: # GN generator bootstrapping and generating ninja files cd ${WRKSRC} && ${SETENV} ${CONFIGURE_ENV} CC=${CC} CXX=${CXX} LD=${CXX} \ READELF=${READELF} AR=${AR} NM=${NM} ${PYTHON_CMD} \ ./tools/gn/bootstrap/bootstrap.py ${GN_BOOTSTRAP_FLAGS} cd ${WRKSRC} && ${SETENV} ${CONFIGURE_ENV} ./out/${BUILDTYPE}/gn \ gen --args='${GN_ARGS}' out/${BUILDTYPE} # Setup nodejs dependency @${MKDIR} ${WRKSRC}/third_party/node/freebsd/node-freebsd/bin ${LN} -sf ${LOCALBASE}/bin/node ${WRKSRC}/third_party/node/freebsd/node-freebsd/bin/node # Setup buildtools/freebsd @${MKDIR} ${WRKSRC}/buildtools/freebsd ${LN} -sf ${WRKSRC}/buildtools/linux64/clang-format ${WRKSRC}/buildtools/freebsd ${LN} -sf ${WRKSRC}/out/${BUILDTYPE}/gn ${WRKSRC}/buildtools/freebsd ${LN} -sf /usr/bin/strip ${WRKSRC}/buildtools/freebsd/strip do-install: @${MKDIR} ${STAGEDIR}${DATADIR} ${INSTALL_MAN} ${WRKSRC}/chrome/app/resources/manpage.1.in \ ${STAGEDIR}${MANPREFIX}/man/man1/chrome.1 @${SED} -i "" -e 's,\@\@PACKAGE\@\@,chromium,g;s,\@\@MENUNAME\@\@,Chromium Web Browser,g' \ ${STAGEDIR}${MANPREFIX}/man/man1/chrome.1 ${CP} ${WRKSRC}/chrome/app/theme/chromium/product_logo_22_mono.png ${WRKSRC}/chrome/app/theme/chromium/product_logo_22.png .for s in 22 24 48 64 128 256 @${MKDIR} ${STAGEDIR}${PREFIX}/share/icons/hicolor/${s}x${s}/apps ${INSTALL_DATA} ${WRKSRC}/chrome/app/theme/chromium/product_logo_${s}.png \ ${STAGEDIR}${PREFIX}/share/icons/hicolor/${s}x${s}/apps/chrome.png .endfor ${INSTALL_DATA} ${WRKSRC}/out/${BUILDTYPE}/*.png ${STAGEDIR}${DATADIR} ${INSTALL_DATA} ${WRKSRC}/out/${BUILDTYPE}/*.pak ${STAGEDIR}${DATADIR} .for d in protoc mksnapshot ${INSTALL_PROGRAM} ${WRKSRC}/out/${BUILDTYPE}/${d} ${STAGEDIR}${DATADIR} .endfor .for d in snapshot_blob.bin v8_context_snapshot.bin ${INSTALL_DATA} ${WRKSRC}/out/${BUILDTYPE}/${d} ${STAGEDIR}${DATADIR} .endfor ${INSTALL_PROGRAM} ${WRKSRC}/out/${BUILDTYPE}/chrome \ ${STAGEDIR}${DATADIR} cd ${WRKSRC}/out/${BUILDTYPE} && \ ${COPYTREE_SHARE} "locales resources" ${STAGEDIR}${DATADIR} @${MKDIR} ${STAGEDIR}${DESKTOPDIR} ${INSTALL_DATA} ${WRKDIR}/chromium-browser.desktop \ ${STAGEDIR}${DESKTOPDIR} ${INSTALL_SCRIPT} ${WRKDIR}/chrome ${STAGEDIR}${PREFIX}/bin ${INSTALL_SCRIPT} ${WRKSRC}/chrome/tools/build/linux/chrome-wrapper \ ${STAGEDIR}${DATADIR} # ANGLE, EGL, Vk .for f in libEGL.so libGLESv2.so libVkICD_mock_icd.so ${INSTALL_LIB} ${WRKSRC}/out/${BUILDTYPE}/${f} ${STAGEDIR}${DATADIR} .endfor ${INSTALL_LIB} ${WRKSRC}/out/${BUILDTYPE}/libvulkan.so.1 \ ${STAGEDIR}${DATADIR}/libvulkan.so .if ${BUILDTYPE} == Debug ${INSTALL_LIB} ${WRKSRC}/out/${BUILDTYPE}/libVkLayer_khronos_validation.so ${STAGEDIR}${DATADIR} .endif # SwiftShader .if ${ARCH} != aarch64 ${INSTALL_LIB} ${WRKSRC}/out/${BUILDTYPE}/libvk_swiftshader.so ${STAGEDIR}${DATADIR} .endif post-install-DEBUG-on: ${INSTALL_LIB} ${WRKSRC}/out/${BUILDTYPE}/*.so \ ${STAGEDIR}${DATADIR} ${INSTALL_PROGRAM} ${WRKSRC}/out/${BUILDTYPE}/character_data_generator \ ${STAGEDIR}${DATADIR} post-install-DRIVER-on: ${INSTALL_PROGRAM} ${WRKSRC}/out/${BUILDTYPE}/chromedriver.unstripped \ ${STAGEDIR}${PREFIX}/bin/chromedriver do-test-TEST-on: .for t in ${TEST_TARGETS} cd ${WRKSRC}/out/${BUILDTYPE} && ${SETENV} LC_ALL=en_US.UTF-8 \ ./${t} --gtest_filter=-${EXCLUDE_${t}:ts:} || ${TRUE} .endfor .include diff --git a/www/chromium/distinfo b/www/chromium/distinfo index b941dd9b4e33..79c528252617 100644 --- a/www/chromium/distinfo +++ b/www/chromium/distinfo @@ -1,9 +1,9 @@ -TIMESTAMP = 1666729701 -SHA256 (chromium-107.0.5304.68.tar.xz) = aac4f19b2e12e3ec3fd8179de26b306a4e209ec2a39b24e9e04fcce057cdb84c -SIZE (chromium-107.0.5304.68.tar.xz) = 1689426804 -SHA256 (chrome-linux-107.0.5304.68-llvm13.profdata.tar.xz) = 0516997025f3c59fa54e315d7df4a2411badfd14edf86c9a75ea2351ba594521 -SIZE (chrome-linux-107.0.5304.68-llvm13.profdata.tar.xz) = 25449520 -SHA256 (chromium-107.0.5304.68-testdata.tar.xz) = d85c84d9bbce2a9c44bf1d9540f94b4527c7e179856831413957c664e3d4020d -SIZE (chromium-107.0.5304.68-testdata.tar.xz) = 263941456 +TIMESTAMP = 1666975763 +SHA256 (chromium-107.0.5304.87.tar.xz) = 6c0e00c186e22a1be29177ea410ba40ff0bf65f3ded67a345eb5b17f76c93c59 +SIZE (chromium-107.0.5304.87.tar.xz) = 1688896996 +SHA256 (chrome-linux-107.0.5304.87-llvm13.profdata.tar.xz) = 70e85fbbf7bbea0fcb99ac9a0f646f1d0392b601d7acab9f283cd82f36e6345d +SIZE (chrome-linux-107.0.5304.87-llvm13.profdata.tar.xz) = 25441580 +SHA256 (chromium-107.0.5304.87-testdata.tar.xz) = 9b4ebb4c1d5bcab70f4eb0738cc2cc9a6545780f9b4d8f7ee1abb4708fa09b35 +SIZE (chromium-107.0.5304.87-testdata.tar.xz) = 266527724 SHA256 (test_fonts-336e775eec536b2d785cc80eff6ac39051931286.tar.gz) = a2ca2962daf482a8f943163541e1c73ba4b2694fabcd2510981f2db4eda493c8 SIZE (test_fonts-336e775eec536b2d785cc80eff6ac39051931286.tar.gz) = 32624734 diff --git a/www/chromium/files/patch-content_gpu_gpu__sandbox__hook__linux.cc b/www/chromium/files/patch-content_gpu_gpu__sandbox__hook__linux.cc index bccf1c0fef55..2498371147ff 100644 --- a/www/chromium/files/patch-content_gpu_gpu__sandbox__hook__linux.cc +++ b/www/chromium/files/patch-content_gpu_gpu__sandbox__hook__linux.cc @@ -1,70 +1,70 @@ ---- content/gpu/gpu_sandbox_hook_linux.cc.orig 2022-10-24 13:33:33 UTC +--- content/gpu/gpu_sandbox_hook_linux.cc.orig 2022-10-28 16:46:12 UTC +++ content/gpu/gpu_sandbox_hook_linux.cc @@ -121,6 +121,7 @@ void AddStandardChromeOsPermissions( permissions->push_back(BrokerFilePermission::ReadOnly(kAngleGlesPath)); } +#if !defined(OS_BSD) void AddV4L2GpuPermissions( std::vector* permissions, const sandbox::policy::SandboxSeccompBPF::Options& options) { -@@ -437,8 +438,10 @@ std::vector FilePermissionsForGp +@@ -440,8 +441,10 @@ std::vector FilePermissionsForGp AddStandardGpuPermissions(&permissions); return permissions; } +#endif void LoadArmGpuLibraries() { +#if !defined(OS_BSD) // Preload the Mali library. if (UseChromecastSandboxAllowlist()) { for (const char* path : kAllowedChromecastPaths) { -@@ -480,6 +483,7 @@ void LoadArmGpuLibraries() { +@@ -483,6 +486,7 @@ void LoadArmGpuLibraries() { dlopen(driver_paths[i], dlopen_flag); } } +#endif } bool LoadAmdGpuLibraries() { -@@ -547,12 +551,14 @@ void LoadV4L2Libraries( +@@ -550,12 +554,14 @@ void LoadV4L2Libraries( } void LoadChromecastV4L2Libraries() { +#if !defined(OS_BSD) for (const char* path : kAllowedChromecastPaths) { const std::string library_path(std::string(path) + std::string("libvpcodec.so")); if (dlopen(library_path.c_str(), dlopen_flag)) break; } +#endif } bool LoadLibrariesForGpu( -@@ -580,6 +586,7 @@ bool LoadLibrariesForGpu( +@@ -583,6 +589,7 @@ bool LoadLibrariesForGpu( return true; } +#if !defined(OS_BSD) sandbox::syscall_broker::BrokerCommandSet CommandSetForGPU( const sandbox::policy::SandboxLinux::Options& options) { sandbox::syscall_broker::BrokerCommandSet command_set; -@@ -602,13 +609,17 @@ bool BrokerProcessPreSandboxHook( +@@ -605,13 +612,17 @@ bool BrokerProcessPreSandboxHook( SetProcessTitleFromCommandLine(nullptr); return true; } +#endif } // namespace bool GpuProcessPreSandboxHook(sandbox::policy::SandboxLinux::Options options) { + NOTIMPLEMENTED(); +#if !defined(OS_BSD) sandbox::policy::SandboxLinux::GetInstance()->StartBrokerProcess( CommandSetForGPU(options), FilePermissionsForGpu(options), base::BindOnce(BrokerProcessPreSandboxHook), options); +#endif if (!LoadLibrariesForGpu(options)) return false; diff --git a/www/chromium/files/patch-services_device_hid_hid__connection__fido.cc b/www/chromium/files/patch-services_device_hid_hid__connection__fido.cc index 2a0b172b142a..590b1dbc5c78 100644 --- a/www/chromium/files/patch-services_device_hid_hid__connection__fido.cc +++ b/www/chromium/files/patch-services_device_hid_hid__connection__fido.cc @@ -1,200 +1,221 @@ ---- services/device/hid/hid_connection_fido.cc.orig 2022-06-17 14:20:10 UTC +--- services/device/hid/hid_connection_fido.cc.orig 2022-10-28 16:39:00 UTC +++ services/device/hid/hid_connection_fido.cc -@@ -0,0 +1,197 @@ -+// Copyright (c) 2020 The Chromium Authors. All rights reserved. +@@ -0,0 +1,218 @@ ++// 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. + +#include "services/device/hid/hid_connection_fido.h" + ++#include ++#include ++ ++#include ++#include ++#include ++ +#include "base/bind.h" +#include "base/files/file_descriptor_watcher_posix.h" -+#include "base/location.h" -+#include "base/numerics/safe_math.h" ++#include "base/memory/ref_counted_memory.h" +#include "base/posix/eintr_wrapper.h" -+#include "base/task/single_thread_task_runner.h" +#include "base/threading/scoped_blocking_call.h" -+#include "base/threading/thread_restrictions.h" -+#include "base/threading/thread_task_runner_handle.h" ++#include "base/threading/sequenced_task_runner_handle.h" +#include "components/device_event_log/device_event_log.h" +#include "services/device/hid/hid_service.h" + +namespace device { + -+class HidConnectionFido::BlockingTaskHelper { -+public: -+ BlockingTaskHelper(base::ScopedFD fd, -+ scoped_refptr device_info, -+ base::WeakPtr connection) ++class HidConnectionFido::BlockingTaskRunnerHelper { ++ public: ++ BlockingTaskRunnerHelper(base::ScopedFD fd, ++ scoped_refptr device_info, ++ base::WeakPtr connection) + : fd_(std::move(fd)), -+ // Report buffers must always have room for the report ID. -+ report_buffer_size_(device_info->max_input_report_size() + 1), -+ has_report_id_(device_info->has_report_id()), connection_(connection), -+ origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) { ++ connection_(connection), ++ origin_task_runner_(base::SequencedTaskRunnerHandle::Get()) { + DETACH_FROM_SEQUENCE(sequence_checker_); ++ // Report buffers must always have room for the report ID. ++ report_buffer_size_ = device_info->max_input_report_size() + 1; ++ has_report_id_ = device_info->has_report_id(); + } + -+ BlockingTaskHelper(const BlockingTaskHelper&) = delete; -+ BlockingTaskHelper& operator=(const BlockingTaskHelper&) = delete; ++ BlockingTaskRunnerHelper(const BlockingTaskRunnerHelper&) = delete; ++ BlockingTaskRunnerHelper& operator=(const BlockingTaskRunnerHelper&) = delete; + -+ ~BlockingTaskHelper() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); } ++ ~BlockingTaskRunnerHelper() { ++ DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ } + + // Starts the FileDescriptorWatcher that reads input events from the device. + // Must be called on a thread that has a base::MessageLoopForIO. + void Start() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -+ base::internal::AssertBlockingAllowed(); + + file_watcher_ = base::FileDescriptorWatcher::WatchReadable( -+ fd_.get(), base::BindRepeating(&BlockingTaskHelper::OnFileCanReadWithoutBlocking, -+ base::Unretained(this))); ++ fd_.get(), base::BindRepeating( ++ &BlockingTaskRunnerHelper::OnFileCanReadWithoutBlocking, ++ base::Unretained(this))); + } + + void Write(scoped_refptr buffer, + WriteCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::ScopedBlockingCall scoped_blocking_call( + FROM_HERE, base::BlockingType::MAY_BLOCK); + + auto data = buffer->front(); + size_t size = buffer->size(); + // if report id is 0, it shouldn't be included + if (data[0] == 0) { + data++; + size--; + } + -+ ssize_t result = HANDLE_EINTR(write(fd_.get(), data, size)); -+ bool success = static_cast(result) == size; -+ if (!success) { -+ HID_LOG(EVENT) << "HID write failed: " << result << " != " << size; ++ ssize_t result = ++ HANDLE_EINTR(write(fd_.get(), data, size)); ++ if (result < 0) { ++ HID_PLOG(EVENT) << "Write failed"; ++ origin_task_runner_->PostTask(FROM_HERE, ++ base::BindOnce(std::move(callback), false)); ++ } else { ++ if (static_cast(result) != size) { ++ HID_LOG(EVENT) << "Incomplete HID write: " << result ++ << " != " << buffer->size(); ++ } ++ origin_task_runner_->PostTask(FROM_HERE, ++ base::BindOnce(std::move(callback), true)); + } -+ origin_task_runner_->PostTask(FROM_HERE, -+ base::BindOnce(std::move(callback), success)); + } + + void GetFeatureReport(uint8_t report_id, + scoped_refptr buffer, + ReadCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + base::ScopedBlockingCall scoped_blocking_call( + FROM_HERE, base::BlockingType::MAY_BLOCK); + HID_PLOG(EVENT) << "GendFeatureReport not implemented on OpenBSD"; + origin_task_runner_->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), false, nullptr, 0)); + } + + void SendFeatureReport(scoped_refptr buffer, + WriteCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); ++ base::ScopedBlockingCall scoped_blocking_call( ++ FROM_HERE, base::BlockingType::MAY_BLOCK); + HID_PLOG(EVENT) << "SendFeatureReport not implemented on OpenBSD"; + origin_task_runner_->PostTask(FROM_HERE, -+ base::BindOnce(std::move(callback), false)); ++ base::BindOnce(std::move(callback), false)); + } + -+private: ++ private: + void OnFileCanReadWithoutBlocking() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + -+ scoped_refptr buffer( -+ new base::RefCountedBytes(report_buffer_size_)); -+ unsigned char *data = buffer->front(); ++ auto buffer = ++ base::MakeRefCounted(report_buffer_size_); ++ uint8_t* data = buffer->front(); + size_t length = report_buffer_size_; + if (!has_report_id_) { -+ // OpenBSD will not prefix the buffer with a report ID if report IDs are -+ // not used by the device. Prefix the buffer with 0. ++ // Fido will not prefix the buffer with a report ID if report IDs are not ++ // used by the device. Prefix the buffer with 0. + *data++ = 0; + length--; + } + + ssize_t bytes_read = HANDLE_EINTR(read(fd_.get(), data, length)); + if (bytes_read < 0) { + if (errno != EAGAIN) { + HID_PLOG(EVENT) << "Read failed"; + // This assumes that the error is unrecoverable and disables reading + // from the device until it has been re-opened. + // TODO(reillyg): Investigate starting and stopping the file descriptor + // watcher in response to pending read requests so that per-request + // errors can be returned to the client. + file_watcher_.reset(); + } + return; + } + if (!has_report_id_) { + // Behave as if the byte prefixed above as the the report ID was read. + bytes_read++; + } + + origin_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&HidConnectionFido::ProcessInputReport, + connection_, buffer, bytes_read)); + } + + SEQUENCE_CHECKER(sequence_checker_); + base::ScopedFD fd_; -+ const size_t report_buffer_size_; -+ const bool has_report_id_; ++ size_t report_buffer_size_; ++ bool has_report_id_; + base::WeakPtr connection_; + const scoped_refptr origin_task_runner_; + std::unique_ptr file_watcher_; +}; + +HidConnectionFido::HidConnectionFido( -+ scoped_refptr device_info, base::ScopedFD fd, ++ scoped_refptr device_info, ++ base::ScopedFD fd, + scoped_refptr blocking_task_runner, -+ bool allow_protected_reports, bool allow_fido_reports) ++ bool allow_protected_reports, ++ bool allow_fido_reports) + : HidConnection(device_info, allow_protected_reports, allow_fido_reports), -+ blocking_task_runner_(std::move(blocking_task_runner)), -+ weak_factory_(this), -+ helper_(std::make_unique( -+ std::move(fd), device_info, weak_factory_.GetWeakPtr())) { ++ helper_(nullptr, base::OnTaskRunnerDeleter(blocking_task_runner)), ++ blocking_task_runner_(std::move(blocking_task_runner)) { ++ helper_.reset(new BlockingTaskRunnerHelper(std::move(fd), device_info, ++ weak_factory_.GetWeakPtr())); + blocking_task_runner_->PostTask( -+ FROM_HERE, base::BindOnce(&BlockingTaskHelper::Start, ++ FROM_HERE, base::BindOnce(&BlockingTaskRunnerHelper::Start, + base::Unretained(helper_.get()))); +} + -+HidConnectionFido::~HidConnectionFido() = default; ++HidConnectionFido::~HidConnectionFido() {} + +void HidConnectionFido::PlatformClose() { + // By closing the device on the blocking task runner 1) the requirement that + // base::ScopedFD is destroyed on a thread where I/O is allowed is satisfied + // and 2) any tasks posted to this task runner that refer to this file will + // complete before it is closed. -+ blocking_task_runner_->DeleteSoon(FROM_HERE, helper_.release()); ++ helper_.reset(); +} + +void HidConnectionFido::PlatformWrite( -+ scoped_refptr buffer, WriteCallback callback) { ++ scoped_refptr buffer, ++ WriteCallback callback) { ++ // Fido expects the first byte of the buffer to always be a report ID so the ++ // buffer can be used directly. + blocking_task_runner_->PostTask( -+ FROM_HERE, base::BindOnce(&BlockingTaskHelper::Write, ++ FROM_HERE, base::BindOnce(&BlockingTaskRunnerHelper::Write, + base::Unretained(helper_.get()), buffer, + std::move(callback))); +} + +void HidConnectionFido::PlatformGetFeatureReport(uint8_t report_id, -+ ReadCallback callback) { ++ ReadCallback callback) { + // The first byte of the destination buffer is the report ID being requested + // and is overwritten by the feature report. + DCHECK_GT(device_info()->max_feature_report_size(), 0u); -+ scoped_refptr buffer( -+ new base::RefCountedBytes(device_info()->max_feature_report_size() + 1)); -+ if (report_id != 0) -+ buffer->data()[0] = report_id; ++ auto buffer = base::MakeRefCounted( ++ device_info()->max_feature_report_size() + 1); ++ buffer->data()[0] = report_id; + + blocking_task_runner_->PostTask( -+ FROM_HERE, base::BindOnce(&BlockingTaskHelper::GetFeatureReport, ++ FROM_HERE, base::BindOnce(&BlockingTaskRunnerHelper::GetFeatureReport, + base::Unretained(helper_.get()), report_id, + buffer, std::move(callback))); +} + +void HidConnectionFido::PlatformSendFeatureReport( -+ scoped_refptr buffer, WriteCallback callback) { -+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, -+ base::BlockingType::MAY_BLOCK); ++ scoped_refptr buffer, ++ WriteCallback callback) { ++ // Fido expects the first byte of the buffer to always be a report ID so the ++ // buffer can be used directly. + blocking_task_runner_->PostTask( -+ FROM_HERE, base::BindOnce(&BlockingTaskHelper::SendFeatureReport, ++ FROM_HERE, base::BindOnce(&BlockingTaskRunnerHelper::SendFeatureReport, + base::Unretained(helper_.get()), buffer, + std::move(callback))); +} + -+} // namespace device ++} // namespace device diff --git a/www/chromium/files/patch-services_device_hid_hid__connection__fido.h b/www/chromium/files/patch-services_device_hid_hid__connection__fido.h index a491864edae6..9e5e403189a4 100644 --- a/www/chromium/files/patch-services_device_hid_hid__connection__fido.h +++ b/www/chromium/files/patch-services_device_hid_hid__connection__fido.h @@ -1,60 +1,63 @@ ---- services/device/hid/hid_connection_fido.h.orig 2022-02-07 13:39:41 UTC +--- services/device/hid/hid_connection_fido.h.orig 2022-10-28 16:39:00 UTC +++ services/device/hid/hid_connection_fido.h -@@ -0,0 +1,57 @@ -+// Copyright (c) 2020 The Chromium Authors. All rights reserved. +@@ -0,0 +1,60 @@ ++// 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. + -+#ifndef SERVICE_DEVICE_HID_HID_CONNECTION_FIDO_H_ -+#define SERVICE_DEVICE_HID_HID_CONNECTION_FIDO_H_ ++#ifndef SERVICES_DEVICE_HID_HID_CONNECTION_LINUX_H_ ++#define SERVICES_DEVICE_HID_HID_CONNECTION_LINUX_H_ ++ ++#include ++#include + +#include "base/files/scoped_file.h" -+#include "base/memory/ptr_util.h" -+#include "base/memory/ref_counted_memory.h" +#include "base/memory/weak_ptr.h" -+#include "base/sequence_checker.h" ++#include "base/task/sequenced_task_runner.h" +#include "services/device/hid/hid_connection.h" + ++namespace base { ++class SequencedTaskRunner; ++} ++ +namespace device { + +class HidConnectionFido : public HidConnection { -+public: ++ public: + HidConnectionFido( -+ scoped_refptr device_info, base::ScopedFD fd, ++ scoped_refptr device_info, ++ base::ScopedFD fd, + scoped_refptr blocking_task_runner, -+ bool allow_protected_reports, bool allow_fido_reports); ++ bool allow_protected_reports, ++ bool allow_fido_reports); ++ HidConnectionFido(HidConnectionFido&) = delete; ++ HidConnectionFido& operator=(HidConnectionFido&) = delete; + -+private: ++ private: + friend class base::RefCountedThreadSafe; -+ class BlockingTaskHelper; -+ -+ HidConnectionFido(const HidConnectionFido&) = delete; -+ HidConnectionFido& operator=(const HidConnectionFido&) = delete; ++ class BlockingTaskRunnerHelper; + + ~HidConnectionFido() override; + + // HidConnection implementation. + void PlatformClose() override; + void PlatformWrite(scoped_refptr buffer, + WriteCallback callback) override; + void PlatformGetFeatureReport(uint8_t report_id, + ReadCallback callback) override; + void PlatformSendFeatureReport(scoped_refptr buffer, + WriteCallback callback) override; + -+ const scoped_refptr blocking_task_runner_; -+ const scoped_refptr task_runner_; -+ -+ SEQUENCE_CHECKER(sequence_checker_); -+ -+ base::WeakPtrFactory weak_factory_; -+ + // |helper_| lives on the sequence to which |blocking_task_runner_| posts + // tasks so all calls must be posted there including this object's + // destruction. -+ std::unique_ptr helper_; ++ std::unique_ptr helper_; ++ ++ const scoped_refptr blocking_task_runner_; ++ ++ base::WeakPtrFactory weak_factory_{this}; +}; + -+} // namespace device ++} // namespace device + -+#endif // SERVICE_DEVICE_HID_HID_CONNECTION_FIDO_H_ ++#endif // SERVICES_DEVICE_HID_HID_CONNECTION_LINUX_H_ diff --git a/www/chromium/files/patch-services_device_hid_hid__service__fido.cc b/www/chromium/files/patch-services_device_hid_hid__service__fido.cc index e0deca268d8a..fd91ce654bb6 100644 --- a/www/chromium/files/patch-services_device_hid_hid__service__fido.cc +++ b/www/chromium/files/patch-services_device_hid_hid__service__fido.cc @@ -1,330 +1,395 @@ ---- services/device/hid/hid_service_fido.cc.orig 2022-06-17 14:20:10 UTC +--- services/device/hid/hid_service_fido.cc.orig 2022-10-28 16:39:00 UTC +++ services/device/hid/hid_service_fido.cc -@@ -0,0 +1,327 @@ -+// Copyright 2020 The Chromium Authors. All rights reserved. +@@ -0,0 +1,392 @@ ++// 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. + +#include "services/device/hid/hid_service_fido.h" + +#include +#include +#include -+#include -+#include -+#include + -+// TODO: remove once the missing guard in fido.h is fixed upstream. -+extern "C" { +#include -+} + -+#include ++#include ++#include +#include -+#include ++#include + +#include "base/bind.h" ++#include "base/callback_helpers.h" +#include "base/files/file.h" -+#include "base/files/file_descriptor_watcher_posix.h" -+#include "base/files/file_enumerator.h" ++#include "base/files/file_path.h" ++#include "base/files/file_util.h" ++#include "base/files/scoped_file.h" +#include "base/location.h" -+#include "base/logging.h" -+#include "base/posix/eintr_wrapper.h" -+#include "base/task/single_thread_task_runner.h" -+#include "base/task/thread_pool.h" -+#include "base/stl_util.h" -+#include "base/strings/pattern.h" ++#include "base/sequence_checker.h" ++#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/strings/string_util.h" -+#include "base/strings/stringprintf.h" -+#include "base/strings/sys_string_conversions.h" ++#include "base/task/sequenced_task_runner.h" ++#include "base/task/thread_pool.h" +#include "base/threading/scoped_blocking_call.h" -+#include "base/threading/thread_task_runner_handle.h" ++#include "base/threading/sequenced_task_runner_handle.h" ++#include "build/build_config.h" ++#include "build/chromeos_buildflags.h" +#include "components/device_event_log/device_event_log.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 { + -+struct ConnectParams { -+ ConnectParams(scoped_refptr device_info, -+ HidService::ConnectCallback callback) -+ : device_info(std::move(device_info)), callback(std::move(callback)), -+ task_runner(base::ThreadTaskRunnerHandle::Get()), -+ blocking_task_runner(base::ThreadPool::CreateSequencedTaskRunner( -+ HidService::kBlockingTaskTraits)) {} -+ ~ConnectParams() {} -+ -+ scoped_refptr device_info; -+ HidService::ConnectCallback callback; -+ scoped_refptr task_runner; -+ scoped_refptr blocking_task_runner; -+ base::ScopedFD fd; -+ bool allow_protected_reports; -+ bool allow_fido_reports; -+}; -+ -+void CreateConnection(std::unique_ptr params) { -+ DCHECK(params->fd.is_valid()); -+ std::move(params->callback).Run(base::MakeRefCounted( -+ std::move(params->device_info), std::move(params->fd), -+ std::move(params->blocking_task_runner), params->allow_protected_reports, -+ params->allow_fido_reports)); -+} -+ -+void FinishOpen(std::unique_ptr params) { -+ scoped_refptr task_runner = params->task_runner; -+ -+ task_runner->PostTask(FROM_HERE, -+ base::BindOnce(&CreateConnection, std::move(params))); -+} -+ +bool terrible_ping_kludge(int fd, const std::string &path) { + u_char data[256]; + int i, n; + struct pollfd pfd; + + for (i = 0; i < 4; i++) { + memset(data, 0, sizeof(data)); + /* broadcast channel ID */ + data[1] = 0xff; + data[2] = 0xff; + data[3] = 0xff; + data[4] = 0xff; + /* Ping command */ + data[5] = 0x81; + /* One byte ping only, Vasili */ -+ data[6] = 0; -+ data[7] = 1; ++ data[6] = 0; ++ data[7] = 1; + HID_LOG(EVENT) << "send ping " << i << " " << path; + if (write(fd, data, 64) == -1) { + HID_PLOG(ERROR) << "write " << path; + return false; + } + HID_LOG(EVENT) << "wait reply " << path; + memset(&pfd, 0, sizeof(pfd)); -+ pfd.fd = fd; ++ pfd.fd = fd; + pfd.events = POLLIN; + if ((n = poll(&pfd, 1, 100)) == -1) { + HID_PLOG(EVENT) << "poll " << path; + return false; + } else if (n == 0) { + HID_LOG(EVENT) << "timed out " << path; + continue; + } -+ if (read(fd, data, 64) == -1) { ++ if (read(fd, data, 64) == -1) { + HID_PLOG(ERROR) << "read " << path; + return false; + } + /* + * Ping isn't always supported on the broadcast channel, + * so we might get an error, but we don't care - we're + * synched now. + */ + HID_LOG(EVENT) << "got reply " << path; + return true; + } + HID_LOG(ERROR) << "no response " << path; + return false; +} + -+void OpenOnBlockingThread(std::unique_ptr params) { -+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, -+ base::BlockingType::MAY_BLOCK); -+ scoped_refptr task_runner = params->task_runner; -+ -+ const auto &device_node = params->device_info->device_node(); -+ base::FilePath device_path(device_node); -+ int flags = -+ base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE; -+ base::File device_file(device_path, flags); -+ if (!device_file.IsValid()) { -+ HID_LOG(EVENT) << "Failed to open '" << device_node << "': " -+ << base::File::ErrorToString(device_file.error_details()); -+ task_runner->PostTask(FROM_HERE, base::BindOnce(std::move(params->callback), nullptr)); -+ return; -+ } -+ if (!terrible_ping_kludge(device_file.GetPlatformFile(), device_node)) { -+ HID_LOG(EVENT) << "Failed to ping " << device_node; -+ task_runner->PostTask(FROM_HERE, base::BindOnce(std::move(params->callback), nullptr)); -+ return; -+ } -+ params->fd.reset(device_file.TakePlatformFile()); -+ FinishOpen(std::move(params)); -+} -+ +// HID report descriptor for U2F interface. Copied from: +// https://chromium.googlesource.com/chromiumos/platform2/+/c6c7e4e54fce11932fedaa3ea10236bf75d85a2b%5E%21/u2fd/u2fhid.cc +// Apparently Chromium wants to see these bytes, but OpenBSD fido(4) +// devices prohibit USB_GET_REPORT_DESC ioctl that could be used to +// get the bytes from the USB device. +constexpr uint8_t kU2fReportDesc[] = { + 0x06, 0xD0, 0xF1, /* Usage Page (FIDO Alliance), FIDO_USAGE_PAGE */ + 0x09, 0x01, /* Usage (U2F HID Auth. Device) FIDO_USAGE_U2FHID */ + 0xA1, 0x01, /* Collection (Application), HID_APPLICATION */ + 0x09, 0x20, /* Usage (Input Report Data), FIDO_USAGE_DATA_IN */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x40, /* Report Count (64), HID_INPUT_REPORT_BYTES */ + 0x81, 0x02, /* Input (Data, Var, Abs), Usage */ + 0x09, 0x21, /* Usage (Output Report Data), FIDO_USAGE_DATA_OUT */ + 0x15, 0x00, /* Logical Minimum (0) */ + 0x26, 0xFF, 0x00, /* Logical Maximum (255) */ + 0x75, 0x08, /* Report Size (8) */ + 0x95, 0x40, /* Report Count (64), HID_OUTPUT_REPORT_BYTES */ + 0x91, 0x02, /* Output (Data, Var, Abs), Usage */ + 0xC0 /* End Collection */ +}; + -+} // namespace ++} // namespace ++ ++struct HidServiceFido::ConnectParams { ++ ConnectParams(scoped_refptr device_info, ++ bool allow_protected_reports, ++ bool allow_fido_reports, ++ ConnectCallback callback) ++ : device_info(std::move(device_info)), ++ allow_protected_reports(allow_protected_reports), ++ allow_fido_reports(allow_fido_reports), ++ callback(std::move(callback)), ++ task_runner(base::SequencedTaskRunnerHandle::Get()), ++ blocking_task_runner( ++ base::ThreadPool::CreateSequencedTaskRunner(kBlockingTaskTraits)) {} ++ ~ConnectParams() {} ++ ++ scoped_refptr device_info; ++ bool allow_protected_reports; ++ bool allow_fido_reports; ++ ConnectCallback callback; ++ scoped_refptr task_runner; ++ scoped_refptr blocking_task_runner; ++ base::ScopedFD fd; ++}; + -+class HidServiceFido::BlockingTaskHelper { -+public: -+ BlockingTaskHelper(base::WeakPtr service) ++class HidServiceFido::BlockingTaskRunnerHelper { ++ public: ++ BlockingTaskRunnerHelper(base::WeakPtr service) + : service_(std::move(service)), -+ task_runner_(base::ThreadTaskRunnerHandle::Get()) { ++ task_runner_(base::SequencedTaskRunnerHandle::Get()) { + DETACH_FROM_SEQUENCE(sequence_checker_); + } + -+ BlockingTaskHelper(const BlockingTaskHelper&) = delete; -+ BlockingTaskHelper& operator=(const BlockingTaskHelper&) = delete; ++ BlockingTaskRunnerHelper(const BlockingTaskRunnerHelper&) = delete; ++ BlockingTaskRunnerHelper& operator=(const BlockingTaskRunnerHelper&) = delete; + -+ ~BlockingTaskHelper() = default; ++ ~BlockingTaskRunnerHelper() = default; + + void Start() { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); -+ base::ScopedBlockingCall scoped_blocking_call( -+ FROM_HERE, base::BlockingType::MAY_BLOCK); + + 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)) != ++ 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) { ++ 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, + base::BindOnce(&HidServiceFido::FirstEnumerationComplete, service_)); + } + ++ 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); ++ + 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::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), + 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)); + } + + void OnDeviceRemoved(std::string device_node) { ++ 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)); + } + -+private: + SEQUENCE_CHECKER(sequence_checker_); + + // This weak pointer is only valid when checked on this task runner. + base::WeakPtr service_; + scoped_refptr task_runner_; +}; + +HidServiceFido::HidServiceFido() -+ : task_runner_(base::ThreadTaskRunnerHandle::Get()), -+ blocking_task_runner_( ++ : blocking_task_runner_( + base::ThreadPool::CreateSequencedTaskRunner(kBlockingTaskTraits)), -+ weak_factory_(this), helper_(std::make_unique( -+ weak_factory_.GetWeakPtr())) { ++ helper_(nullptr, base::OnTaskRunnerDeleter(blocking_task_runner_)) { ++ // We need to properly initialize |blocking_task_helper_| here because we need ++ // |weak_factory_| to be created first. ++ helper_.reset(new BlockingTaskRunnerHelper(weak_factory_.GetWeakPtr())); + blocking_task_runner_->PostTask( -+ FROM_HERE, -+ base::BindOnce(&BlockingTaskHelper::Start, base::Unretained(helper_.get()))); ++ FROM_HERE, base::BindOnce(&BlockingTaskRunnerHelper::Start, ++ base::Unretained(helper_.get()))); +} + -+HidServiceFido::~HidServiceFido() { -+ blocking_task_runner_->DeleteSoon(FROM_HERE, helper_.release()); -+} ++HidServiceFido::~HidServiceFido() = default; + +base::WeakPtr HidServiceFido::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + -+void HidServiceFido::Connect(const std::string &device_guid, -+ bool allow_protected_reports, -+ bool allow_fido_reports, -+ ConnectCallback callback) { ++void HidServiceFido::Connect(const std::string& device_guid, ++ bool allow_protected_reports, ++ bool allow_fido_reports, ++ ConnectCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + -+ const auto &map_entry = devices().find(device_guid); ++ const auto& map_entry = devices().find(device_guid); + if (map_entry == devices().end()) { -+ base::ThreadTaskRunnerHandle::Get()->PostTask( ++ base::SequencedTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(std::move(callback), nullptr)); + return; + } -+ + scoped_refptr device_info = map_entry->second; + -+ auto params = std::make_unique(device_info, std::move(callback)); -+ ++// 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)); + scoped_refptr blocking_task_runner = + params->blocking_task_runner; + blocking_task_runner->PostTask( -+ FROM_HERE, base::BindOnce(&OpenOnBlockingThread, std::move(params))); ++ 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) { ++ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE, ++ base::BlockingType::MAY_BLOCK); ++ scoped_refptr task_runner = params->task_runner; ++ ++ base::FilePath device_path(params->device_info->device_node()); ++ base::File device_file; ++ int flags = ++ base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_WRITE; ++ device_file.Initialize(device_path, flags); ++ if (!device_file.IsValid()) { ++ base::File::Error file_error = device_file.error_details(); ++ ++ if (file_error == base::File::FILE_ERROR_ACCESS_DENIED) { ++ HID_LOG(EVENT) ++ << "Access denied opening device read-write, trying read-only."; ++ flags = base::File::FLAG_OPEN | base::File::FLAG_READ; ++ device_file.Initialize(device_path, flags); ++ } ++ } ++ if (!device_file.IsValid()) { ++ HID_LOG(EVENT) << "Failed to open '" << params->device_info->device_node() ++ << "': " ++ << base::File::ErrorToString(device_file.error_details()); ++ task_runner->PostTask(FROM_HERE, ++ base::BindOnce(std::move(params->callback), nullptr)); ++ return; ++ } ++ if (!terrible_ping_kludge(device_file.GetPlatformFile(), params->device_info->device_node())) { ++ HID_LOG(EVENT) << "Failed to ping " << params->device_info->device_node(); ++ task_runner->PostTask(FROM_HERE, base::BindOnce(std::move(params->callback), nullptr)); ++ return; ++ } ++ params->fd.reset(device_file.TakePlatformFile()); ++ ++ task_runner->PostTask(FROM_HERE, base::BindOnce(&HidServiceFido::FinishOpen, ++ std::move(params))); ++} ++ ++#endif // BUILDFLAG(IS_CHROMEOS_ASH) ++ ++// static ++void HidServiceFido::FinishOpen(std::unique_ptr params) { ++ DCHECK(params->fd.is_valid()); ++ ++ if (!base::SetNonBlocking(params->fd.get())) { ++ HID_PLOG(DEBUG) << "Failed to set the non-blocking flag on the device fd"; ++ std::move(params->callback).Run(nullptr); ++ return; ++ } ++ ++ std::move(params->callback) ++ .Run(base::MakeRefCounted( ++ std::move(params->device_info), std::move(params->fd), ++ std::move(params->blocking_task_runner), ++ params->allow_protected_reports, params->allow_fido_reports)); +} + -+} // namespace device ++} // namespace device diff --git a/www/chromium/files/patch-services_device_hid_hid__service__fido.h b/www/chromium/files/patch-services_device_hid_hid__service__fido.h index 77e12e42fe1c..c5af55c5d3c5 100644 --- a/www/chromium/files/patch-services_device_hid_hid__service__fido.h +++ b/www/chromium/files/patch-services_device_hid_hid__service__fido.h @@ -1,46 +1,68 @@ ---- services/device/hid/hid_service_fido.h.orig 2022-02-07 13:39:41 UTC +--- services/device/hid/hid_service_fido.h.orig 2022-10-28 16:39:00 UTC +++ services/device/hid/hid_service_fido.h -@@ -0,0 +1,43 @@ -+// Copyright 2020 The Chromium Authors. All rights reserved. +@@ -0,0 +1,65 @@ ++// 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. + -+#ifndef SERVICE_DEVICE_HID_HID_SERVICE_FIDO_H_ -+#define SERVICE_DEVICE_HID_HID_SERVICE_FIDO_H_ ++#ifndef SERVICES_DEVICE_HID_HID_SERVICE_LINUX_H_ ++#define SERVICES_DEVICE_HID_HID_SERVICE_LINUX_H_ + -+#include ++#include + -+#include "base/memory/ref_counted.h" ++#include "base/compiler_specific.h" ++#include "base/files/scoped_file.h" +#include "base/memory/weak_ptr.h" ++#include "base/task/sequenced_task_runner.h" ++#include "build/build_config.h" ++#include "build/chromeos_buildflags.h" ++#include "services/device/hid/hid_device_info.h" +#include "services/device/hid/hid_service.h" + +namespace device { + +class HidServiceFido : public HidService { -+public: ++ public: + HidServiceFido(); -+ -+ HidServiceFido(const HidServiceFido&) = delete; -+ HidServiceFido& operator=(const HidServiceFido&) = delete; -+ ++ HidServiceFido(HidServiceFido&) = delete; ++ HidServiceFido& operator=(HidServiceFido&) = delete; + ~HidServiceFido() override; + -+ void Connect(const std::string &device_guid, ++ // HidService: ++ void Connect(const std::string& device_id, + bool allow_protected_reports, + bool allow_fido_reports, -+ ConnectCallback connect) override; ++ ConnectCallback callback) override; + base::WeakPtr GetWeakPtr() override; + -+private: -+ class BlockingTaskHelper; -+ const scoped_refptr task_runner_; ++ private: ++ struct ConnectParams; ++ class BlockingTaskRunnerHelper; ++ ++// These functions implement the process of locating, requesting access to and ++// opening a device. Because this operation crosses multiple threads these ++// functions are static and the necessary parameters are passed as a single ++// struct. ++#if BUILDFLAG(IS_CHROMEOS_ASH) ++ static void OnPathOpenComplete(std::unique_ptr params, ++ base::ScopedFD fd); ++ static void OnPathOpenError(const std::string& device_path, ++ ConnectCallback callback, ++ const std::string& error_name, ++ const std::string& error_message); ++#else ++ static void OpenOnBlockingThread(std::unique_ptr params); ++#endif ++ static void FinishOpen(std::unique_ptr params); ++ + const scoped_refptr blocking_task_runner_; -+ base::WeakPtrFactory weak_factory_; ++ + // |helper_| lives on the sequence |blocking_task_runner_| posts to and holds + // a weak reference back to the service that owns it. -+ std::unique_ptr helper_; ++ std::unique_ptr helper_; ++ base::WeakPtrFactory weak_factory_{this}; +}; + -+} // namespace device ++} // namespace device + -+#endif // SERVICE_DEVICE_HID_HID_SERVICE_FIDO_H_ ++#endif // SERVICES_DEVICE_HID_HID_SERVICE_LINUX_H_