// Copyright 2019 The Chromium 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 "sql/sandboxed_vfs_file.h"

#include <atomic>
#include <cstring>
#include <type_traits>
#include <utility>

#include "base/check_op.h"
#include "base/files/file.h"
#include "base/notreached.h"
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
#include "sql/initialization.h"
#include "sql/sandboxed_vfs.h"
#include "third_party/sqlite/sqlite3.h"

namespace sql {

namespace {

int SandboxedClose(sqlite3_file* file) {
  return SandboxedVfsFile::FromSqliteFile(*file).Close();
}
int SandboxedRead(sqlite3_file* file,
                  void* buffer,
                  int size,
                  sqlite3_int64 offset) {
  return SandboxedVfsFile::FromSqliteFile(*file).Read(buffer, size, offset);
}
int SandboxedWrite(sqlite3_file* file,
                   const void* buffer,
                   int size,
                   sqlite3_int64 offset) {
  return SandboxedVfsFile::FromSqliteFile(*file).Write(buffer, size, offset);
}
int SandboxedTruncate(sqlite3_file* file, sqlite3_int64 size) {
  return SandboxedVfsFile::FromSqliteFile(*file).Truncate(size);
}
int SandboxedSync(sqlite3_file* file, int flags) {
  return SandboxedVfsFile::FromSqliteFile(*file).Sync(flags);
}
int SandboxedFileSize(sqlite3_file* file, sqlite3_int64* result_size) {
  return SandboxedVfsFile::FromSqliteFile(*file).FileSize(result_size);
}
int SandboxedLock(sqlite3_file* file, int mode) {
  return SandboxedVfsFile::FromSqliteFile(*file).Lock(mode);
}
int SandboxedUnlock(sqlite3_file* file, int mode) {
  return SandboxedVfsFile::FromSqliteFile(*file).Unlock(mode);
}
int SandboxedCheckReservedLock(sqlite3_file* file, int* has_reserved_lock) {
  return SandboxedVfsFile::FromSqliteFile(*file).CheckReservedLock(
      has_reserved_lock);
}
int SandboxedFileControl(sqlite3_file* file, int opcode, void* data) {
  return SandboxedVfsFile::FromSqliteFile(*file).FileControl(opcode, data);
}
int SandboxedSectorSize(sqlite3_file* file) {
  return SandboxedVfsFile::FromSqliteFile(*file).SectorSize();
}
int SandboxedDeviceCharacteristics(sqlite3_file* file) {
  return SandboxedVfsFile::FromSqliteFile(*file).DeviceCharacteristics();
}
int SandboxedShmMap(sqlite3_file* file,
                    int page_index,
                    int page_size,
                    int extend_file_if_needed,
                    void volatile** result) {
  return SandboxedVfsFile::FromSqliteFile(*file).ShmMap(
      page_index, page_size, extend_file_if_needed, result);
}
int SandboxedShmLock(sqlite3_file* file, int offset, int size, int flags) {
  return SandboxedVfsFile::FromSqliteFile(*file).ShmLock(offset, size, flags);
}
void SandboxedShmBarrier(sqlite3_file* file) {
  SandboxedVfsFile::FromSqliteFile(*file).ShmBarrier();
}
int SandboxedShmUnmap(sqlite3_file* file, int also_delete_file) {
  return SandboxedVfsFile::FromSqliteFile(*file).ShmUnmap(also_delete_file);
}
int SandboxedFetch(sqlite3_file* file,
                   sqlite3_int64 offset,
                   int size,
                   void** result) {
  return SandboxedVfsFile::FromSqliteFile(*file).Fetch(offset, size, result);
}
int SandboxedUnfetch(sqlite3_file* file,
                     sqlite3_int64 offset,
                     void* fetch_result) {
  return SandboxedVfsFile::FromSqliteFile(*file).Unfetch(offset, fetch_result);
}

const sqlite3_io_methods* GetSqliteIoMethods() {
  // VFS IO API entry points are listed at
  // https://www.sqlite.org/c3ref/io_methods.html
  static constexpr int kSqliteVfsIoApiVersion = 3;

  static const sqlite3_io_methods kIoMethods = {
      kSqliteVfsIoApiVersion,
      SandboxedClose,
      SandboxedRead,
      SandboxedWrite,
      SandboxedTruncate,
      SandboxedSync,
      SandboxedFileSize,
      SandboxedLock,
      SandboxedUnlock,
      SandboxedCheckReservedLock,
      SandboxedFileControl,
      SandboxedSectorSize,
      SandboxedDeviceCharacteristics,
      SandboxedShmMap,
      SandboxedShmLock,
      SandboxedShmBarrier,
      SandboxedShmUnmap,
      SandboxedFetch,
      SandboxedUnfetch,
  };

  return &kIoMethods;
}

}  // namespace

// static
void SandboxedVfsFile::Create(base::File file,
                              base::FilePath file_path,
                              SandboxedVfs* vfs,
                              sqlite3_file& buffer) {
  SandboxedVfsFileSqliteBridge& bridge =
      SandboxedVfsFileSqliteBridge::FromSqliteFile(buffer);
  bridge.sandboxed_vfs_file =
      new SandboxedVfsFile(std::move(file), std::move(file_path), vfs);
  bridge.sqlite_file.pMethods = GetSqliteIoMethods();
}

// static
SandboxedVfsFile& SandboxedVfsFile::FromSqliteFile(sqlite3_file& sqlite_file) {
  return *SandboxedVfsFileSqliteBridge::FromSqliteFile(sqlite_file)
              .sandboxed_vfs_file;
}

int SandboxedVfsFile::Close() {
  file_.Close();
  delete this;
  return SQLITE_OK;
}

int SandboxedVfsFile::Read(void* buffer, int size, sqlite3_int64 offset) {
  DCHECK(buffer);
  DCHECK_GE(size, 0);
  DCHECK_GE(offset, 0);
  char* data = reinterpret_cast<char*>(buffer);

  // If we supported mmap()ed files, we'd check for a memory mapping here,
  // and try to fill as much of the request as possible from the mmap()ed
  // region.

  int bytes_read = file_.Read(offset, data, size);
  DCHECK_LE(bytes_read, size);
  if (bytes_read == size)
    return SQLITE_OK;

  // SQLite first reads the database header without locking the file. On
  // Windows, this read will fail if there is an exclusive lock on the file,
  // even if the current process owns that lock.
  if (sqlite_lock_mode_ == SQLITE_LOCK_NONE) {
    // The unlocked read is considered an optimization. SQLite can continue even
    // if the read fails, as long as failure is communicated by zeroing out the
    // output buffer.
    std::memset(data, 0, size);
    return SQLITE_OK;
  }

  if (bytes_read < 0) {
    vfs_->SetLastError(base::File::GetLastFileError());
    return SQLITE_IOERR_READ;
  }

  // SQLite requires that we fill the unread bytes in the buffer with zeros.
  std::memset(data + bytes_read, 0, size - bytes_read);
  return SQLITE_IOERR_SHORT_READ;
}

int SandboxedVfsFile::Write(const void* buffer,
                            int size,
                            sqlite3_int64 offset) {
  DCHECK(buffer);
  DCHECK_GE(size, 0);
  DCHECK_GE(offset, 0);
  const char* data = reinterpret_cast<const char*>(buffer);

  // If we supported mmap()ed files, we'd check for a memory mapping here,
  // and try to fill as much of the request as possible by copying to the
  // mmap()ed region.

  int bytes_written = file_.Write(offset, data, size);
  DCHECK_LE(bytes_written, size);
  if (bytes_written >= size)
    return SQLITE_OK;

  base::File::Error last_error = base::File::GetLastFileError();
  vfs_->SetLastError(last_error);
  if (last_error == base::File::Error::FILE_ERROR_NO_SPACE)
    return SQLITE_FULL;

  return SQLITE_IOERR_WRITE;
}

int SandboxedVfsFile::Truncate(sqlite3_int64 size) {
  if (file_.SetLength(size))
    return SQLITE_OK;

  // On macOS < 10.15, the default sandbox blocks ftruncate(), so we have to use
  // a sync mojo IPC to ask the browser process to call ftruncate() for us.
  //
  // TODO(crbug.com/1084565): Figure out if we can allow ftruncate() in renderer
  // and utility processes. It would be useful for low-level storage APIs, like
  // the upcoming filesystem API.
  if (vfs_->delegate()->SetFileLength(file_path_, file_,
                                      static_cast<size_t>(size))) {
    return SQLITE_OK;
  }

  return SQLITE_IOERR_TRUNCATE;
}

int SandboxedVfsFile::Sync(int flags) {
  // NOTE: SQLite passes in (SQLITE_SYNC_NORMAL or SQLITE_SYNC_FULL),
  //       potentially OR-ed with SQLITE_SYNC_DATAONLY. Implementing these could
  //       lead to better performance.
  if (!file_.Flush()) {
    vfs_->SetLastError(base::File::GetLastFileError());
    return SQLITE_IOERR_FSYNC;
  }

  // The unix VFS also syncs the file's directory on the first xSync() call.
  // Chrome's LevelDB Env implementation does the same for specific files
  // (database manifests).
  //
  // For WebSQL, we would want to sync the directory at file open time, when the
  // file is opened for writing.

  return SQLITE_OK;
}

int SandboxedVfsFile::FileSize(sqlite3_int64* result_size) {
  int64_t length = file_.GetLength();
  if (length < 0) {
    vfs_->SetLastError(base::File::GetLastFileError());
    return SQLITE_IOERR_FSTAT;
  }

  // SQLite's unix VFS reports 1-byte files as empty. This is documented as a
  // workaround for a fairly obscure bug. See unixFileSize() in os_unix.c.
  if (length == 1)
    length = 0;

  *result_size = length;
  return SQLITE_OK;
}

namespace {

// True if our simplified implementation uses an exclusive lock for a mode.
bool IsExclusiveLockMode(int sqlite_lock_mode) {
  switch (sqlite_lock_mode) {
    case SQLITE_LOCK_NONE:
    case SQLITE_LOCK_SHARED:
      return false;

    case SQLITE_LOCK_RESERVED:
    case SQLITE_LOCK_PENDING:
    case SQLITE_LOCK_EXCLUSIVE:
      return true;
  }

  NOTREACHED() << "Unsupported mode: " << sqlite_lock_mode;
  return false;
}

}  // namespace

int SandboxedVfsFile::Lock(int mode) {
#if defined(OS_FUCHSIA)
  return SQLITE_IOERR_LOCK;
#else
  base::File::LockMode file_lock_mode = base::File::LockMode::kExclusive;

  switch (mode) {
    case SQLITE_LOCK_NONE:
      return SQLITE_OK;

    case SQLITE_LOCK_SHARED:
      if (sqlite_lock_mode_ != SQLITE_LOCK_NONE)
        return SQLITE_OK;

      file_lock_mode = base::File::LockMode::kShared;
      break;

    case SQLITE_LOCK_RESERVED:
      // A SHARED lock is required before a RESERVED lock is acquired.
      DCHECK_EQ(sqlite_lock_mode_, SQLITE_LOCK_SHARED);
      file_lock_mode = base::File::LockMode::kExclusive;
      break;

    case SQLITE_LOCK_PENDING:
      // A SHARED lock is required before a PENDING lock is acquired. The caller
      // may have a RESERVED lock.
      if (sqlite_lock_mode_ == SQLITE_LOCK_RESERVED) {
        sqlite_lock_mode_ = mode;
        return SQLITE_OK;
      }

      DCHECK_EQ(sqlite_lock_mode_, SQLITE_LOCK_SHARED);
      file_lock_mode = base::File::LockMode::kExclusive;
      break;

    case SQLITE_LOCK_EXCLUSIVE:
      if (IsExclusiveLockMode(sqlite_lock_mode_)) {
        sqlite_lock_mode_ = mode;
        return SQLITE_OK;
      }
      file_lock_mode = base::File::LockMode::kExclusive;
      break;

    default:
      NOTREACHED() << "Unimplemented xLock() mode: " << mode;
  }

  DCHECK_EQ(IsExclusiveLockMode(mode),
            file_lock_mode == base::File::LockMode::kExclusive)
      << "Incorrect file_lock_mode logic for SQLite mode: " << mode;

  // On POSIX, it would be possible to upgrade atomically from a shared lock to
  // an exclusive lock. This implementation prioritizes the simplicity of no
  // platform-specific code over being faster in high contention cases.
  if (sqlite_lock_mode_ != SQLITE_LOCK_NONE) {
    base::File::Error error = file_.Unlock();
    if (error != base::File::FILE_OK) {
      vfs_->SetLastError(base::File::GetLastFileError());
      return SQLITE_IOERR_LOCK;
    }
    sqlite_lock_mode_ = SQLITE_LOCK_NONE;
  }

  base::File::Error error = file_.Lock(file_lock_mode);
  if (error != base::File::FILE_OK) {
    vfs_->SetLastError(base::File::GetLastFileError());
    return SQLITE_IOERR_LOCK;
  }

  sqlite_lock_mode_ = mode;
  return SQLITE_OK;
#endif  // defined(OS_FUCHSIA)
}

int SandboxedVfsFile::Unlock(int mode) {
  // No-op if we're already unlocked or at the requested mode.
  if (sqlite_lock_mode_ == mode || sqlite_lock_mode_ == SQLITE_LOCK_NONE)
    return SQLITE_OK;

#if defined(OS_FUCHSIA)
  return SQLITE_IOERR_UNLOCK;
#else
  // On POSIX, it is possible to downgrade atomically from an exclusive lock to
  // a shared lock. SQLite's unix VFS takes advantage of this. This
  // implementation prioritizes the simplicity of no platform-specific code over
  // being faster in high contention cases.
  base::File::Error error = file_.Unlock();
  if (error != base::File::FILE_OK) {
    vfs_->SetLastError(base::File::GetLastFileError());
    return SQLITE_IOERR_UNLOCK;
  }

  if (mode == SQLITE_LOCK_NONE) {
    sqlite_lock_mode_ = mode;
    return SQLITE_OK;
  }

  DCHECK_EQ(mode, SQLITE_LOCK_SHARED);
  error = file_.Lock(base::File::LockMode::kShared);
  if (error == base::File::FILE_OK) {
    sqlite_lock_mode_ = mode;
    return SQLITE_OK;
  }

  // Gave up the exclusive lock, but failed to get a shared lock.
  vfs_->SetLastError(base::File::GetLastFileError());
  sqlite_lock_mode_ = SQLITE_LOCK_NONE;
  return SQLITE_IOERR_UNLOCK;
#endif  // defined(OS_FUCHSIA)
}

int SandboxedVfsFile::CheckReservedLock(int* has_reserved_lock) {
  if (IsExclusiveLockMode(sqlite_lock_mode_)) {
    *has_reserved_lock = 1;
    return SQLITE_OK;
  }

  if (sqlite_lock_mode_ == SQLITE_LOCK_SHARED) {
    // Lock modes at or above RESERVED map to exclusive locks in our simplified
    // implementation. If this process has a shared lock, no other process can
    // have an exclusive lock.
    *has_reserved_lock = 0;
    return SQLITE_OK;
  }

#if defined(OS_FUCHSIA)
  return SQLITE_IOERR_CHECKRESERVEDLOCK;
#else
  // On POSIX, it's possible to query the existing lock state of a file. The
  // SQLite unix VFS takes advantage of this. On Windows, this isn't the case.
  // Follow the strategy of the Windows VFS, which checks by trying to get an
  // exclusive lock on the file.
  base::File::Error error = file_.Lock(base::File::LockMode::kShared);
  if (error != base::File::FILE_OK) {
    *has_reserved_lock = 1;
    return SQLITE_OK;
  }

  *has_reserved_lock = 0;
  if (file_.Unlock() == base::File::FILE_OK)
    return SQLITE_OK;

  // We acquired a shared lock that we can't get rid of.
  sqlite_lock_mode_ = SQLITE_LOCK_SHARED;
  return SQLITE_IOERR_CHECKRESERVEDLOCK;
#endif  // defined(OS_FUCHSIA)
}

int SandboxedVfsFile::FileControl(int opcode, void* data) {
  switch (opcode) {
    case SQLITE_FCNTL_MMAP_SIZE:
      // Implementing memory-mapping will require handling this correctly.
      return SQLITE_NOTFOUND;
    default:
      return SQLITE_NOTFOUND;
  }
}

int SandboxedVfsFile::SectorSize() {
  return 0;
}

int SandboxedVfsFile::DeviceCharacteristics() {
  // TODO(pwnall): Figure out if we can get away with returning 0 on Windows.
#if defined(OS_WIN)
  return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
#else
  // NOTE: SQLite's unix VFS attempts to detect the underlying filesystem and
  // sets some flags based on the result.
  return 0;
#endif  // OS_WIN
}

int SandboxedVfsFile::ShmMap(int page_index,
                             int page_size,
                             int extend_file_if_needed,
                             void volatile** result) {
  DCHECK_GE(page_index, 0);
  DCHECK_GE(page_size, 0);
  DCHECK(result);

  // https://www.sqlite.org/wal.html#use_of_wal_without_shared_memory states
  // that SQLite only attempts to use shared memory "-shm" files for databases
  // in WAL mode that may be accessed by multiple processes (are not EXCLUSIVE).
  //
  // Chrome will not only use WAL mode on EXCLUSIVE databases.
  NOTREACHED() << "SQLite should not attempt to use shared memory";

  *result = nullptr;
  return SQLITE_IOERR;
}

int SandboxedVfsFile::ShmLock(int offset, int size, int flags) {
  DCHECK_GE(offset, 0);
  DCHECK_GE(size, 0);

  // https://www.sqlite.org/wal.html#use_of_wal_without_shared_memory states
  // that SQLite only attempts to use shared memory "-shm" files for databases
  // in WAL mode that may be accessed by multiple processes (are not EXCLUSIVE).
  //
  // Chrome will not only use WAL mode on EXCLUSIVE databases.
  NOTREACHED() << "SQLite should not attempt to use shared memory";

  return SQLITE_IOERR;
}

void SandboxedVfsFile::ShmBarrier() {
  // https://www.sqlite.org/wal.html#use_of_wal_without_shared_memory states
  // that SQLite only attempts to use shared memory "-shm" files for databases
  // in WAL mode that may be accessed by multiple processes (are not EXCLUSIVE).
  //
  // Chrome will not only use WAL mode on EXCLUSIVE databases.
  NOTREACHED() << "SQLite should not attempt to use shared memory";

  // All writes to shared memory that have already been issued before this
  // function is called must complete before the function returns.
  std::atomic_thread_fence(std::memory_order_acq_rel);
}

int SandboxedVfsFile::ShmUnmap(int also_delete_file) {
  // https://www.sqlite.org/wal.html#use_of_wal_without_shared_memory states
  // that SQLite only attempts to use shared memory "-shm" files for databases
  // in WAL mode that may be accessed by multiple processes (are not EXCLUSIVE).
  //
  // Chrome will not only use WAL mode on EXCLUSIVE databases.
  NOTREACHED() << "SQLite should not attempt to use shared memory";

  return SQLITE_IOERR;
}

int SandboxedVfsFile::Fetch(sqlite3_int64 offset, int size, void** result) {
  DCHECK_GE(offset, 0);
  DCHECK_GE(size, 0);
  DCHECK(result);

  // NOTE: This would be needed for mmap()ed file support.
  *result = nullptr;
  return SQLITE_IOERR;
}

int SandboxedVfsFile::Unfetch(sqlite3_int64 offset, void* fetch_result) {
  DCHECK_GE(offset, 0);
  DCHECK(fetch_result);

  // NOTE: This would be needed for mmap()ed file support.
  return SQLITE_IOERR;
}

SandboxedVfsFile::SandboxedVfsFile(base::File file,
                                   base::FilePath file_path,
                                   SandboxedVfs* vfs)
    : file_(std::move(file)),
      sqlite_lock_mode_(SQLITE_LOCK_NONE),
      vfs_(vfs),
      file_path_(std::move(file_path)) {}

SandboxedVfsFile::~SandboxedVfsFile() = default;

// static
SandboxedVfsFileSqliteBridge& SandboxedVfsFileSqliteBridge::FromSqliteFile(
    sqlite3_file& sqlite_file) {
  static_assert(std::is_standard_layout<SandboxedVfsFileSqliteBridge>::value,
                "needed for the reinterpret_cast below");
  static_assert(offsetof(SandboxedVfsFileSqliteBridge, sqlite_file) == 0,
                "sqlite_file must be the first member of the struct.");

  SandboxedVfsFileSqliteBridge& bridge =
      reinterpret_cast<SandboxedVfsFileSqliteBridge&>(sqlite_file);
  DCHECK_EQ(&sqlite_file, &bridge.sqlite_file)
      << "assumed by the reinterpret_casts in the implementation";
  return bridge;
}

}  // namespace sql
