// 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.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

// On Linux, when the user tries to launch a second copy of chrome, we check
// for a socket in the user's profile directory.  If the socket file is open we
// send a message to the first chrome browser process with the current
// directory and second process command line flags.  The second process then
// exits.
//
// Because many networked filesystem implementations do not support unix domain
// sockets, we create the socket in a temporary directory and create a symlink
// in the profile. This temporary directory is no longer bound to the profile,
// and may disappear across a reboot or login to a separate session. To bind
// them, we store a unique cookie in the profile directory, which must also be
// present in the remote directory to connect. The cookie is checked both before
// and after the connection. /tmp is sticky, and different Chrome sessions use
// different cookies. Thus, a matching cookie before and after means the
// connection was to a directory with a valid cookie.
//
// We also have a lock file, which is a symlink to a non-existent destination.
// The destination is a string containing the hostname and process id of
// chrome's browser process, eg. "SingletonLock -> example.com-9156".  When the
// first copy of chrome exits it will delete the lock file on shutdown, so that
// a different instance on a different host may then use the profile directory.
//
// If writing to the socket fails, the hostname in the lock is checked to see if
// another instance is running a different host using a shared filesystem (nfs,
// etc.) If the hostname differs an error is displayed and the second process
// exits.  Otherwise the first process (if any) is killed and the second process
// starts as normal.
//
// When the second process sends the current directory and command line flags to
// the first process, it waits for an ACK message back from the first process
// for a certain time. If there is no ACK message back in time, then the first
// process will be considered as hung for some reason. The second process then
// retrieves the process id from the symbol link and kills it by sending
// SIGKILL. Then the second process starts as normal.

#include "chrome/browser/process_singleton.h"

#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stddef.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>

#include <cstring>
#include <memory>
#include <set>
#include <string>
#include <type_traits>

#include "base/base_paths.h"
#include "base/command_line.h"
#include "base/containers/unique_ptr_adapters.h"
#include "base/files/file_descriptor_watcher_posix.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/path_service.h"
#include "base/posix/eintr_wrapper.h"
#include "base/posix/safe_strerror.h"
#include "base/rand_util.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/strings/utf_string_conversions.h"
#include "base/task/sequenced_task_runner_helpers.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/platform_thread.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/process_singleton_internal.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/process_singleton_lock_posix.h"
#include "chrome/grit/branded_strings.h"
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/network_interfaces.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/scoped_startup_resource_bundle.h"

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include "chrome/browser/ui/process_singleton_dialog_linux.h"
#endif

using content::BrowserThread;

