/*
 * Copyright (c) Facebook, Inc.
 * Licensed under the Apache License, Version 2.0 (the "License")
 *
 * Usage:
 *   $ ./KModRetExample
 *   opened file: /bin/true
 *   security_file_open() is called 1 times, expecting 1
 *
 * Kfunc modify_ret support is only available at kernel version 5.6 and later.
 * This example only works for x64. Currently, only the kernel functions can
 * be attached with BPF_MODIFY_RETURN:
 *   - Whitelisted for error injection by checking within_error_injection_list.
 *     Similar discussions happened for the bpf_override_return helper.
 *   - The LSM security hooks (kernel global function with prefix "security_").
 */

#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>

#include <error.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "bcc_version.h"
#include "BPF.h"

const std::string BPF_PROGRAM = R"(
#include <linux/fs.h>
#include <asm/errno.h>

BPF_ARRAY(target_pid, u32, 1);
static bool match_target_pid()
{
  int key = 0, *val, tpid, cpid;

  val = target_pid.lookup(&key);
  if (!val)
    return false;

  tpid = *val;
  cpid = bpf_get_current_pid_tgid() >> 32;
  if (tpid == 0 || tpid != cpid)
     return false;
  return true;
}

struct fname_buf {
  char buf[16];
};
BPF_ARRAY(fname_table, struct fname_buf, 1);

KMOD_RET(__x64_sys_openat, struct pt_regs *regs, int ret)
{
  if (!match_target_pid())
    return 0;

  // openat syscall arguments:
  //   int dfd, const char __user * filename, int flags, umode_t mode
  char *filename = (char *)PT_REGS_PARM2_SYSCALL(regs);

  int key = 0;
  struct fname_buf *val;
  val = fname_table.lookup(&key);
  if (!val)
    return false;

  if (bpf_copy_from_user(val, sizeof(*val), filename) < 0)
    return 0;

  /* match target_pid, return -EINVAL. */
  return -EINVAL;
}

BPF_ARRAY(count, u32, 1);
KMOD_RET(security_file_open, struct file *file, int ret)
{
  if (!match_target_pid())
    return 0;

  int key = 0, *val;
  val = count.lookup(&key);
  if (!val)
    return 0;

  /* no modification, kernel func continues to execute after this. */
  lock_xadd(val, 1);
  return 0;
}
)";

struct fname_buf {
  char buf[16];
};

static int modify_return(ebpf::BPF &bpf) {
  int prog_fd;
  auto res = bpf.load_func("kmod_ret____x64_sys_openat",
                           BPF_PROG_TYPE_TRACING, prog_fd, BPF_F_SLEEPABLE);
  if (!res.ok()) {
    std::cerr << res.msg() << std::endl;
    return 1;
  }

  int attach_fd = bpf_attach_kfunc(prog_fd);
  if (attach_fd < 0) {
    std::cerr << "bpf_attach_kfunc failed: " << attach_fd << std::endl;
    return 1;
  }

  int ret = open("/bin/true", O_RDONLY);
  if (ret >= 0 || errno != EINVAL) {
    close(attach_fd);
    std::cerr << "incorrect open result" << std::endl;
    return 1;
  }

  auto fname_table = bpf.get_array_table<struct fname_buf>("fname_table");
  uint32_t key = 0;
  struct fname_buf val;
  res = fname_table.get_value(key, val);
  if (!res.ok()) {
    close(attach_fd);
    std::cerr << res.msg() << std::endl;
    return 1;
  }
  std::cout << "opened file: " << val.buf << std::endl;

  // detach the kfunc.
  close(attach_fd);
  return 0;
}

static int not_modify_return(ebpf::BPF &bpf) {
  int prog_fd;
  auto res = bpf.load_func("kmod_ret__security_file_open",
                            BPF_PROG_TYPE_TRACING, prog_fd);
  if (!res.ok()) {
    std::cerr << res.msg() << std::endl;
    return 1;
  }

  int attach_fd = bpf_attach_kfunc(prog_fd);
  if (attach_fd < 0) {
    std::cerr << "bpf_attach_kfunc failed: " << attach_fd << std::endl;
    return 1;
  }

  int ret = open("/bin/true", O_RDONLY);
  if (ret < 0) {
    close(attach_fd);
    std::cerr << "incorrect open result" << std::endl;
    return 1;
  }

  auto count_table = bpf.get_array_table<uint32_t>("count");
  uint32_t key = 0, val = 0;
  res = count_table.get_value(key, val);
  if (!res.ok()) {
    close(attach_fd);
    std::cerr << res.msg() << std::endl;
    return 1;
  }

  close(attach_fd);
  std::cout << "security_file_open() is called " << val << " times, expecting 1\n";
  return 0;
}

int main() {
  ebpf::BPF bpf;
  auto res = bpf.init(BPF_PROGRAM);
  if (!res.ok()) {
    std::cerr << res.msg() << std::endl;
    return 1;
  }

  uint32_t key = 0, val = getpid();
  auto pid_table = bpf.get_array_table<uint32_t>("target_pid");
  res = pid_table.update_value(key, val);
  if (!res.ok()) {
    std::cerr << res.msg() << std::endl;
    return 1;
  }

  if (modify_return(bpf))
    return 1;

  if (not_modify_return(bpf))
    return 1;

  return 0;
}
