// 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 <fuchsia/ldsvc/llcpp/fidl.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_NOT_FILE)));
  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 = {};
  req.header.ordinal = LDMSG_OP_LOAD_OBJECT;
  req.header.magic_number = kFidlWireFormatMagicNumberInitial;
  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