namespace {

#if BUILDFLAG(IS_MAC)
// In order to allow longer paths for the singleton socket's filesystem node,
// provide an "oversized" sockaddr_un-equivalent with a larger sun_path member.
// sockaddr_un in the SDK has sun_path[104], which is too confined for the
// singleton socket's path. The kernel will accept a sockaddr structure up to
// SOCK_MAXADDRLEN (255) bytes long. This structure makes all of that space
// available, effectively allowing sun_path[253]. Although shorter than
// PATH_MAX (1024), this will hopefully be long enough. Many systems support an
// extension like this, but it's not entirely portable. In this case, the OS
// vendor has said that the behavior is stable. Learn more at SetupSockAddr.
struct SockaddrUn {
  decltype(sockaddr_un::sun_len) sun_len;
  decltype(sockaddr_un::sun_family) sun_family;
  std::remove_extent_t<decltype(sockaddr_un::sun_path)>
      sun_path[SOCK_MAXADDRLEN - offsetof(sockaddr_un, sun_path)];
};
#else
// On other platforms without a demonstrated need for paths longer than
// sockaddr_un::sun_path, just do the portable thing.
using SockaddrUn = sockaddr_un;
#endif

// Timeout for the current browser process to respond. 20 seconds should be
// enough.
const int kTimeoutInSeconds = 20;
// Number of retries to notify the browser. 20 retries over 20 seconds = 1 try
// per second.
const int kRetryAttempts = 20;
const char kStartToken[] = "START";
const char kACKToken[] = "ACK";
const char kShutdownToken[] = "SHUTDOWN";
const char kTokenDelimiter = '\0';
const int kMaxMessageLength = 32 * 1024;
const int kMaxACKMessageLength = std::size(kShutdownToken) - 1;

bool g_disable_prompt = false;
bool g_skip_is_chrome_process_check = false;
bool g_user_opted_unlock_in_use_profile = false;

// Set the close-on-exec bit on a file descriptor.
// Returns 0 on success, -1 on failure.
int SetCloseOnExec(int fd) {
  int flags = fcntl(fd, F_GETFD, 0);
  if (-1 == flags)
    return flags;
  if (flags & FD_CLOEXEC)
    return 0;
  return fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
}

// Close a socket and check return value.
void CloseSocket(int fd) {
  int rv = IGNORE_EINTR(close(fd));
  DPCHECK(rv == 0) << "Error closing socket";
}

// Write a message to a socket fd.
bool WriteToSocket(int fd, const char *message, size_t length) {
  DCHECK(message);
  DCHECK(length);
  size_t bytes_written = 0;
  do {
    ssize_t rv = HANDLE_EINTR(
        write(fd, message + bytes_written, length - bytes_written));
    if (rv < 0) {
      if (errno == EAGAIN || errno == EWOULDBLOCK) {
        // The socket shouldn't block, we're sending so little data.  Just give
        // up here, since NotifyOtherProcess() doesn't have an asynchronous api.
        LOG(ERROR) << "ProcessSingleton would block on write(), so it gave up.";
        return false;
      }
      PLOG(ERROR) << "write() failed";
      return false;
    }
    bytes_written += rv;
  } while (bytes_written < length);

  return true;
}

struct timeval TimeDeltaToTimeVal(const base::TimeDelta& delta) {
  struct timeval result;
  result.tv_sec = delta.InSeconds();
  result.tv_usec = delta.InMicroseconds() % base::Time::kMicrosecondsPerSecond;
  return result;
}

// Wait a socket for read for a certain timeout.
// Returns -1 if error occurred, 0 if timeout reached, > 0 if the socket is
// ready for read.
int WaitSocketForRead(int fd, const base::TimeDelta& timeout) {
  fd_set read_fds;
  struct timeval tv = TimeDeltaToTimeVal(timeout);

  FD_ZERO(&read_fds);
  FD_SET(fd, &read_fds);

  return HANDLE_EINTR(select(fd + 1, &read_fds, nullptr, nullptr, &tv));
}

// Read a message from a socket fd, with an optional timeout.
// If |timeout| <= 0 then read immediately.
// Return number of bytes actually read, or -1 on error.
ssize_t ReadFromSocket(int fd,
                       char* buf,
                       size_t bufsize,
                       const base::TimeDelta& timeout) {
  if (timeout.is_positive()) {
    int rv = WaitSocketForRead(fd, timeout);
    if (rv <= 0)
      return rv;
  }

  size_t bytes_read = 0;
  do {
    ssize_t rv = HANDLE_EINTR(read(fd, buf + bytes_read, bufsize - bytes_read));
    if (rv < 0) {
      if (errno != EAGAIN && errno != EWOULDBLOCK) {
        PLOG(ERROR) << "read() failed";
        return rv;
      } else {
        // It would block, so we just return what has been read.
        return bytes_read;
      }
    } else if (!rv) {
      // No more data to read.
      return bytes_read;
    } else {
      bytes_read += rv;
    }
  } while (bytes_read < bufsize);

  return bytes_read;
}

// Set up a sockaddr appropriate for messaging.
bool SetupSockAddr(const std::string& path,
                   SockaddrUn* addr,
                   socklen_t* socklen) {
  addr->sun_family = AF_UNIX;
#if BUILDFLAG(IS_MAC)
  // Allow the use of the entire length of sun_path, without reservation for a
  // NUL terminator. The socklen parameter to bind and connect encodes the
  // length of the sockaddr structure, and xnu does not require sun_path to be
  // NUL-terminated. This is not portable, but it’s OK on macOS, and allows
  // maximally-sized paths on a platform where the singleton socket path is
  // already long. 11.5 xnu-7195.141.2/bsd/kern/uipc_usrreq.c unp_bind,
  // unp_connect.
  if (path.length() > std::size(addr->sun_path))
    return false;

  // On input to the kernel, sun_len is ignored and overwritten by the value of
  // the passed-in socklen parameter. 11.5
  // xnu-7195.141.2/bsd/kern/uipc_syscalls.c getsockaddr[_s]; note that the
  // field is sa_len and not sun_len there because it occurs in generic code
  // referring to sockaddr before being specialized into sockaddr_un or any
  // other address family's sockaddr structure.
  //
  // Since the length needs to be computed for socklen anyway, just populate
  // sun_len correctly.
  addr->sun_len =
      offsetof(std::remove_pointer_t<decltype(addr)>, sun_path) + path.length();

  *socklen = addr->sun_len;
  memcpy(addr->sun_path, path.c_str(), path.length());
#else
  // The portable version: NUL-terminate sun_path and don’t touch sun_len (which
  // may not even exist).
  if (path.length() >= std::size(addr->sun_path))
    return false;
  *socklen = sizeof(*addr);
  base::strlcpy(addr->sun_path, path.c_str(), std::size(addr->sun_path));
#endif
  return true;
}

// Set up a socket appropriate for messaging.
int SetupSocketOnly() {
  int sock = socket(PF_UNIX, SOCK_STREAM, 0);
  PCHECK(sock >= 0) << "socket() failed";

  DCHECK(base::SetNonBlocking(sock)) << "Failed to make non-blocking socket.";
  int rv = SetCloseOnExec(sock);
  DCHECK_EQ(0, rv) << "Failed to set CLOEXEC on socket.";

  return sock;
}

// Set up a socket and sockaddr appropriate for messaging.
void SetupSocket(const std::string& path,
                 int* sock,
                 SockaddrUn* addr,
                 socklen_t* socklen) {
  *sock = SetupSocketOnly();
  CHECK(SetupSockAddr(path, addr, socklen)) << "Socket path too long: " << path;
}

// Read a symbolic link, return empty string if given path is not a symbol link.
base::FilePath ReadLink(const base::FilePath& path) {
  base::FilePath target;
  if (!base::ReadSymbolicLink(path, &target)) {
    // The only errno that should occur is ENOENT.
    if (errno != 0 && errno != ENOENT)
      PLOG(ERROR) << "readlink(" << path.value() << ") failed";
  }
  return target;
}

// Unlink a path. Return true on success.
bool UnlinkPath(const base::FilePath& path) {
  int rv = unlink(path.value().c_str());
  if (rv < 0 && errno != ENOENT)
    PLOG(ERROR) << "Failed to unlink " << path.value();

  return rv == 0;
}

// Create a symlink. Returns true on success.
bool SymlinkPath(const base::FilePath& target, const base::FilePath& path) {
  if (!base::CreateSymbolicLink(target, path)) {
    // Double check the value in case symlink suceeded but we got an incorrect
    // failure due to NFS packet loss & retry.
    int saved_errno = errno;
    if (ReadLink(path) != target) {
      // If we failed to create the lock, most likely another instance won the
      // startup race.
      errno = saved_errno;
      PLOG(ERROR) << "Failed to create " << path.value();
      return false;
    }
  }
  return true;
}

// Returns true if the user opted to unlock the profile.
bool DisplayProfileInUseError(const base::FilePath& lock_path,
                              const std::string& hostname,
                              int pid) {
  // Ensure there is an instance of ResourceBundle that is initialized for
  // localized string resource accesses.
  ui::ScopedStartupResourceBundle ensure_startup_resource_bundle;

  std::u16string error = l10n_util::GetStringFUTF16(
      IDS_PROFILE_IN_USE_POSIX, base::NumberToString16(pid),
      base::ASCIIToUTF16(hostname));
  LOG(ERROR) << error;

  if (g_disable_prompt)
    return g_user_opted_unlock_in_use_profile;

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  std::u16string relaunch_button_text =
      l10n_util::GetStringUTF16(IDS_PROFILE_IN_USE_LINUX_RELAUNCH);
  return ShowProcessSingletonDialog(error, relaunch_button_text);
#elif BUILDFLAG(IS_MAC)
  // On Mac, always usurp the lock.
  return true;
#else
  NOTREACHED();
#endif
}

bool IsChromeProcess(pid_t pid) {
  if (g_skip_is_chrome_process_check)
    return true;

  base::FilePath other_chrome_path(base::GetProcessExecutablePath(pid));
  return (!other_chrome_path.empty() &&
          other_chrome_path.BaseName() ==
              base::FilePath(chrome::kBrowserProcessExecutableName));
}

// A helper class to hold onto a socket.
class ScopedSocket {
 public:
  ScopedSocket() : fd_(-1) { Reset(); }
  ~ScopedSocket() { Close(); }
  int fd() { return fd_; }
  void Reset() {
    Close();
    fd_ = SetupSocketOnly();
  }
  void Close() {
    if (fd_ >= 0)
      CloseSocket(fd_);
    fd_ = -1;
  }
 private:
  int fd_;
};

// Returns a random string for uniquifying profile connections.
std::string GenerateCookie() {
  return base::NumberToString(base::RandUint64());
}

bool CheckCookie(const base::FilePath& path, const base::FilePath& cookie) {
  return (cookie == ReadLink(path));
}

bool ConnectSocket(ScopedSocket* socket,
                   const base::FilePath& socket_path,
                   const base::FilePath& cookie_path) {
  base::FilePath socket_target;
  if (base::ReadSymbolicLink(socket_path, &socket_target)) {
    // It's a symlink. Read the cookie.
    base::FilePath cookie = ReadLink(cookie_path);
    if (cookie.empty())
      return false;
    base::FilePath remote_cookie = socket_target.DirName().
                             Append(chrome::kSingletonCookieFilename);
    // Verify the cookie before connecting.
    if (!CheckCookie(remote_cookie, cookie))
      return false;
    // Now we know the directory was (at that point) created by the profile
    // owner. Try to connect.
    SockaddrUn addr;
    socklen_t socklen;
    if (!SetupSockAddr(socket_target.value(), &addr, &socklen)) {
      // If a sockaddr couldn't be initialized due to too long of a socket
      // path, we can be sure there isn't already a Chrome running with this
      // socket path, since it would have hit the CHECK() on the path length.
      return false;
    }
    int ret = HANDLE_EINTR(
        connect(socket->fd(), reinterpret_cast<sockaddr*>(&addr), socklen));
    if (ret != 0)
      return false;
    // Check the cookie again. We only link in /tmp, which is sticky, so, if the
    // directory is still correct, it must have been correct in-between when we
    // connected. POSIX, sadly, lacks a connectat().
    if (!CheckCookie(remote_cookie, cookie)) {
      socket->Reset();
      return false;
    }
    // Success!
    return true;
  } else if (errno == EINVAL) {
    // It exists, but is not a symlink (or some other error we detect
    // later). Just connect to it directly; this is an older version of Chrome.
    SockaddrUn addr;
    socklen_t socklen;
    if (!SetupSockAddr(socket_path.value(), &addr, &socklen)) {
      // If a sockaddr couldn't be initialized due to too long of a socket
      // path, we can be sure there isn't already a Chrome running with this
      // socket path, since it would have hit the CHECK() on the path length.
      return false;
    }
    int ret = HANDLE_EINTR(
        connect(socket->fd(), reinterpret_cast<sockaddr*>(&addr), socklen));
    return (ret == 0);
  } else {
    // File is missing, or other error.
    if (errno != ENOENT)
      PLOG(ERROR) << "readlink failed";
    return false;
  }
}

#if BUILDFLAG(IS_MAC)
bool ReplaceOldSingletonLock(const base::FilePath& symlink_content,
                             const base::FilePath& lock_path) {
  // Try taking an flock(2) on the file. Failure means the lock is taken so we
  // should quit.
  base::ScopedFD lock_fd(HANDLE_EINTR(
      open(lock_path.value().c_str(), O_RDWR | O_CREAT | O_SYMLINK, 0644)));
  if (!lock_fd.is_valid()) {
    PLOG(ERROR) << "Could not open singleton lock";
    return false;
  }

  int rc = HANDLE_EINTR(flock(lock_fd.get(), LOCK_EX | LOCK_NB));
  if (rc == -1) {
    if (errno == EWOULDBLOCK) {
      LOG(ERROR) << "Singleton lock held by old process.";
    } else {
      PLOG(ERROR) << "Error locking singleton lock";
    }
    return false;
  }

  // Successfully taking the lock means we can replace it with the a new symlink
  // lock. We never flock() the lock file from now on. I.e. we assume that an
  // old version of Chrome will not run with the same user data dir after this
  // version has run.
  if (!base::DeleteFile(lock_path)) {
    PLOG(ERROR) << "Could not delete old singleton lock.";
    return false;
  }

  return SymlinkPath(symlink_content, lock_path);
}
#endif  // BUILDFLAG(IS_MAC)

}  // namespace

