fix: create singleton pipename from user & executable (#34139)

* fix: create singleton pipename from user & executable

* fix: use process id & main thread id for pipe name

* fix: write rand to file using WIN method

* fix: remove file rand, add user_name to pipe

* chore: style fixes, shorten program_name & user_name

* fix: remove user_name
This commit is contained in:
Keeley Hammond 2022-05-10 13:24:40 -07:00 committed by GitHub
parent 7f5346b954
commit 627c2987ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -282,10 +282,20 @@ index be2c417c07a4206fac4a9a6c03e516fd0493c942..78f74b0b21242553b6af98628dc48190
return PROCESS_NOTIFIED; return PROCESS_NOTIFIED;
} }
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d05018b627 100644 index ec725b44296266bea1a51aea889463a0bba8449c..6355e5c73ba9df9bdb9ff48205d909dca04470f1 100644
--- a/chrome/browser/process_singleton_win.cc --- a/chrome/browser/process_singleton_win.cc
+++ b/chrome/browser/process_singleton_win.cc +++ b/chrome/browser/process_singleton_win.cc
@@ -21,6 +21,7 @@ @@ -13,14 +13,17 @@
#include "base/command_line.h"
#include "base/debug/activity_tracker.h"
#include "base/files/file_path.h"
+#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/process/process.h"
#include "base/process/process_info.h"
+#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/time/time.h" #include "base/time/time.h"
@ -293,11 +303,10 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0
#include "base/trace_event/base_tracing.h" #include "base/trace_event/base_tracing.h"
#include "base/win/registry.h" #include "base/win/registry.h"
#include "base/win/scoped_handle.h" #include "base/win/scoped_handle.h"
@@ -45,6 +46,14 @@ @@ -45,6 +48,13 @@
namespace { namespace {
const char kLockfile[] = "lockfile"; const char kLockfile[] = "lockfile";
+const LPCWSTR kPipeName = L"\\\\.\\pipe\\electronAckPipe";
+const DWORD kPipeTimeout = 10000; +const DWORD kPipeTimeout = 10000;
+const DWORD kMaxMessageLength = 32 * 1024; +const DWORD kMaxMessageLength = 32 * 1024;
+ +
@ -308,7 +317,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0
// A helper class that acquires the given |mutex| while the AutoLockMutex is in // A helper class that acquires the given |mutex| while the AutoLockMutex is in
// scope. // scope.
@@ -80,10 +89,12 @@ BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) { @@ -80,10 +90,12 @@ BOOL CALLBACK BrowserWindowEnumeration(HWND window, LPARAM param) {
bool ParseCommandLine(const COPYDATASTRUCT* cds, bool ParseCommandLine(const COPYDATASTRUCT* cds,
base::CommandLine* parsed_command_line, base::CommandLine* parsed_command_line,
@ -323,7 +332,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0
static const int min_message_size = 7; static const int min_message_size = 7;
if (cds->cbData < min_message_size * sizeof(wchar_t) || if (cds->cbData < min_message_size * sizeof(wchar_t) ||
cds->cbData % sizeof(wchar_t) != 0) { cds->cbData % sizeof(wchar_t) != 0) {
@@ -133,11 +144,82 @@ bool ParseCommandLine(const COPYDATASTRUCT* cds, @@ -133,11 +145,82 @@ bool ParseCommandLine(const COPYDATASTRUCT* cds,
const std::wstring cmd_line = const std::wstring cmd_line =
msg.substr(second_null + 1, third_null - second_null); msg.substr(second_null + 1, third_null - second_null);
*parsed_command_line = base::CommandLine::FromString(cmd_line); *parsed_command_line = base::CommandLine::FromString(cmd_line);
@ -406,7 +415,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0
bool ProcessLaunchNotification( bool ProcessLaunchNotification(
const ProcessSingleton::NotificationCallback& notification_callback, const ProcessSingleton::NotificationCallback& notification_callback,
UINT message, UINT message,
@@ -151,16 +233,35 @@ bool ProcessLaunchNotification( @@ -151,16 +234,35 @@ bool ProcessLaunchNotification(
// Handle the WM_COPYDATA message from another process. // Handle the WM_COPYDATA message from another process.
const COPYDATASTRUCT* cds = reinterpret_cast<COPYDATASTRUCT*>(lparam); const COPYDATASTRUCT* cds = reinterpret_cast<COPYDATASTRUCT*>(lparam);
@ -446,7 +455,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0
return true; return true;
} }
@@ -261,9 +362,13 @@ bool ProcessSingleton::EscapeVirtualization( @@ -261,9 +363,13 @@ bool ProcessSingleton::EscapeVirtualization(
ProcessSingleton::ProcessSingleton( ProcessSingleton::ProcessSingleton(
const std::string& program_name, const std::string& program_name,
const base::FilePath& user_data_dir, const base::FilePath& user_data_dir,
@ -461,16 +470,26 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0
program_name_(program_name), program_name_(program_name),
is_app_sandboxed_(is_app_sandboxed), is_app_sandboxed_(is_app_sandboxed),
is_virtualized_(false), is_virtualized_(false),
@@ -278,6 +383,37 @@ ProcessSingleton::~ProcessSingleton() { @@ -278,6 +384,47 @@ ProcessSingleton::~ProcessSingleton() {
::CloseHandle(lock_file_); ::CloseHandle(lock_file_);
} }
+void ReadAck(const ProcessSingleton::NotificationAckCallback& ack_callback) { +void ReadAck(const ProcessSingleton::NotificationAckCallback& ack_callback,
+ const std::string program_name,
+ base::FilePath& user_data_dir) {
+ // We are reading the ack from the first instance. + // We are reading the ack from the first instance.
+ // First, wait for the pipe. + // First, wait for the pipe.
+ ::WaitNamedPipe(kPipeName, NMPWAIT_USE_DEFAULT_WAIT); + HWND remote_window = chrome::FindRunningChromeWindow(user_data_dir);
+ DWORD process_id;
+ DWORD thread_id = GetWindowThreadProcessId(remote_window, &process_id);
+ std::string identifier = base::NumberToString(process_id) +
+ base::NumberToString(thread_id);
+ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + identifier +
+ program_name);
+ const LPCWSTR w_pipe_name = pipe_name.c_str();
+ ::WaitNamedPipe(w_pipe_name, NMPWAIT_USE_DEFAULT_WAIT);
+ +
+ HANDLE read_ack_pipe = ::CreateFile(kPipeName, + HANDLE read_ack_pipe = ::CreateFile(w_pipe_name,
+ GENERIC_READ, + GENERIC_READ,
+ FILE_SHARE_READ, + FILE_SHARE_READ,
+ NULL, + NULL,
@ -499,23 +518,31 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0
// Code roughly based on Mozilla. // Code roughly based on Mozilla.
ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
TRACE_EVENT0("startup", "ProcessSingleton::NotifyOtherProcess"); TRACE_EVENT0("startup", "ProcessSingleton::NotifyOtherProcess");
@@ -290,8 +426,9 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { @@ -290,8 +437,9 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
return PROCESS_NONE; return PROCESS_NONE;
} }
- switch (chrome::AttemptToNotifyRunningChrome(remote_window_)) { - switch (chrome::AttemptToNotifyRunningChrome(remote_window_)) {
+ switch (chrome::AttemptToNotifyRunningChrome(remote_window_, additional_data_)) { + switch (chrome::AttemptToNotifyRunningChrome(remote_window_, additional_data_)) {
case chrome::NOTIFY_SUCCESS: case chrome::NOTIFY_SUCCESS:
+ ReadAck(notification_ack_callback_); + ReadAck(notification_ack_callback_, program_name_, user_data_dir_);
return PROCESS_NOTIFIED; return PROCESS_NOTIFIED;
case chrome::NOTIFY_FAILED: case chrome::NOTIFY_FAILED:
remote_window_ = NULL; remote_window_ = NULL;
@@ -429,6 +566,18 @@ bool ProcessSingleton::Create() { @@ -429,6 +577,26 @@ bool ProcessSingleton::Create() {
<< "Lock file can not be created! Error code: " << error; << "Lock file can not be created! Error code: " << error;
if (lock_file_ != INVALID_HANDLE_VALUE) { if (lock_file_ != INVALID_HANDLE_VALUE) {
+ // We are the first instance. Create a pipe to send out ack data. + // We are the first instance. Create a pipe to send out ack data.
+ ack_pipe_ = ::CreateNamedPipe(kPipeName, + // Create a per-process pipename using a combination of the
+ // username, process id, thread id, and program name. Pipe names max
+ // at 256 characters, can include any character other than a backslash
+ std::string identifier = base::NumberToString(::GetCurrentProcessId()) +
+ base::NumberToString(::GetCurrentThreadId());
+ std::wstring pipe_name = base::UTF8ToWide("\\\\.\\pipe\\" + identifier +
+ program_name_);
+ const LPCWSTR w_pipe_name = pipe_name.c_str();
+ ack_pipe_ = ::CreateNamedPipe(w_pipe_name,
+ PIPE_ACCESS_OUTBOUND, + PIPE_ACCESS_OUTBOUND,
+ PIPE_TYPE_BYTE | PIPE_REJECT_REMOTE_CLIENTS, + PIPE_TYPE_BYTE | PIPE_REJECT_REMOTE_CLIENTS,
+ PIPE_UNLIMITED_INSTANCES, + PIPE_UNLIMITED_INSTANCES,
@ -529,7 +556,7 @@ index ec725b44296266bea1a51aea889463a0bba8449c..3bb74c08cd78b11cd9925a6bfafc62d0
// Set the window's title to the path of our user data directory so // Set the window's title to the path of our user data directory so
// other Chrome instances can decide if they should forward to us. // other Chrome instances can decide if they should forward to us.
TRACE_EVENT0("startup", "ProcessSingleton::Create:CreateWindow"); TRACE_EVENT0("startup", "ProcessSingleton::Create:CreateWindow");
@@ -456,6 +605,7 @@ bool ProcessSingleton::Create() { @@ -456,6 +624,7 @@ bool ProcessSingleton::Create() {
} }
void ProcessSingleton::Cleanup() { void ProcessSingleton::Cleanup() {