From nobody Sat Oct 29 09:29:21 2022 X-Original-To: dev-commits-ports-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4MzvJ20Y7Nz4gYRS; Sat, 29 Oct 2022 09:29:22 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4MzvJ20BCJz3FZV; Sat, 29 Oct 2022 09:29:22 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1667035762; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=A+q6bJA7zc8dGhWidUPEW21XHa8M5cjM1aNHpQBzJtQ=; b=teFVlQeLJjILmBWt8eznOqVhewdp+ZXDl9CZkJy07xxQfMkg58bpDnw0UJ+5UwgTFpTUeE 1H7vvo0+rDW4o9v3NzlbfOMCEqEKr7pfry6taU05qk1p7htkhEd1G9gN+iolHFAiqzMJlX oq2AC7/5B34DPaP4XeNyIR+xcR5p4FMQBwage/AY62p6rSUjLwyULUqAXmKagD2tOnNZma ysdmT/fbFcmW4Bk4eT9BQ52SI/haEiU+fM6MjBZoMmWJnzzS/r+h7MjZNdptOvNrewMEmr 8xkE3CUEPdwLz2xzLt8Ijv+7HRYMli9fg68wbskHIraLWoPiff4dw1MGFqwL1w== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4MzvJ16DWXz1C77; Sat, 29 Oct 2022 09:29:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 29T9TLit069609; Sat, 29 Oct 2022 09:29:21 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 29T9TLuJ069608; Sat, 29 Oct 2022 09:29:21 GMT (envelope-from git) Date: Sat, 29 Oct 2022 09:29:21 GMT Message-Id: <202210290929.29T9TLuJ069608@gitrepo.freebsd.org> To: ports-committers@FreeBSD.org, dev-commits-ports-all@FreeBSD.org, dev-commits-ports-main@FreeBSD.org From: Rene Ladan Subject: git: dcf58b2c13fd - main - www/chromium: update to 107.0.5304.87 List-Id: Commit messages for all branches of the ports repository List-Archive: https://lists.freebsd.org/archives/dev-commits-ports-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-ports-all@freebsd.org X-BeenThere: dev-commits-ports-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: rene X-Git-Repository: ports X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: dcf58b2c13fde2acd01d61020abb85a678686882 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1667035762; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=A+q6bJA7zc8dGhWidUPEW21XHa8M5cjM1aNHpQBzJtQ=; b=MuXxMKb29K/qR3zKRMFjOoJ52ZD3bMa5Z/mpKpC6GclbuVgtSddITDoxB8fT8qdhYpEU82 pAHzVXPFz3h4ogmrEnsOsWpOOS2785FRAuudJaf5VE5YC+anlmtKcd0u27KaedVmz345NX 8WloyMEen/eQXS6T5CvUv72wqBpZJ/OecarhQuNiNGVcPKIC1cEsEMK+Ec19/uB7BiGC2F mIQtnHZfVYEDw3svH5iXPDb/3ffVkbWTVZq/wksA5+eVMBorEQyhEwo+3rxCiqSTEx+z1U xHUpjmwHpt5qaM4tb+NWeKxeWeIGumTQaj+seg6awsdPb8eRB5U8aUN3dKMqsg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1667035762; a=rsa-sha256; cv=none; b=kkUfe25fdBtEGn15TTii+uTo6OjrzoLUMmh7RaTkkx85Do6slOlvwt8JyMlgzy7rCuNUPp 9q4Zej5KtUcv9jCciPBGRfsomg8Q9XUQ3xxwAhY6MqF6w0HyDXKP5tLACZnnqC/mNFLzE3 Z/3kTnp5uLBZI4IUBXikaxhCReywr9m0yspuYVfNI8bwvdowSqESrMEr8H9O51HEbMHKKm 5bOELpqhvQvMnV60a35N3z+EgCeKhYbr6lfjkXLp3piOkFMrRfpSI3RcuFoXoQcHvedfZK Ep2Vw6kaHpdNCHc08y940SdE3CMnhVOiIE/cedhb5jGMvhPhhk+sb5Mw0+nYEw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by rene: URL: https://cgit.FreeBSD.org/ports/commit/?id=dcf58b2c13fde2acd01d61020abb85a678686882 commit dcf58b2c13fde2acd01d61020abb85a678686882 Author: Robert Nagy AuthorDate: 2022-10-29 05:54:18 +0000 Commit: Rene Ladan CommitDate: 2022-10-29 09:25:45 +0000 www/chromium: update to 107.0.5304.87 This also has partial support for FIDO U2F, but it does not work yet. Security: https://vuxml.freebsd.org/freebsd/1225c888-56ea-11ed-b5c3-3065ec8fd3ec.html --- www/chromium/Makefile | 2 +- www/chromium/distinfo | 14 +- .../patch-content_gpu_gpu__sandbox__hook__linux.cc | 12 +- ...ch-services_device_hid_hid__connection__fido.cc | 141 ++++++---- ...tch-services_device_hid_hid__connection__fido.h | 55 ++-- ...patch-services_device_hid_hid__service__fido.cc | 307 +++++++++++++-------- .../patch-services_device_hid_hid__service__fido.h | 64 +++-- 7 files changed, 353 insertions(+), 242 deletions(-) diff --git a/www/chromium/Makefile b/www/chromium/Makefile index 520947c339a6..c6bae9d7775a 100644 --- a/www/chromium/Makefile +++ b/www/chromium/Makefile @@ -1,5 +1,5 @@ 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 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,4 +1,4 @@ ---- 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)); @@ -8,7 +8,7 @@ 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; } @@ -19,7 +19,7 @@ // 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); } } @@ -27,7 +27,7 @@ } bool LoadAmdGpuLibraries() { -@@ -547,12 +551,14 @@ void LoadV4L2Libraries( +@@ -550,12 +554,14 @@ void LoadV4L2Libraries( } void LoadChromecastV4L2Libraries() { @@ -42,7 +42,7 @@ } bool LoadLibrariesForGpu( -@@ -580,6 +586,7 @@ bool LoadLibrariesForGpu( +@@ -583,6 +589,7 @@ bool LoadLibrariesForGpu( return true; } @@ -50,7 +50,7 @@ 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; } 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,53 +1,60 @@ ---- 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, @@ -64,13 +71,20 @@ + 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, @@ -87,22 +101,24 @@ + 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--; + } @@ -132,69 +148,74 @@ + + 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,35 +1,41 @@ ---- 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; + @@ -42,19 +48,16 @@ + 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,7 +1,7 @@ ---- 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. + @@ -10,76 +10,45 @@ +#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; @@ -95,8 +64,8 @@ + /* 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; @@ -104,7 +73,7 @@ + } + 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; @@ -113,7 +82,7 @@ + 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; + } @@ -129,31 +98,6 @@ + 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) @@ -178,25 +122,46 @@ + 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; @@ -204,17 +169,17 @@ + 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)"; + @@ -224,7 +189,7 @@ + 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; + } @@ -252,11 +217,16 @@ + 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( @@ -265,19 +235,19 @@ + 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. @@ -286,45 +256,140 @@ +}; + +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); ++ *** 15 LINES SKIPPED ***