///////////////////////////////////////////////////////////////////////////////
// ProcessSingleton::LinuxWatcher
// A helper class for a Linux specific implementation of the process singleton.
// This class sets up a listener on the singleton socket and handles parsing
// messages that come in on the singleton socket.
class ProcessSingleton::LinuxWatcher
    : public base::RefCountedThreadSafe<ProcessSingleton::LinuxWatcher,
                                        BrowserThread::DeleteOnIOThread> {
 public:
  // A helper class to read message from an established socket.
  class SocketReader {
   public:
    SocketReader(ProcessSingleton::LinuxWatcher* parent,
                 scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
                 int fd)
        : parent_(parent),
          ui_task_runner_(ui_task_runner),
          fd_(fd),
          bytes_read_(0) {
      DCHECK_CURRENTLY_ON(BrowserThread::IO);
      // Wait for reads.
      fd_watch_controller_ = base::FileDescriptorWatcher::WatchReadable(
          fd, base::BindRepeating(&SocketReader::OnSocketCanReadWithoutBlocking,
                                  base::Unretained(this)));
      // If we haven't completed in a reasonable amount of time, give up.
      timer_.Start(FROM_HERE, base::Seconds(kTimeoutInSeconds), this,
                   &SocketReader::CleanupAndDeleteSelf);
    }

    SocketReader(const SocketReader&) = delete;
    SocketReader& operator=(const SocketReader&) = delete;

    ~SocketReader() { CloseSocket(fd_); }

    // Finish handling the incoming message by optionally sending back an ACK
    // message and removing this SocketReader.
    void FinishWithACK(const char *message, size_t length);

   private:
    void OnSocketCanReadWithoutBlocking();

    void CleanupAndDeleteSelf() {
      DCHECK_CURRENTLY_ON(BrowserThread::IO);

      parent_->RemoveSocketReader(this);
      // We're deleted beyond this point.
    }

    // Controls watching |fd_|.
    std::unique_ptr<base::FileDescriptorWatcher::Controller>
        fd_watch_controller_;

    // The ProcessSingleton::LinuxWatcher that owns us.
    const raw_ptr<ProcessSingleton::LinuxWatcher> parent_;

    // A reference to the UI task runner.
    scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;

    // The file descriptor we're reading.
    const int fd_;

    // Store the message in this buffer.
    char buf_[kMaxMessageLength];

    // Tracks the number of bytes we've read in case we're getting partial
    // reads.
    size_t bytes_read_;

    base::OneShotTimer timer_;
  };

  // We expect to only be constructed on the UI thread.
  explicit LinuxWatcher(ProcessSingleton* parent)
      : ui_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()),
        parent_(parent) {}

  LinuxWatcher(const LinuxWatcher&) = delete;
  LinuxWatcher& operator=(const LinuxWatcher&) = delete;

  // Start listening for connections on the socket.  This method should be
  // called from the IO thread.
  void StartListening(int socket);

  // This method determines if we should use the same process and if we should,
  // opens a new browser tab.  This runs on the UI thread.
  // |reader| is for sending back ACK message.
  void HandleMessage(const std::string& current_dir,
                     const std::vector<std::string>& argv,
                     SocketReader* reader);

  // Called when the ProcessSingleton that owns this class is about to be
  // destroyed to remove the raw_ptr reference to it and prevent a leaked
  // dangling pointer.
  void OnEminentProcessSingletonDestruction() { parent_ = nullptr; }

 private:
  friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
  friend class base::DeleteHelper<ProcessSingleton::LinuxWatcher>;

  ~LinuxWatcher() {
    DCHECK_CURRENTLY_ON(BrowserThread::IO);
  }

  void OnSocketCanReadWithoutBlocking(int socket);

  // Removes and deletes the SocketReader.
  void RemoveSocketReader(SocketReader* reader);

  std::unique_ptr<base::FileDescriptorWatcher::Controller> socket_watcher_;

  // A reference to the UI message loop (i.e., the message loop we were
  // constructed on).
  scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;

  // The ProcessSingleton that owns us.
  raw_ptr<ProcessSingleton> parent_;

  std::set<std::unique_ptr<SocketReader>, base::UniquePtrComparator> readers_;
};

