/*
 * pi3's Linux kernel Runtime Guard
 *
 * Component:
 *  - Intercept setfsuid syscall
 *
 * Notes:
 *  - None
 *
 * Caveats:
 *  - None
 *
 * Timeline:
 *  - Created: 09.IX.2017
 *
 * Author:
 *  - Adam 'pi3' Zabrocki (http://pi3.com.pl)
 *
 */

#include "../../../../p_lkrg_main.h"

static int p_sys_setfsuid_entry(struct kretprobe_instance *p_ri, struct pt_regs *p_regs) {

   struct p_ed_process *p_tmp;

   /*
    * This is special case, since we can NOT identify when syscall fail or succeed,
    * we must verify process list before and after the syscall
    */
   p_ed_enforce_validation();
   if ((p_tmp = ed_task_lock_current())) {
#ifdef P_LKRG_TASK_OFF_DEBUG
      p_debug_off_flag_off(p_tmp, 43);
#endif
      // This process is on the ED list - set temporary 'disable' flag!
      p_set_ed_process_off(p_tmp);
      ed_task_unlock(p_tmp);
   }

   return 0;
}

static int p_sys_setfsuid_ret(struct kretprobe_instance *ri, struct pt_regs *p_regs) {

   struct p_ed_process *p_tmp;

   p_debug_kprobe_log(
          "Setfsuid returned value => %ld comm[%s] Pid:%d parent[%d]",
                       p_regs_get_ret(p_regs),current->comm,current->pid,current->real_parent->pid);
      if ((p_tmp = ed_task_lock_current())) {
         // This process is on the ED list - update information!
         p_update_ed_process(p_tmp, 0);
#ifdef P_LKRG_TASK_OFF_DEBUG
         p_debug_off_flag_on(p_tmp, 44);
#endif
         p_set_ed_process_on(p_tmp);
         ed_task_unlock(p_tmp);
   }

//   p_ed_enforce_validation();

   return 0;
}

static struct lkrg_probe p_sys_setfsuid_probe = {
  .type = LKRG_KRETPROBE,
  .krp = {
    .kp.symbol_name = P_GET_SET_ID_NAME(setfsuid),
    .handler = p_sys_setfsuid_ret,
    .entry_handler = p_sys_setfsuid_entry,
  }
};

GENERATE_INSTALL_FUNC(sys_setfsuid)
