#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/kprobes.h>

static int cntr;

static int exec_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
  int ret = (int)regs_return_value(regs);
  if (!(unlikely(IS_ERR_VALUE(ret)))) {
     struct mm_struct *mm = NULL;
     mm = get_task_mm(current);
     if (mm)
       mmput(mm);
  }
  return 0;
}

static struct kretprobe exec_kretprobe = {
  .kp.symbol_name = "do_execve",
  .handler = exec_handler,
};

static int __init probe_init(void)
{
  int err;
  if ((err = register_kretprobe(&exec_kretprobe))) {
    pr_err("register failed: %d\n", err);
    return err;
  }
  pr_info("exec_mm_probe loaded.\n");
  cntr = 0;
  return 0;
}

static void probe_exit(void)
{
  unregister_kretprobe(&exec_kretprobe);
  pr_info("exec_mm_probe unloaded.\n");
}

MODULE_LICENSE("GPL v2");

module_init(probe_init);
module_exit(probe_exit);