void ProcessSingleton::LinuxWatcher::OnSocketCanReadWithoutBlocking(
    int socket) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  // Accepting incoming client.
  SockaddrUn from;
  socklen_t from_len = sizeof(from);
  int connection_socket = HANDLE_EINTR(
      accept(socket, reinterpret_cast<sockaddr*>(&from), &from_len));
  if (-1 == connection_socket) {
    PLOG(ERROR) << "accept() failed";
    return;
  }
  DCHECK(base::SetNonBlocking(connection_socket))
      << "Failed to make non-blocking socket.";
  readers_.insert(
      std::make_unique<SocketReader>(this, ui_task_runner_, connection_socket));
}

void ProcessSingleton::LinuxWatcher::StartListening(int socket) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  // Watch for client connections on this socket.
  socket_watcher_ = base::FileDescriptorWatcher::WatchReadable(
      socket, base::BindRepeating(&LinuxWatcher::OnSocketCanReadWithoutBlocking,
                                  base::Unretained(this), socket));
}

void ProcessSingleton::LinuxWatcher::HandleMessage(
    const std::string& current_dir, const std::vector<std::string>& argv,
    SocketReader* reader) {
  DCHECK(ui_task_runner_->BelongsToCurrentThread());
  DCHECK(reader);

  if (parent_ && parent_->notification_callback_.Run(
                     base::CommandLine(argv), base::FilePath(current_dir))) {
    // Send back "ACK" message to prevent the client process from starting up.
    reader->FinishWithACK(kACKToken, std::size(kACKToken) - 1);
  } else {
    LOG(WARNING) << "Not handling interprocess notification as browser"
                    " is shutting down";
    // Send back "SHUTDOWN" message, so that the client process can start up
    // without killing this process.
    reader->FinishWithACK(kShutdownToken, std::size(kShutdownToken) - 1);
    return;
  }
}

