// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/lib/loader_service/loader_service.h"

#include <fidl/fuchsia.ldsvc/cpp/wire.h>
#include <lib/fdio/unsafe.h>
#include <lib/zx/channel.h>
#include <lib/zx/result.h>
#include <zircon/errors.h>
#include <zircon/fidl.h>

#include <utility>

#include <ldmsg/ldmsg.h>

#include "src/lib/loader_service/loader_service_test_fixture.h"

#define ASSERT_OK(expr) ASSERT_EQ(ZX_OK, expr)
#define EXPECT_OK(expr) EXPECT_EQ(ZX_OK, expr)

namespace loader {
namespace test {
namespace {

namespace fldsvc = fuchsia_ldsvc;

TEST_F(LoaderServiceTest, ConnectBindDone) {
  std::shared_ptr<LoaderService> loader;
  std::vector<TestDirectoryEntry> config;
  config.emplace_back("libfoo.so", "science", true);
  ASSERT_NO_FATAL_FAILURE(CreateTestLoader(config, &loader));

  {
    auto status = loader->Connect();
    ASSERT_TRUE(status.is_ok());
    fidl::WireSyncClient<fldsvc::Loader> client(std::move(status.value()));
    EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libfoo.so", zx::ok("science")));

    // Done should cleanly shutdown connection from server side.
    ASSERT_TRUE(client->Done().ok());
    ASSERT_EQ(client->LoadObject("libfoo.so").status(), ZX_ERR_PEER_CLOSED);
  }

  // Should be able to still make new connections.
  {
    auto [client_end, server_end] = fidl::Endpoints<fldsvc::Loader>::Create();
    loader->Bind(std::move(server_end));
    fidl::WireSyncClient<fldsvc::Loader> client(std::move(client_end));
    EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libfoo.so", zx::ok("science")));
  }
}

TEST_F(LoaderServiceTest, OpenConnectionsKeepLoaderAlive) {
  fbl::unique_fd root_fd;
  std::vector<TestDirectoryEntry> config;
  config.emplace_back("libfoo.so", "science", true);
  ASSERT_NO_FATAL_FAILURE(CreateTestDirectory(config, &root_fd));

  // Grab the raw zx_handle_t for the root_fd's channel for use below.
  fdio_t* fdio = fdio_unsafe_fd_to_io(root_fd.get());
  zx::unowned_channel fd_channel(fdio_unsafe_borrow_channel(fdio));
  fdio_unsafe_release(fdio);

  const ::testing::TestInfo* const test_info =
      ::testing::UnitTest::GetInstance()->current_test_info();
  auto loader =
      LoaderService::Create(loader_loop().dispatcher(), std::move(root_fd), test_info->name());

  fidl::WireSyncClient<fldsvc::Loader> client1, client2;
  {
    auto status = loader->Connect();
    ASSERT_TRUE(status.is_ok());
    client1 = fidl::WireSyncClient<fldsvc::Loader>(std::move(status.value()));
  }
  {
    auto status = loader->Connect();
    ASSERT_TRUE(status.is_ok());
    client2 = fidl::WireSyncClient<fldsvc::Loader>(std::move(status.value()));
  }

  // Drop our copy of the LoaderService. Open connections should continue working.
  loader.reset();

  // Should still be able to Clone any open connection.
  auto [client, server] = fidl::Endpoints<fldsvc::Loader>::Create();
  auto result = client2->Clone(std::move(server));
  ASSERT_TRUE(result.ok());
  ASSERT_OK(result->rv);
  fidl::WireSyncClient<fldsvc::Loader> client3(std::move(client));

  EXPECT_NO_FATAL_FAILURE(LoadObject(client1, "libfoo.so", zx::ok("science")));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client2, "libfoo.so", zx::ok("science")));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client3, "libfoo.so", zx::ok("science")));

  // Note this closes the channels from the client side rather than using Done, which is exercised
  // in another test, since this is closer to real Loader usage.
  client1 = fidl::WireSyncClient<fldsvc::Loader>();
  EXPECT_NO_FATAL_FAILURE(LoadObject(client2, "libfoo.so", zx::ok("science")));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client3, "libfoo.so", zx::ok("science")));

  // Connection cloned from another should work the same as connections created from LoaderService.
  client2 = fidl::WireSyncClient<fldsvc::Loader>();
  EXPECT_NO_FATAL_FAILURE(LoadObject(client3, "libfoo.so", zx::ok("science")));

  // Verify that the directory fd used to create the loader is properly closed once all connections
  // are closed.
  ASSERT_OK(fd_channel->get_info(ZX_INFO_HANDLE_VALID, nullptr, 0, nullptr, nullptr));
  client3 = fidl::WireSyncClient<fldsvc::Loader>();
  // Must shutdown the loader_loop (which joins its thread) to ensure this is not racy. Otherwise
  // the server FIDL bindings may not have handled the client-side channel closure yet.
  loader_loop().Shutdown();
  ASSERT_EQ(ZX_ERR_BAD_HANDLE,
            fd_channel->get_info(ZX_INFO_HANDLE_VALID, nullptr, 0, nullptr, nullptr));
}

