// Copyright 2019 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 "bad-handle.h"

#include <lib/fdio/spawn.h>
#include <lib/zx/event.h>
#include <lib/zx/job.h>
#include <lib/zx/process.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/syscalls/policy.h>

#include <iterator>

#include <zxtest/zxtest.h>

#include "utils.h"

const char* BadHandleFlagTest() { return "--bad-handle-test"; }

enum class BadHandleTestCase {
  kInvalid,
  kMatchingValueInWait,
  kNonMatchingValueInWait,
  kMatchingValueInRequeue,
  kNonMatchingValueInRequeue,
};

int BadHandleTestMain(int argc, char** argv) {
  zx::event event;
  zx_status_t status = zx::event::create(0, &event);
  if (status != ZX_OK) {
    return 1;
  }

  if (argc != 3) {
    ZX_PANIC("Need to pass an argument");
  }

  BadHandleTestCase test = BadHandleTestCase::kInvalid;
  if (!strcmp(argv[2], "match_wait")) {
    test = BadHandleTestCase::kMatchingValueInWait;
  } else if (!strcmp(argv[2], "no_match_wait")) {
    test = BadHandleTestCase::kNonMatchingValueInWait;
  } else if (!strcmp(argv[2], "match_requeue")) {
    test = BadHandleTestCase::kMatchingValueInRequeue;
  } else if (!strcmp(argv[2], "no_match_requeue")) {
    test = BadHandleTestCase::kNonMatchingValueInRequeue;
  }

  const zx_handle_t bad_handle = event.get() & ~ZX_HANDLE_FIXED_BITS_MASK;

  switch (test) {
    case BadHandleTestCase::kMatchingValueInWait: {
      zx_futex_t futex = 0;
      // This line should cause a BAD_HANDLE policy exception, since the value matches
      return zx_futex_wait(&futex, 0, bad_handle, ZX_TIME_INFINITE);
    }
    case BadHandleTestCase::kNonMatchingValueInWait: {
      zx_futex_t futex = 0;
      // This line should not cause a BAD_HANDLE policy exception, since the value mismatches
      return zx_futex_wait(&futex, 1, bad_handle, ZX_TIME_INFINITE);
    }
    case BadHandleTestCase::kMatchingValueInRequeue: {
      zx_futex_t futex1 = 0, futex2 = 0;
      // This line should cause a BAD_HANDLE policy exception, since the value matches
      return zx_futex_requeue(&futex1, 1, 0, &futex2, 1, bad_handle);
    }
    case BadHandleTestCase::kNonMatchingValueInRequeue: {
      zx_futex_t futex1 = 0, futex2 = 0;
      // This line should not cause a BAD_HANDLE policy exception, since the value mismatches
      return zx_futex_requeue(&futex1, 1, 1, &futex2, 1, bad_handle);
    }
    case BadHandleTestCase::kInvalid:
      break;
  }
  ZX_PANIC("Need to pass a known argument");
}

namespace {

void LaunchTestCase(const char* test_case, zx_info_process_v2_t* proc_info) {
  // Set up a subjob and subprocess in order to set BAD_HANDLE policy.
  zx::job job;
  ASSERT_OK(zx::job::create(*zx::job::default_job(), 0u, &job));
  zx_policy_basic_v2_t policy[] = {{.condition = ZX_POL_BAD_HANDLE,
                                    .action = ZX_POL_ACTION_ALLOW_EXCEPTION,
                                    .flags = ZX_POL_OVERRIDE_DENY}};
  ASSERT_OK(job.set_policy(ZX_JOB_POL_RELATIVE, ZX_JOB_POL_BASIC_V2, policy,
                           static_cast<uint32_t>(std::size(policy))));

  // Make sure that we have a program name and have not already started.
  ASSERT_NOT_NULL(ExternalThread::ProgramName());

  const char* args[] = {ExternalThread::ProgramName(), BadHandleFlagTest(), test_case, nullptr};
  zx::process proc;
  char err_msg_out[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
  zx_status_t res =
      fdio_spawn_etc(job.get(), FDIO_SPAWN_CLONE_ALL, ExternalThread::ProgramName(), args, nullptr,
                     0, nullptr, proc.reset_and_get_address(), err_msg_out);
  ASSERT_OK(res, "%s", err_msg_out);

  res = proc.wait_one(ZX_PROCESS_TERMINATED, zx::time::infinite(), nullptr);
  ASSERT_OK(res);

  ASSERT_OK(proc.get_info(ZX_INFO_PROCESS_V2, proc_info, sizeof(*proc_info), nullptr, nullptr));
}

// This is a test for fxbug.dev/41780 where we accidentally enforced the BAD_HANDLE policy in a case
// where the futex value mismatched expectations.
TEST(BadHandleTest, WaitBadHandleWithMismatchedValueDoesNotExit) {
  zx_info_process_v2_t proc_info;
  ASSERT_NO_FATAL_FAILURES(LaunchTestCase("no_match_wait", &proc_info));
  // We should see ZX_ERR_BAD_STATE since the futex value mismatched
  ASSERT_EQ(proc_info.return_code, ZX_ERR_BAD_STATE);
}

TEST(BadHandleTest, WaitBadHandleWithMatchedValueExits) {
  zx_info_process_v2_t proc_info;
  ASSERT_NO_FATAL_FAILURES(LaunchTestCase("match_wait", &proc_info));
  // We should see an exception kill due to the policy violation
  ASSERT_EQ(proc_info.return_code, ZX_TASK_RETCODE_EXCEPTION_KILL);
}

TEST(BadHandleTest, RequeueBadHandleWithMismatchedValueDoesNotExit) {
  zx_info_process_v2_t proc_info;
  ASSERT_NO_FATAL_FAILURES(LaunchTestCase("no_match_requeue", &proc_info));
  // We should see ZX_ERR_BAD_STATE since the futex value mismatched
  ASSERT_EQ(proc_info.return_code, ZX_ERR_BAD_STATE);
}

TEST(BadHandleTest, RequeueBadHandleWithMatchedValueExits) {
  zx_info_process_v2_t proc_info;
  ASSERT_NO_FATAL_FAILURES(LaunchTestCase("match_requeue", &proc_info));
  // We should see an exception kill due to the policy violation
  ASSERT_EQ(proc_info.return_code, ZX_TASK_RETCODE_EXCEPTION_KILL);
}

}  // namespace