void ProcessSingleton::LinuxWatcher::RemoveSocketReader(SocketReader* reader) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  DCHECK(reader);
  auto it = readers_.find(reader);
  readers_.erase(it);
}

///////////////////////////////////////////////////////////////////////////////
// ProcessSingleton::LinuxWatcher::SocketReader
//

void ProcessSingleton::LinuxWatcher::SocketReader::
    OnSocketCanReadWithoutBlocking() {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  while (bytes_read_ < sizeof(buf_)) {
    ssize_t rv =
        HANDLE_EINTR(read(fd_, buf_ + bytes_read_, sizeof(buf_) - bytes_read_));
    if (rv < 0) {
      if (errno != EAGAIN && errno != EWOULDBLOCK) {
        PLOG(ERROR) << "read() failed";
        CloseSocket(fd_);
        return;
      } else {
        // It would block, so we just return and continue to watch for the next
        // opportunity to read.
        return;
      }
    } else if (!rv) {
      // No more data to read.  It's time to process the message.
      break;
    } else {
      bytes_read_ += rv;
    }
  }

  // Validate the message.  The shortest message is kStartToken\0x\0x
  const size_t kMinMessageLength = std::size(kStartToken) + 4;
  if (bytes_read_ < kMinMessageLength) {
    buf_[bytes_read_] = 0;
    LOG(ERROR) << "Invalid socket message (wrong length):" << buf_;
    CleanupAndDeleteSelf();
    return;
  }

  std::string str(buf_, bytes_read_);
  std::vector<std::string> tokens = base::SplitString(
      str, std::string(1, kTokenDelimiter),
      base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);

  if (tokens.size() < 3 || tokens[0] != kStartToken) {
    LOG(ERROR) << "Wrong message format: " << str;
    CleanupAndDeleteSelf();
    return;
  }

  // Stop the expiration timer to prevent this SocketReader object from being
  // terminated unexpectedly.
  timer_.Stop();

  std::string current_dir = tokens[1];
  // Remove the first two tokens.  The remaining tokens should be the command
  // line argv array.
  tokens.erase(tokens.begin());
  tokens.erase(tokens.begin());

  // Return to the UI thread to handle opening a new browser tab.
  ui_task_runner_->PostTask(
      FROM_HERE, base::BindOnce(&ProcessSingleton::LinuxWatcher::HandleMessage,
                                parent_, current_dir, tokens, this));
  fd_watch_controller_.reset();

  // LinuxWatcher::HandleMessage() is in charge of destroying this SocketReader
  // object by invoking SocketReader::FinishWithACK().
}

void ProcessSingleton::LinuxWatcher::SocketReader::FinishWithACK(
    const char *message, size_t length) {
  if (message && length) {
    // Not necessary to care about the return value.
    WriteToSocket(fd_, message, length);
  }

  if (shutdown(fd_, SHUT_WR) < 0)
    PLOG(ERROR) << "shutdown() failed";

  content::GetIOThreadTaskRunner({})->PostTask(
      FROM_HERE,
      base::BindOnce(&ProcessSingleton::LinuxWatcher::RemoveSocketReader,
                     parent_, this));
  // We will be deleted once the posted RemoveSocketReader task runs.
}

///////////////////////////////////////////////////////////////////////////////
// ProcessSingleton
//
ProcessSingleton::ProcessSingleton(
    const base::FilePath& user_data_dir,
    const NotificationCallback& notification_callback)
    : notification_callback_(notification_callback),
      current_pid_(base::GetCurrentProcId()) {
  socket_path_ = user_data_dir.Append(chrome::kSingletonSocketFilename);
  lock_path_ = user_data_dir.Append(chrome::kSingletonLockFilename);
  cookie_path_ = user_data_dir.Append(chrome::kSingletonCookieFilename);

  kill_callback_ = base::BindRepeating(&ProcessSingleton::KillProcess,
                                       base::Unretained(this));
}