TEST_F(LoaderServiceTest, LoadObject) {
  std::shared_ptr<LoaderService> loader;
  std::vector<TestDirectoryEntry> config;
  config.emplace_back("libfoo.so", "science", true);
  config.emplace_back("libnoexec.so", "rules", false);
  ASSERT_NO_FATAL_FAILURE(CreateTestLoader(config, &loader));

  auto status = loader->Connect();
  ASSERT_TRUE(status.is_ok());
  fidl::WireSyncClient<fldsvc::Loader> client(std::move(status.value()));

  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libfoo.so", zx::ok("science")));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libmissing.so", zx::error(ZX_ERR_NOT_FOUND)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libnoexec.so", zx::error(ZX_ERR_ACCESS_DENIED)));
}

TEST_F(LoaderServiceTest, Config) {
  std::shared_ptr<LoaderService> loader;
  std::vector<TestDirectoryEntry> config;
  config.emplace_back("asan/libfoo.so", "black", true);
  config.emplace_back("asan/libasan_only.so", "lives", true);
  config.emplace_back("libfoo.so", "must", true);
  config.emplace_back("libno_san.so", "matter", true);
  ASSERT_NO_FATAL_FAILURE(CreateTestLoader(config, &loader));

  auto status = loader->Connect();
  ASSERT_TRUE(status.is_ok());
  fidl::WireSyncClient<fldsvc::Loader> client(std::move(status.value()));

  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libfoo.so", zx::ok("must")));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libasan_only.so", zx::error(ZX_ERR_NOT_FOUND)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libno_san.so", zx::ok("matter")));

  ASSERT_NO_FATAL_FAILURE(Config(client, "asan", zx::ok(ZX_OK)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libfoo.so", zx::ok("black")));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libasan_only.so", zx::ok("lives")));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libno_san.so", zx::ok("matter")));

  ASSERT_NO_FATAL_FAILURE(Config(client, "asan!", zx::ok(ZX_OK)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libfoo.so", zx::ok("black")));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libasan_only.so", zx::ok("lives")));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libno_san.so", zx::error(ZX_ERR_NOT_FOUND)));

  ASSERT_NO_FATAL_FAILURE(Config(client, "ubsan", zx::ok(ZX_OK)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libfoo.so", zx::ok("must")));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libasan_only.so", zx::error(ZX_ERR_NOT_FOUND)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libno_san.so", zx::ok("matter")));

  // '!' mid-string should do nothing special, same as non-existing directory
  ASSERT_NO_FATAL_FAILURE(Config(client, "ubsa!n", zx::ok(ZX_OK)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libfoo.so", zx::ok("must")));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libasan_only.so", zx::error(ZX_ERR_NOT_FOUND)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libno_san.so", zx::ok("matter")));

  ASSERT_NO_FATAL_FAILURE(Config(client, "ubsan!", zx::ok(ZX_OK)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libfoo.so", zx::error(ZX_ERR_NOT_FOUND)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libasan_only.so", zx::error(ZX_ERR_NOT_FOUND)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libno_san.so", zx::error(ZX_ERR_NOT_FOUND)));

  // Config can be reset back to default.
  ASSERT_NO_FATAL_FAILURE(Config(client, "", zx::ok(ZX_OK)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libfoo.so", zx::ok("must")));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libasan_only.so", zx::error(ZX_ERR_NOT_FOUND)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libno_san.so", zx::ok("matter")));
}

// Each new connection to the loader service should act as if Config has not yet been called, even
// if it had been called on the connection it was cloned from.
TEST_F(LoaderServiceTest, ClonedConnectionHasDefaultConfig) {
  std::shared_ptr<LoaderService> loader;
  std::vector<TestDirectoryEntry> config;
  config.emplace_back("asan/libfoo.so", "black", true);
  config.emplace_back("asan/libasan_only.so", "lives", true);
  config.emplace_back("libno_san.so", "matter", true);
  ASSERT_NO_FATAL_FAILURE(CreateTestLoader(config, &loader));

  auto status = loader->Connect();
  ASSERT_TRUE(status.is_ok());
  fidl::WireSyncClient<fldsvc::Loader> client(std::move(status.value()));

  ASSERT_NO_FATAL_FAILURE(Config(client, "asan", zx::ok(ZX_OK)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libfoo.so", zx::ok("black")));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libasan_only.so", zx::ok("lives")));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libno_san.so", zx::ok("matter")));

  auto [client2, server] = fidl::Endpoints<fldsvc::Loader>::Create();
  auto result = client->Clone(std::move(server));
  ASSERT_TRUE(result.ok());
  ASSERT_OK(result->rv);
  {
    fidl::WireSyncClient<fldsvc::Loader> client(std::move(client2));
    EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libfoo.so", zx::error(ZX_ERR_NOT_FOUND)));
    EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libasan_only.so", zx::error(ZX_ERR_NOT_FOUND)));
    EXPECT_NO_FATAL_FAILURE(LoadObject(client, "libno_san.so", zx::ok("matter")));
  }
}

TEST_F(LoaderServiceTest, InvalidLoadObject) {
  std::shared_ptr<LoaderService> loader;
  std::vector<TestDirectoryEntry> config;
  config.emplace_back("libfoo.so", "science", true);
  config.emplace_back("asan/libfoo.so", "rules", true);
  ASSERT_NO_FATAL_FAILURE(CreateTestLoader(config, &loader));

  auto status = loader->Connect();
  ASSERT_TRUE(status.is_ok());
  fidl::WireSyncClient<fldsvc::Loader> client(std::move(status.value()));

  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "/", zx::error(ZX_ERR_INVALID_ARGS)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "..", zx::error(ZX_ERR_INVALID_ARGS)));
  EXPECT_NO_FATAL_FAILURE(LoadObject(client, "asan", zx::error(ZX_ERR_NOT_FILE)));
}

TEST_F(LoaderServiceTest, InvalidConfig) {
  std::shared_ptr<LoaderService> loader;
  std::vector<TestDirectoryEntry> config;
  ASSERT_NO_FATAL_FAILURE(CreateTestLoader(config, &loader));

  auto status = loader->Connect();
  ASSERT_TRUE(status.is_ok());
  fidl::WireSyncClient<fldsvc::Loader> client(std::move(status.value()));

  EXPECT_NO_FATAL_FAILURE(Config(client, "!", zx::ok(ZX_ERR_INVALID_ARGS)));
  EXPECT_NO_FATAL_FAILURE(Config(client, "/", zx::ok(ZX_ERR_INVALID_ARGS)));
  EXPECT_NO_FATAL_FAILURE(Config(client, "foo/", zx::ok(ZX_ERR_INVALID_ARGS)));
  EXPECT_NO_FATAL_FAILURE(Config(client, "foo/bar", zx::ok(ZX_ERR_INVALID_ARGS)));
}

// fuchsia.ldsvc.Loader is manually implemented in //zircon/system/ulib/ldmsg, and this
// implementation is the one used by our musl-based ld.so dynamic linker/loader. In other words,
// that implementation is used to send most Loader client requests. Test interop with it.
void LoadObjectLdmsg(fidl::UnownedClientEnd<fldsvc::Loader> client, const char* object_name,
                     zx::result<> expected) {
  size_t req_len;
  ldmsg_req_t req;
  zx_status_t status =
      ldmsg_req_encode(LDMSG_OP_LOAD_OBJECT, &req, &req_len, object_name, strlen(object_name));
  ASSERT_OK(status);

  ldmsg_rsp_t rsp = {};
  zx::vmo result;
  zx_channel_call_args_t call = {
      .wr_bytes = &req,
      .wr_handles = nullptr,
      .rd_bytes = &rsp,
      .rd_handles = result.reset_and_get_address(),
      .wr_num_bytes = static_cast<uint32_t>(req_len),
      .wr_num_handles = 0,
      .rd_num_bytes = sizeof(rsp),
      .rd_num_handles = 1,
  };

  uint32_t actual_bytes, actual_handles;
  status = client.channel()->call(0, zx::time::infinite(), &call, &actual_bytes, &actual_handles);
  ASSERT_OK(status);
  ASSERT_EQ(actual_bytes, ldmsg_rsp_get_size(&rsp));
  ASSERT_EQ(rsp.header.ordinal, req.header.ordinal);

  EXPECT_EQ(rsp.rv, expected.status_value());
  EXPECT_EQ(result.is_valid(), expected.is_ok());
}

TEST_F(LoaderServiceTest, InteropWithLdmsg_LoadObject) {
  std::shared_ptr<LoaderService> loader;
  std::vector<TestDirectoryEntry> config;
  config.emplace_back("libfoo.so", "science", true);
  config.emplace_back("libnoexec.so", "rules", false);
  ASSERT_NO_FATAL_FAILURE(CreateTestLoader(config, &loader));

  auto status = loader->Connect();
  ASSERT_TRUE(status.is_ok());
  auto client = std::move(status).value();

  EXPECT_NO_FATAL_FAILURE(LoadObjectLdmsg(client, "libfoo.so", zx::ok()));
  EXPECT_NO_FATAL_FAILURE(LoadObjectLdmsg(client, "libmissing.so", zx::error(ZX_ERR_NOT_FOUND)));
  EXPECT_NO_FATAL_FAILURE(LoadObjectLdmsg(client, "libnoexec.so", zx::error(ZX_ERR_ACCESS_DENIED)));
}

}  // namespace
}  // namespace test
}  // namespace loader
