// Copyright 2018 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 <lib/cksum.h>
#include <stdint.h>
#include <zircon/boot/crash-reason.h>
#include <zircon/errors.h>

#include <array>
#include <vector>

#include <ram-crashlog/ram-crashlog.h>
#include <zxtest/zxtest.h>

namespace {

// The buffer we will use as our target for serializing the crashlog during testing.
uint8_t crashlog_buffer[256];
constexpr uint32_t TEST_PAYLOAD_MAX = sizeof(crashlog_buffer) - sizeof(ram_crashlog_t);
constexpr uint8_t TEST_PAYLOAD_FILL = 0xA5;
static_assert(sizeof(crashlog_buffer) > sizeof(ram_crashlog_t),
              "Test buffer must be able to hold _some_ payload");
static_assert(TEST_PAYLOAD_MAX >= 2,
              "Test buffer must be able to hold a payload of at least 2 bytes");

constexpr const char LONG_PAYLOAD[] =
    "Four score and seven years ago our fathers brought forth on this continent, a new nation, "
    "conceived in Liberty, and dedicated to the proposition that all men are created equal.  Now "
    "we are engaged in a great civil war, testing whether that nation, or any nation so conceived "
    "and so dedicated, can long endure. We are met on a great battle-field of that war. We have "
    "come to dedicate a portion of that field, as a final resting place for those who here gave "
    "their lives that that nation might live. It is altogether fitting and proper that we should "
    "do this.  But, in a larger sense, we can not dedicate—we can not consecrate—we can not "
    "hallow—this ground. The brave men, living and dead, who struggled here, have consecrated it, "
    "far above our poor power to add or detract. The world will little note, nor long remember "
    "what we say here, but it can never forget what they did here. It is for us the living, "
    "rather, to be dedicated here to the unfinished work which they who fought here have thus far "
    "so nobly advanced. It is rather for us to be here dedicated to the great task remaining "
    "before us—that from these honored dead we take increased devotion to that cause for which "
    "they gave the last full measure of devotion—that we here highly resolve that these dead shall "
    "not have died in vain—that this nation, under God, shall have a new birth of freedom—and that "
    "government of the people, by the people, for the people, shall not perish from the earth.";
constexpr uint32_t LONG_PAYLOAD_LEN = sizeof(LONG_PAYLOAD) - 1;
static_assert(LONG_PAYLOAD_LEN > TEST_PAYLOAD_MAX,
              "Long payload must be longer than the max test payload");

// A constant test vector we use in several tests.  This "crashlog" image
// contains two valid headers, and indicates hdr[0] as being the active header.
// Starting from this template, many types of tests can be constructed.
constexpr ram_crashlog_t TEST_LOG = {
    .magic = RAM_CRASHLOG_MAGIC_0,
    .hdr =
        {
            {
                .uptime = 0xabcde,
                .reason = ZirconCrashReason::Panic,
                .payload_len = TEST_PAYLOAD_MAX,
                .payload_crc32 = 0xaa0b6321,  // CRC for a payload of all 0xA5s
                .header_crc32 = 0xd8d492b1,
            },
            {
                .uptime = 0x12345,
                .reason = ZirconCrashReason::Unknown,
                .payload_len = 0,
                .payload_crc32 = 0x0,
                .header_crc32 = 0xe082e1b7,
            },
        },
};

TEST(RamCrashlogTestCase, ValidBufferRequired) {
  zx_status_t res = ram_crashlog_stow(nullptr, 0, nullptr, 0, ZirconCrashReason::Unknown, 0);
  EXPECT_STATUS(res, ZX_ERR_INVALID_ARGS);

  res = ram_crashlog_stow(crashlog_buffer, sizeof(crashlog_buffer), nullptr, 25,
                          ZirconCrashReason::Unknown, 0);
  EXPECT_STATUS(res, ZX_ERR_INVALID_ARGS);
}

TEST(RamCrashlogTestCase, BufferTooSmall) {
  // Attempt to stash a crashlog into a location which cannot possibly fit the
  // internal header and verify that it informs us that our buffer is too small.
  uint8_t tiny_buf[1];
  zx_status_t res =
      ram_crashlog_stow(tiny_buf, sizeof(tiny_buf), nullptr, 0, ZirconCrashReason::Unknown, 0);
  EXPECT_STATUS(res, ZX_ERR_BUFFER_TOO_SMALL);

  // Likewise, we cannot recover a crashlog from a user supplied buffer which is too small to
  // possibly hold a crashlog.
  recovered_ram_crashlog_t rlog;
  res = ram_crashlog_recover(tiny_buf, sizeof(tiny_buf), &rlog);
  EXPECT_STATUS(res, ZX_ERR_BUFFER_TOO_SMALL);
}

TEST(RamCrashlogTestCase, ValidReasonRequired) {
  // When stowing a crashlog, require that the crash reason given is a valid one
  // (even if the reason is unknown).
  //
  struct Reason {
    ZirconCrashReason reason;
    bool is_valid;
  };

  constexpr std::array REASONS{
      Reason{ZirconCrashReason::Unknown, true},
      Reason{ZirconCrashReason::NoCrash, true},
      Reason{ZirconCrashReason::Oom, true},
      Reason{ZirconCrashReason::Panic, true},
      Reason{ZirconCrashReason::SoftwareWatchdog, true},
      Reason{ZirconCrashReason::UserspaceRootJobTermination, true},
      Reason{ZirconCrashReason::Invalid, false},
      Reason{static_cast<ZirconCrashReason>(0xbaadf00d), false},
  };

  for (const auto& r : REASONS) {
    zx_status_t res =
        ram_crashlog_stow(crashlog_buffer, sizeof(crashlog_buffer), nullptr, 0, r.reason, 0);
    EXPECT_STATUS(res, r.is_valid ? ZX_OK : ZX_ERR_INVALID_ARGS);
  }
}

TEST(RamCrashlogTestCase, IntegrityChecks) {
  // Start by using our test header template to simulate a crashlog stowed in
  // RAM, and make sure that it passes the default integrity checks.
  ram_crashlog_t& log = *(reinterpret_cast<ram_crashlog_t*>(crashlog_buffer));
  uint8_t* payload = reinterpret_cast<uint8_t*>(&log + 1);
  memset(crashlog_buffer, TEST_PAYLOAD_FILL, sizeof(crashlog_buffer));
  log = TEST_LOG;

  // Recover the log, and make sure that the recovered data matches what we
  // expect.  Right now, the magic number indicates that the active header is
  // hdr[0].
  recovered_ram_crashlog_t rlog;
  zx_status_t res;

  res = ram_crashlog_recover(crashlog_buffer, sizeof(crashlog_buffer), &rlog);
  ASSERT_OK(res);
  EXPECT_EQ(TEST_LOG.hdr[0].uptime, rlog.uptime);
  EXPECT_EQ(TEST_LOG.hdr[0].reason, rlog.reason);
  EXPECT_EQ(TEST_LOG.hdr[0].payload_len, rlog.payload_len);
  EXPECT_TRUE(rlog.payload_valid);
  EXPECT_EQ(payload, rlog.payload);

  // Corrupt the payload and verify that the log is still recoverable, but that
  // it clearly indicates that the payload portion of the log may have been
  // damaged.
  payload[0] = ~payload[0];
  res = ram_crashlog_recover(crashlog_buffer, sizeof(crashlog_buffer), &rlog);
  ASSERT_OK(res);
  EXPECT_EQ(TEST_LOG.hdr[0].uptime, rlog.uptime);
  EXPECT_EQ(TEST_LOG.hdr[0].reason, rlog.reason);
  EXPECT_EQ(TEST_LOG.hdr[0].payload_len, rlog.payload_len);
  EXPECT_FALSE(rlog.payload_valid);
  EXPECT_EQ(payload, rlog.payload);

  // Fix the damage we just did to the payload, then update the payload length
  // length in hdr[0] to be impossibly long (longer than the buffer we provide,
  // once the fixed overhead is accounted for).  Make sure to update the header
  // CRC.  Finally, attempt to recover the log.  Again, this should succeed, but
  // indicate that the payload may be damaged.  Additionally, it should report a
  // length which is equal to the space we have remaining in the crashlog buffer
  // after the log headers.
  payload[0] = TEST_PAYLOAD_FILL;
  log.hdr[0].payload_len = sizeof(crashlog_buffer);
  log.hdr[0].header_crc32 = crc32(0, reinterpret_cast<const uint8_t*>(log.hdr),
                                  offsetof(ram_crashlog_header_t, header_crc32));
  res = ram_crashlog_recover(crashlog_buffer, sizeof(crashlog_buffer), &rlog);
  ASSERT_OK(res);
  EXPECT_EQ(TEST_LOG.hdr[0].uptime, rlog.uptime);
  EXPECT_EQ(TEST_LOG.hdr[0].reason, rlog.reason);
  EXPECT_EQ(TEST_PAYLOAD_MAX, rlog.payload_len);
  EXPECT_FALSE(rlog.payload_valid);
  EXPECT_EQ(payload, rlog.payload);

  // Corrupt the header by restoring the old payload length, but not updating
  // the header CRC, then attempt to recover the log.  This should simply fail.
  // We cannot currently recover the log if the active header is damaged.
  log.hdr[0].payload_len = TEST_LOG.hdr[0].payload_len;
  res = ram_crashlog_recover(crashlog_buffer, sizeof(crashlog_buffer), &rlog);
  EXPECT_STATUS(ZX_ERR_IO_DATA_INTEGRITY, res);

  // Flip the magic number to indicate that the other header is active, and
  // re-verify.  This should succeed, even though we have corrupted hdr[0].
  // This header should indicate a valid but zero-length payload.
  log.magic = RAM_CRASHLOG_MAGIC_1;
  res = ram_crashlog_recover(crashlog_buffer, sizeof(crashlog_buffer), &rlog);
  ASSERT_OK(res);
  EXPECT_EQ(TEST_LOG.hdr[1].uptime, rlog.uptime);
  EXPECT_EQ(TEST_LOG.hdr[1].reason, rlog.reason);
  EXPECT_EQ(TEST_LOG.hdr[1].payload_len, rlog.payload_len);
  EXPECT_TRUE(rlog.payload_valid);
  EXPECT_NULL(rlog.payload);

  // Corrupt the contents of hdr[1] and make sure that it fails to recover.
  log.hdr[1].payload_len = 1;
  res = ram_crashlog_recover(crashlog_buffer, sizeof(crashlog_buffer), &rlog);
  EXPECT_STATUS(ZX_ERR_IO_DATA_INTEGRITY, res);

  // Finally, fix all of the headers by going back to the template image, but
  // corrupt the magic number so that we don't know which header (if any) is
  // active.  This should also produce a DATA_INTEGRITY error.
  log = TEST_LOG;
  log.magic = 0x0123456789ABCDEF;
  res = ram_crashlog_recover(crashlog_buffer, sizeof(crashlog_buffer), &rlog);
  EXPECT_STATUS(ZX_ERR_IO_DATA_INTEGRITY, res);
}

TEST(RamCrashlogTestCase, Stow) {
  // Start with an invalid crashlog state (we just use a buffer full of 0s).
  // Verify that this fails to recover.
  ram_crashlog_t& log = *(reinterpret_cast<ram_crashlog_t*>(crashlog_buffer));
  uint8_t* payload = reinterpret_cast<uint8_t*>(&log + 1);
  memset(crashlog_buffer, 0, sizeof(crashlog_buffer));

  recovered_ram_crashlog_t rlog;
  zx_status_t res;
  res = ram_crashlog_recover(crashlog_buffer, sizeof(crashlog_buffer), &rlog);
  EXPECT_STATUS(ZX_ERR_IO_DATA_INTEGRITY, res);

  // Now stow a new log with no payload and verify that it holds the values we
  // told it to.
  res = ram_crashlog_stow(crashlog_buffer, sizeof(crashlog_buffer), nullptr, 0,
                          ZirconCrashReason::Unknown, 4599);
  ASSERT_OK(res);

  res = ram_crashlog_recover(crashlog_buffer, sizeof(crashlog_buffer), &rlog);
  ASSERT_OK(res);
  EXPECT_EQ(4599, rlog.uptime);
  EXPECT_EQ(ZirconCrashReason::Unknown, rlog.reason);
  EXPECT_EQ(0, rlog.payload_len);
  EXPECT_TRUE(rlog.payload_valid);
  EXPECT_NULL(rlog.payload);

  // While we do not specific which header the implementation will use when
  // replacing an invalid log with a valid log, we _do_ specify that the log
  // headers should be double buffered.  Now that the implementation has chosen
  // a header, we expect the choice of header to toggle each time we stow a new
  // log.
  uint64_t expected_magic =
      (log.magic == RAM_CRASHLOG_MAGIC_0) ? RAM_CRASHLOG_MAGIC_1 : RAM_CRASHLOG_MAGIC_0;

  // Stow a new crashlog, but this time stash a payload which fits in our space, but
  // does not fill it entirely.
  constexpr uint32_t TO_STOW = TEST_PAYLOAD_MAX / 2;
  memset(payload, 0, TEST_PAYLOAD_MAX);
  res = ram_crashlog_stow(crashlog_buffer, sizeof(crashlog_buffer), LONG_PAYLOAD, TO_STOW,
                          ZirconCrashReason::Oom, 9945);
  ASSERT_OK(res);

  res = ram_crashlog_recover(crashlog_buffer, sizeof(crashlog_buffer), &rlog);
  ASSERT_OK(res);
  EXPECT_EQ(9945, rlog.uptime);
  EXPECT_EQ(ZirconCrashReason::Oom, rlog.reason);
  EXPECT_EQ(TO_STOW, rlog.payload_len);
  EXPECT_TRUE(rlog.payload_valid);
  EXPECT_BYTES_EQ(LONG_PAYLOAD, rlog.payload, rlog.payload_len);
  EXPECT_EQ(expected_magic,
            log.magic);  // Peek under the hood and validate this implementation detail.

  // Attempt to stash a log with a payload which does _not_ fit into our
  // available space.  This should succeed, but the payload (once recovered)
  // should be truncated.
  expected_magic =
      (log.magic == RAM_CRASHLOG_MAGIC_0) ? RAM_CRASHLOG_MAGIC_1 : RAM_CRASHLOG_MAGIC_0;

  memset(payload, 0xFF, TEST_PAYLOAD_MAX);
  res = ram_crashlog_stow(crashlog_buffer, sizeof(crashlog_buffer), LONG_PAYLOAD, LONG_PAYLOAD_LEN,
                          ZirconCrashReason::Panic, 314159);
  ASSERT_OK(res);

  res = ram_crashlog_recover(crashlog_buffer, sizeof(crashlog_buffer), &rlog);
  ASSERT_OK(res);
  EXPECT_EQ(314159, rlog.uptime);
  EXPECT_EQ(ZirconCrashReason::Panic, rlog.reason);
  EXPECT_EQ(TEST_PAYLOAD_MAX, rlog.payload_len);
  EXPECT_TRUE(rlog.payload_valid);
  EXPECT_BYTES_EQ(LONG_PAYLOAD, rlog.payload, rlog.payload_len);
  EXPECT_EQ(expected_magic,
            log.magic);  // Peek under the hood and validate this implementation detail.

  // Attempt to stash a log with a payload which has been pre-rendered by the
  // user to the location immediately following the crashlog headers.
  expected_magic =
      (log.magic == RAM_CRASHLOG_MAGIC_0) ? RAM_CRASHLOG_MAGIC_1 : RAM_CRASHLOG_MAGIC_0;

  memset(payload, 0xFF, TEST_PAYLOAD_MAX);
  memcpy(payload, LONG_PAYLOAD, std::min(TEST_PAYLOAD_MAX, LONG_PAYLOAD_LEN));

  res = ram_crashlog_stow(crashlog_buffer, sizeof(crashlog_buffer), payload, LONG_PAYLOAD_LEN,
                          ZirconCrashReason::SoftwareWatchdog, 877265);
  ASSERT_OK(res);

  res = ram_crashlog_recover(crashlog_buffer, sizeof(crashlog_buffer), &rlog);
  ASSERT_OK(res);
  EXPECT_EQ(877265, rlog.uptime);
  EXPECT_EQ(ZirconCrashReason::SoftwareWatchdog, rlog.reason);
  EXPECT_EQ(TEST_PAYLOAD_MAX, rlog.payload_len);
  EXPECT_TRUE(rlog.payload_valid);
  EXPECT_BYTES_EQ(LONG_PAYLOAD, rlog.payload, rlog.payload_len);
  EXPECT_EQ(expected_magic,
            log.magic);  // Peek under the hood and validate this implementation detail.

  // Attempt to stow the crashlog, indicating that the payload is located at any
  // of the other positions inside of the crashlog buffer.  This should always
  // fail with INVALID_ARGS.  When we are finished, the contents of a recovered
  // crashlog buffer should remain unchanged from the last successful attempt to
  // stow it.
  for (uint8_t* ptr = crashlog_buffer; ptr < crashlog_buffer + sizeof(crashlog_buffer); ++ptr) {
    if (ptr == payload) {
      continue;
    }
    res = ram_crashlog_stow(crashlog_buffer, sizeof(crashlog_buffer), ptr, LONG_PAYLOAD_LEN,
                            ZirconCrashReason::SoftwareWatchdog, 877265);
    ASSERT_STATUS(res, ZX_ERR_INVALID_ARGS);
  }
}

}  // namespace