ProcessSingleton::~ProcessSingleton() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  if (watcher_) {
    watcher_->OnEminentProcessSingletonDestruction();
  }
}

ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
  return NotifyOtherProcessWithTimeout(*base::CommandLine::ForCurrentProcess(),
                                       kRetryAttempts,
                                       base::Seconds(kTimeoutInSeconds), true);
}

ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessWithTimeout(
    const base::CommandLine& cmd_line,
    int retry_attempts,
    const base::TimeDelta& timeout,
    bool kill_unresponsive) {
  DCHECK_GE(retry_attempts, 0);
  DCHECK_GE(timeout.InMicroseconds(), 0);

  base::TimeDelta sleep_interval = timeout / retry_attempts;

  ScopedSocket socket;
  int pid = 0;
  for (int retries = 0; retries <= retry_attempts; ++retries) {
    // Try to connect to the socket.
    if (ConnectSocket(&socket, socket_path_, cookie_path_)) {
#if BUILDFLAG(IS_MAC)
      // On Mac, we want the open process' pid in case there are
      // Apple Events to forward. See crbug.com/777863.
      std::string hostname;
      ParseProcessSingletonLock(lock_path_, &hostname, &pid);
#endif
      break;
    }

    // If we're in a race with another process, they may be in Create() and have
    // created the lock but not attached to the socket.  So we check if the
    // process with the pid from the lockfile is currently running and is a
    // chrome browser.  If so, we loop and try again for |timeout|.

    std::string hostname;
    if (!ParseProcessSingletonLock(lock_path_, &hostname, &pid)) {
      // No lockfile exists.
      return PROCESS_NONE;
    }

    if (hostname.empty()) {
      // Invalid lockfile.
      UnlinkPath(lock_path_);
      internal::SendRemoteProcessInteractionResultHistogram(INVALID_LOCK_FILE);
      return PROCESS_NONE;
    }

    if (hostname != net::GetHostName() && !IsChromeProcess(pid)) {
      // Locked by process on another host. If the user selected to unlock
      // the profile, try to continue; otherwise quit.
      if (DisplayProfileInUseError(lock_path_, hostname, pid)) {
        UnlinkPath(lock_path_);
        internal::SendRemoteProcessInteractionResultHistogram(PROFILE_UNLOCKED);
        return PROCESS_NONE;
      }
      return PROFILE_IN_USE;
    }

    if (!IsChromeProcess(pid)) {
      // Orphaned lockfile (no process with pid, or non-chrome process.)
      UnlinkPath(lock_path_);
      internal::SendRemoteProcessInteractionResultHistogram(ORPHANED_LOCK_FILE);
      return PROCESS_NONE;
    }

    if (IsSameChromeInstance(pid)) {
      // Orphaned lockfile (pid is part of same chrome instance we are, even
      // though we haven't tried to create a lockfile yet).
      UnlinkPath(lock_path_);
      internal::SendRemoteProcessInteractionResultHistogram(
          SAME_BROWSER_INSTANCE);
      return PROCESS_NONE;
    }

    if (retries == retry_attempts) {
      // Retries failed.  Kill the unresponsive chrome process and continue.
      if (!kill_unresponsive || !KillProcessByLockPath(false))
        return PROFILE_IN_USE;
      internal::SendRemoteHungProcessTerminateReasonHistogram(
          NOTIFY_ATTEMPTS_EXCEEDED);
      return PROCESS_NONE;
    }

    base::PlatformThread::Sleep(sleep_interval);
  }

#if BUILDFLAG(IS_MAC)
  if (pid > 0 && WaitForAndForwardOpenURLEvent(pid)) {
    return PROCESS_NOTIFIED;
  }
#endif
  timeval socket_timeout = TimeDeltaToTimeVal(timeout);
  setsockopt(socket.fd(),
             SOL_SOCKET,
             SO_SNDTIMEO,
             &socket_timeout,
             sizeof(socket_timeout));

  // Found another process, prepare our command line
  // format is "START\0<current dir>\0<argv[0]>\0...\0<argv[n]>".
  std::string to_send(kStartToken);
  to_send.push_back(kTokenDelimiter);

  base::FilePath current_dir;
  if (!base::PathService::Get(base::DIR_CURRENT, &current_dir))
    return PROCESS_NONE;
  to_send.append(current_dir.value());

  const std::vector<std::string>& argv = cmd_line.argv();
  for (auto it = argv.begin(); it != argv.end(); ++it) {
    to_send.push_back(kTokenDelimiter);
    to_send.append(*it);
  }

  // Send the message
  if (!WriteToSocket(socket.fd(), to_send.data(), to_send.length())) {
    // Try to kill the other process, because it might have been dead.
    if (!kill_unresponsive || !KillProcessByLockPath(true))
      return PROFILE_IN_USE;
    internal::SendRemoteHungProcessTerminateReasonHistogram(
        SOCKET_WRITE_FAILED);
    return PROCESS_NONE;
  }

  if (shutdown(socket.fd(), SHUT_WR) < 0)
    PLOG(ERROR) << "shutdown() failed";

  // Read ACK message from the other process. It might be blocked for a certain
  // timeout, to make sure the other process has enough time to return ACK.
  char buf[kMaxACKMessageLength + 1];
  ssize_t len = ReadFromSocket(socket.fd(), buf, kMaxACKMessageLength, timeout);

  // Failed to read ACK, the other process might have been frozen.
  if (len <= 0) {
    if (!kill_unresponsive || !KillProcessByLockPath(true))
      return PROFILE_IN_USE;
    internal::SendRemoteHungProcessTerminateReasonHistogram(SOCKET_READ_FAILED);
    return PROCESS_NONE;
  }

  buf[len] = '\0';
  if (strncmp(buf, kShutdownToken, std::size(kShutdownToken) - 1) == 0) {
    // The other process is shutting down, it's safe to start a new process.
    internal::SendRemoteProcessInteractionResultHistogram(
        REMOTE_PROCESS_SHUTTING_DOWN);
    return PROCESS_NONE;
  } else if (strncmp(buf, kACKToken, std::size(kACKToken) - 1) == 0) {
    // Assume the other process is handling the request.
    return PROCESS_NOTIFIED;
  }

  NOTREACHED() << "The other process returned unknown message: " << buf;
}

ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate() {
  return NotifyOtherProcessWithTimeoutOrCreate(
      *base::CommandLine::ForCurrentProcess(), kRetryAttempts,
      base::Seconds(kTimeoutInSeconds));
}

