// Copyright 2017 The Crashpad Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "handler/linux/exception_handler_server.h"

#include <sys/types.h>
#include <unistd.h>

#include "build/build_config.h"
#include "gtest/gtest.h"
#include "snapshot/linux/process_snapshot_linux.h"
#include "test/errors.h"
#include "test/multiprocess.h"
#include "util/linux/direct_ptrace_connection.h"
#include "util/linux/exception_handler_client.h"
#include "util/linux/ptrace_client.h"
#include "util/linux/scoped_pr_set_ptracer.h"
#include "util/misc/uuid.h"
#include "util/synchronization/semaphore.h"
#include "util/thread/thread.h"

#if BUILDFLAG(IS_ANDROID)
#include <android/api-level.h>
#endif

namespace crashpad {
namespace test {
namespace {

// Runs the ExceptionHandlerServer on a background thread.
class RunServerThread : public Thread {
 public:
  RunServerThread(ExceptionHandlerServer* server,
                  ExceptionHandlerServer::Delegate* delegate)
      : server_(server), delegate_(delegate), join_sem_(0) {}

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

  ~RunServerThread() override {}

  bool JoinWithTimeout(double timeout) {
    if (!join_sem_.TimedWait(timeout)) {
      return false;
    }
    Join();
    return true;
  }

 private:
  // Thread:
  void ThreadMain() override {
    server_->Run(delegate_);
    join_sem_.Signal();
  }

  ExceptionHandlerServer* server_;
  ExceptionHandlerServer::Delegate* delegate_;
  Semaphore join_sem_;
};

class ScopedStopServerAndJoinThread {
 public:
  ScopedStopServerAndJoinThread(ExceptionHandlerServer* server,
                                RunServerThread* thread)
      : server_(server), thread_(thread) {}

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

  ~ScopedStopServerAndJoinThread() {
    server_->Stop();
    EXPECT_TRUE(thread_->JoinWithTimeout(5.0));
  }

 private:
  ExceptionHandlerServer* server_;
  RunServerThread* thread_;
};

class TestDelegate : public ExceptionHandlerServer::Delegate {
 public:
  TestDelegate()
      : Delegate(), last_exception_address_(0), last_client_(-1), sem_(0) {}

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

  ~TestDelegate() {}

  bool WaitForException(double timeout_seconds,
                        pid_t* last_client,
                        VMAddress* last_address) {
    if (sem_.TimedWait(timeout_seconds)) {
      *last_client = last_client_;
      *last_address = last_exception_address_;
      return true;
    }

    return false;
  }

  bool HandleException(pid_t client_process_id,
                       uid_t client_uid,
                       const ExceptionHandlerProtocol::ClientInformation& info,
                       VMAddress requesting_thread_stack_address,
                       pid_t* requesting_thread_id = nullptr,
                       UUID* local_report_id = nullptr) override {
    DirectPtraceConnection connection;
    bool connected = connection.Initialize(client_process_id);
    EXPECT_TRUE(connected);

    last_exception_address_ = info.exception_information_address;
    last_client_ = client_process_id;
    sem_.Signal();
    if (!connected) {
      return false;
    }

    if (requesting_thread_id) {
      if (requesting_thread_stack_address) {
        ProcessSnapshotLinux process_snapshot;
        if (!process_snapshot.Initialize(&connection)) {
          ADD_FAILURE();
          return false;
        }
        *requesting_thread_id = process_snapshot.FindThreadWithStackAddress(
            requesting_thread_stack_address);
      } else {
        *requesting_thread_id = -1;
      }
    }
    return true;
  }

  bool HandleExceptionWithBroker(
      pid_t client_process_id,
      uid_t client_uid,
      const ExceptionHandlerProtocol::ClientInformation& info,
      int broker_sock,
      UUID* local_report_id = nullptr) override {
    PtraceClient client;
    bool connected = client.Initialize(broker_sock, client_process_id);
    EXPECT_TRUE(connected);

    last_exception_address_ = info.exception_information_address,
    last_client_ = client_process_id;
    sem_.Signal();
    return connected;
  }

 private:
  VMAddress last_exception_address_;
  pid_t last_client_;
  Semaphore sem_;
};

class MockPtraceStrategyDecider : public PtraceStrategyDecider {
 public:
  MockPtraceStrategyDecider(PtraceStrategyDecider::Strategy strategy)
      : PtraceStrategyDecider(), strategy_(strategy) {}

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

  ~MockPtraceStrategyDecider() {}

  Strategy ChooseStrategy(int sock,
                          bool multiple_clients,
                          const ucred& client_credentials) override {
    if (strategy_ == Strategy::kUseBroker) {
      ExceptionHandlerProtocol::ServerToClientMessage message = {};
      message.type =
          ExceptionHandlerProtocol::ServerToClientMessage::kTypeForkBroker;

      ExceptionHandlerProtocol::Errno status;
      bool result = LoggingWriteFile(sock, &message, sizeof(message)) &&
                    LoggingReadFileExactly(sock, &status, sizeof(status));
      EXPECT_TRUE(result);

      if (!result) {
        return Strategy::kError;
      }

      if (status != 0) {
        errno = status;
        ADD_FAILURE() << ErrnoMessage("Handler Client ForkBroker");
        return Strategy::kNoPtrace;
      }
    }
    return strategy_;
  }

 private:
  Strategy strategy_;
};

class ExceptionHandlerServerTest : public testing::TestWithParam<bool> {
 public:
  ExceptionHandlerServerTest()
      : server_(),
        delegate_(),
        server_thread_(&server_, &delegate_),
        sock_to_handler_(),
        use_multi_client_socket_(GetParam()) {}

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

  ~ExceptionHandlerServerTest() = default;

