// 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/status.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(std::move(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 endpoints = fidl::CreateEndpoints<fldsvc::Loader>();
    ASSERT_TRUE(endpoints.is_ok());
    auto [client_end, server_end] = *std::move(endpoints);
    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(std::move(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.
  zx::channel client_chan, server_chan;
  ASSERT_OK(zx::channel::create(0, &client_chan, &server_chan));
  auto result = client2->Clone(std::move(server_chan));
  ASSERT_TRUE(result.ok());
  ASSERT_OK(result.Unwrap()->rv);
  fidl::WireSyncClient<fldsvc::Loader> client3(std::move(client_chan));

  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(std::move(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(std::move(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(std::move(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")));

  zx::channel client_chan, server_chan;
  ASSERT_OK(zx::channel::create(0, &client_chan, &server_chan));
  auto result = client->Clone(std::move(server_chan));
  ASSERT_TRUE(result.ok());
  ASSERT_OK(result.Unwrap()->rv);
  {
    fidl::WireSyncClient<fldsvc::Loader> client(std::move(client_chan));
    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(std::move(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(std::move(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::status<> expected) {
  size_t req_len;
  ldmsg_req_t req;
  ldmsg_req_init_txn_header(&req, LDMSG_OP_LOAD_OBJECT);
  zx_status_t status = ldmsg_req_encode(&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(std::move(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