ProcessSingleton::NotifyResult
ProcessSingleton::NotifyOtherProcessWithTimeoutOrCreate(
    const base::CommandLine& command_line,
    int retry_attempts,
    const base::TimeDelta& timeout) {
  const base::TimeTicks begin_ticks = base::TimeTicks::Now();
  NotifyResult result = NotifyOtherProcessWithTimeout(
      command_line, retry_attempts, timeout, true);
  if (result != PROCESS_NONE) {
    if (result == PROCESS_NOTIFIED) {
      DEPRECATED_UMA_HISTOGRAM_MEDIUM_TIMES(
          "Chrome.ProcessSingleton.TimeToNotify",
          base::TimeTicks::Now() - begin_ticks);
    } else {
      DEPRECATED_UMA_HISTOGRAM_MEDIUM_TIMES(
          "Chrome.ProcessSingleton.TimeToFailure",
          base::TimeTicks::Now() - begin_ticks);
    }
    return result;
  }

  if (Create()) {
    DEPRECATED_UMA_HISTOGRAM_MEDIUM_TIMES(
        "Chrome.ProcessSingleton.TimeToCreate",
        base::TimeTicks::Now() - begin_ticks);
    return PROCESS_NONE;
  }

  // If the Create() failed, try again to notify. (It could be that another
  // instance was starting at the same time and managed to grab the lock before
  // we did.)
  // This time, we don't want to kill anything if we aren't successful, since we
  // aren't going to try to take over the lock ourselves.
  result = NotifyOtherProcessWithTimeout(
      command_line, retry_attempts, timeout, false);

  if (result == PROCESS_NOTIFIED) {
    DEPRECATED_UMA_HISTOGRAM_MEDIUM_TIMES(
        "Chrome.ProcessSingleton.TimeToNotify",
        base::TimeTicks::Now() - begin_ticks);
  } else {
    DEPRECATED_UMA_HISTOGRAM_MEDIUM_TIMES(
        "Chrome.ProcessSingleton.TimeToFailure",
        base::TimeTicks::Now() - begin_ticks);
  }

  if (result != PROCESS_NONE)
    return result;

  return LOCK_ERROR;
}

void ProcessSingleton::OverrideCurrentPidForTesting(base::ProcessId pid) {
  current_pid_ = pid;
}

void ProcessSingleton::OverrideKillCallbackForTesting(
    const base::RepeatingCallback<void(int)>& callback) {
  kill_callback_ = callback;
}

// static
void ProcessSingleton::DisablePromptForTesting() {
  g_disable_prompt = true;
}

// static
void ProcessSingleton::SkipIsChromeProcessCheckForTesting(bool skip) {
  g_skip_is_chrome_process_check = skip;
}

// static
void ProcessSingleton::SetUserOptedUnlockInUseProfileForTesting(
    bool set_unlock) {
  g_user_opted_unlock_in_use_profile = set_unlock;
}