  int SockToHandler() { return sock_to_handler_.get(); }

  TestDelegate* Delegate() { return &delegate_; }

  void Hangup() { sock_to_handler_.reset(); }

  RunServerThread* ServerThread() { return &server_thread_; }

  ExceptionHandlerServer* Server() { return &server_; }

  class CrashDumpTest : public Multiprocess {
   public:
    CrashDumpTest(ExceptionHandlerServerTest* server_test, bool succeeds)
        : Multiprocess(), server_test_(server_test), succeeds_(succeeds) {}

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

    ~CrashDumpTest() = default;

    void MultiprocessParent() override {
      ExceptionHandlerProtocol::ClientInformation info;
      ASSERT_TRUE(
          LoggingReadFileExactly(ReadPipeHandle(), &info, sizeof(info)));

      if (succeeds_) {
        VMAddress last_address;
        pid_t last_client;
        ASSERT_TRUE(server_test_->Delegate()->WaitForException(
            5.0, &last_client, &last_address));
        // `exception_information_address` is underaligned and `EXPECT_EQ`
        // internally takes arguments by reference. Copy it into a temporary
        // before comparing to avoid undefined behavior.
        EXPECT_EQ(last_address, VMAddress{info.exception_information_address});
        EXPECT_EQ(last_client, ChildPID());
      } else {
        CheckedReadFileAtEOF(ReadPipeHandle());
      }
    }

    void MultiprocessChild() override {
      ASSERT_EQ(close(server_test_->sock_to_client_), 0);

      ExceptionHandlerProtocol::ClientInformation info;
      info.exception_information_address = 42;
      ASSERT_TRUE(LoggingWriteFile(WritePipeHandle(), &info, sizeof(info)));

      // If the current ptrace_scope is restricted, the broker needs to be set
      // as the ptracer for this process. Setting this process as its own
      // ptracer allows the broker to inherit this condition.
      ScopedPrSetPtracer set_ptracer(getpid(), /* may_log= */ true);

      ExceptionHandlerClient client(server_test_->SockToHandler(),
                                    server_test_->use_multi_client_socket_);
      ASSERT_EQ(client.RequestCrashDump(info), 0);
    }

   private:
    ExceptionHandlerServerTest* server_test_;
    bool succeeds_;
  };

  void ExpectCrashDumpUsingStrategy(PtraceStrategyDecider::Strategy strategy,
                                    bool succeeds) {
    Server()->SetPtraceStrategyDecider(
        std::make_unique<MockPtraceStrategyDecider>(strategy));

    ScopedStopServerAndJoinThread stop_server(Server(), ServerThread());
    ServerThread()->Start();

    CrashDumpTest test(this, succeeds);
    test.Run();
  }

  bool UsingMultiClientSocket() const { return use_multi_client_socket_; }

 protected:
  void SetUp() override {
    int socks[2];
    ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, socks), 0);
    sock_to_handler_.reset(socks[0]);
    sock_to_client_ = socks[1];

    ASSERT_TRUE(server_.InitializeWithClient(ScopedFileHandle(socks[1]),
                                             use_multi_client_socket_));
  }

 private:
  ExceptionHandlerServer server_;
  TestDelegate delegate_;
  RunServerThread server_thread_;
  ScopedFileHandle sock_to_handler_;
  int sock_to_client_;
  bool use_multi_client_socket_;
};

TEST_P(ExceptionHandlerServerTest, ShutdownWithNoClients) {
  ServerThread()->Start();
  Hangup();
  ASSERT_TRUE(ServerThread()->JoinWithTimeout(5.0));
}

TEST_P(ExceptionHandlerServerTest, StopWithClients) {
  ServerThread()->Start();
  Server()->Stop();
  ASSERT_TRUE(ServerThread()->JoinWithTimeout(5.0));
}

TEST_P(ExceptionHandlerServerTest, StopBeforeRun) {
  Server()->Stop();
  ServerThread()->Start();
  ASSERT_TRUE(ServerThread()->JoinWithTimeout(5.0));
}

TEST_P(ExceptionHandlerServerTest, MultipleStops) {
  ServerThread()->Start();
  Server()->Stop();
  Server()->Stop();
  ASSERT_TRUE(ServerThread()->JoinWithTimeout(5.0));
}

TEST_P(ExceptionHandlerServerTest, RequestCrashDumpDefault) {
  ScopedStopServerAndJoinThread stop_server(Server(), ServerThread());
  ServerThread()->Start();

  CrashDumpTest test(this, true);
  test.Run();
}

TEST_P(ExceptionHandlerServerTest, RequestCrashDumpNoPtrace) {
  ExpectCrashDumpUsingStrategy(PtraceStrategyDecider::Strategy::kNoPtrace,
                               false);
}

TEST_P(ExceptionHandlerServerTest, RequestCrashDumpForkBroker) {
  if (UsingMultiClientSocket()) {
    // The broker is not supported with multiple clients connected on a single
    // socket.
    return;
  }
  ExpectCrashDumpUsingStrategy(PtraceStrategyDecider::Strategy::kUseBroker,
                               true);
}

TEST_P(ExceptionHandlerServerTest, RequestCrashDumpDirectPtrace) {
  ExpectCrashDumpUsingStrategy(PtraceStrategyDecider::Strategy::kDirectPtrace,
                               true);
}

TEST_P(ExceptionHandlerServerTest, RequestCrashDumpError) {
  ExpectCrashDumpUsingStrategy(PtraceStrategyDecider::Strategy::kError, false);
}

INSTANTIATE_TEST_SUITE_P(ExceptionHandlerServerTestSuite,
                         ExceptionHandlerServerTest,
                         testing::Bool()
);

}  // namespace
}  // namespace test
}  // namespace crashpad