bool ProcessSingleton::Create() {
  // The symlink lock is pointed to the hostname and process id, so other
  // processes can find it out.
  base::FilePath symlink_content(
      base::StringPrintf("%s%c%u", net::GetHostName().c_str(),
                         kProcessSingletonLockDelimiter, current_pid_));

  // Create symbol link before binding the socket, to ensure only one instance
  // can have the socket open.
  if (!SymlinkPath(symlink_content, lock_path_)) {
    // TODO(jackhou): Remove this case once this code is stable on Mac.
    // http://crbug.com/367612
#if BUILDFLAG(IS_MAC)
    // On Mac, an existing non-symlink lock file means the lock could be held by
    // the old process singleton code. If we can successfully replace the lock,
    // continue as normal.
    if (base::IsLink(lock_path_) ||
        !ReplaceOldSingletonLock(symlink_content, lock_path_)) {
      return false;
    }
#else
    // If we failed to create the lock, most likely another instance won the
    // startup race.
    return false;
#endif
  }

  // Create the socket file somewhere in /tmp which is usually mounted as a
  // normal filesystem. Some network filesystems (notably AFS) are screwy and
  // do not support Unix domain sockets.
  if (!socket_dir_.CreateUniqueTempDir()) {
    LOG(ERROR) << "Failed to create socket directory.";
    return false;
  }

  // Check that the directory was created with the correct permissions.
  int dir_mode = 0;
  CHECK(base::GetPosixFilePermissions(socket_dir_.GetPath(), &dir_mode) &&
        dir_mode == base::FILE_PERMISSION_USER_MASK)
      << "Temp directory mode is not 700: " << std::oct << dir_mode;

  // Try to create the socket before creating the symlink, as SetupSocket may
  // fail on a CHECK if the |socket_target_path| is too long, and this avoids
  // leaving a dangling symlink.
  base::FilePath socket_target_path =
      socket_dir_.GetPath().Append(chrome::kSingletonSocketFilename);
  SockaddrUn addr;
  socklen_t socklen;
  SetupSocket(socket_target_path.value(), &sock_, &addr, &socklen);

  // Setup the socket symlink and the two cookies.
  base::FilePath cookie(GenerateCookie());
  base::FilePath remote_cookie_path =
      socket_dir_.GetPath().Append(chrome::kSingletonCookieFilename);
  UnlinkPath(socket_path_);
  UnlinkPath(cookie_path_);
  if (!SymlinkPath(socket_target_path, socket_path_) ||
      !SymlinkPath(cookie, cookie_path_) ||
      !SymlinkPath(cookie, remote_cookie_path)) {
    // We've already locked things, so we can't have lost the startup race,
    // but something doesn't like us.
    LOG(ERROR) << "Failed to create symlinks.";
    if (!socket_dir_.Delete())
      LOG(ERROR) << "Encountered a problem when deleting socket directory.";
    return false;
  }

  if (bind(sock_, reinterpret_cast<sockaddr*>(&addr), socklen) < 0) {
    PLOG(ERROR) << "Failed to bind() " << socket_target_path.value();
    CloseSocket(sock_);
    return false;
  }

  if (listen(sock_, 5) < 0) {
    NOTREACHED() << "listen failed: " << base::safe_strerror(errno);
  }

  return true;
}

void ProcessSingleton::StartWatching() {
  DCHECK_GE(sock_, 0);
  DCHECK(!watcher_);
  watcher_ = base::MakeRefCounted<LinuxWatcher>(this);
  DCHECK(BrowserThread::IsThreadInitialized(BrowserThread::IO));
  content::GetIOThreadTaskRunner({})->PostTask(
      FROM_HERE, base::BindOnce(&ProcessSingleton::LinuxWatcher::StartListening,
                                watcher_, sock_));
}

void ProcessSingleton::Cleanup() {
  UnlinkPath(socket_path_);
  UnlinkPath(cookie_path_);
  UnlinkPath(lock_path_);
}

bool ProcessSingleton::IsSameChromeInstance(pid_t pid) {
  pid_t cur_pid = current_pid_;
  while (pid != cur_pid) {
    pid = base::GetParentProcessId(pid);
    if (pid <= 0)
      return false;
    if (!IsChromeProcess(pid))
      return false;
  }
  return true;
}

bool ProcessSingleton::KillProcessByLockPath(bool is_connected_to_socket) {
  std::string hostname;
  int pid;
  ParseProcessSingletonLock(lock_path_, &hostname, &pid);

  if (!hostname.empty() && hostname != net::GetHostName() &&
      !is_connected_to_socket) {
    bool res = DisplayProfileInUseError(lock_path_, hostname, pid);
    if (res) {
      UnlinkPath(lock_path_);
      internal::SendRemoteProcessInteractionResultHistogram(
          PROFILE_UNLOCKED_BEFORE_KILL);
    }
    return res;
  }
  UnlinkPath(lock_path_);

  if (IsSameChromeInstance(pid)) {
    internal::SendRemoteProcessInteractionResultHistogram(
        SAME_BROWSER_INSTANCE_BEFORE_KILL);
    return true;
  }

  if (pid > 0) {
    kill_callback_.Run(pid);
    return true;
  }

  internal::SendRemoteProcessInteractionResultHistogram(FAILED_TO_EXTRACT_PID);

  LOG(ERROR) << "Failed to extract pid from path: " << lock_path_.value();
  return true;
}

void ProcessSingleton::KillProcess(int pid) {
  // TODO(james.su@gmail.com): Is SIGKILL ok?
  int rv = kill(static_cast<base::ProcessHandle>(pid), SIGKILL);
  // ESRCH = No Such Process (can happen if the other process is already in
  // progress of shutting down and finishes before we try to kill it).
  DPCHECK(rv == 0 || errno == ESRCH) << "Error killing process";

  int error_code = (rv == 0) ? 0 : errno;
  base::UmaHistogramSparse(
      "Chrome.ProcessSingleton.TerminateProcessErrorCode.Posix", error_code);

  RemoteProcessInteractionResult action = TERMINATE_SUCCEEDED;
  if (rv != 0) {
    switch (error_code) {
      case ESRCH:
        action = REMOTE_PROCESS_NOT_FOUND;
        break;
      case EPERM:
        action = TERMINATE_NOT_ENOUGH_PERMISSIONS;
        break;
      default:
        action = TERMINATE_FAILED;
        break;
    }
  }
  internal::SendRemoteProcessInteractionResultHistogram(action);
}
