This source file includes following definitions.
- shadow_leak_ctor
- livepatch_fix1_dummy_alloc
- livepatch_fix1_dummy_leak_dtor
- livepatch_fix1_dummy_free
- livepatch_shadow_fix1_init
- livepatch_shadow_fix1_exit
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  26 
  27 #include <linux/module.h>
  28 #include <linux/kernel.h>
  29 #include <linux/livepatch.h>
  30 #include <linux/slab.h>
  31 
  32 
  33 #define SV_LEAK         1
  34 
  35 
  36 #define ALLOC_PERIOD    1
  37 
  38 #define CLEANUP_PERIOD  (3 * ALLOC_PERIOD)
  39 
  40 #define EXPIRE_PERIOD   (4 * CLEANUP_PERIOD)
  41 
  42 struct dummy {
  43         struct list_head list;
  44         unsigned long jiffies_expire;
  45 };
  46 
  47 
  48 
  49 
  50 
  51 
  52 
  53 static int shadow_leak_ctor(void *obj, void *shadow_data, void *ctor_data)
  54 {
  55         void **shadow_leak = shadow_data;
  56         void *leak = ctor_data;
  57 
  58         *shadow_leak = leak;
  59         return 0;
  60 }
  61 
  62 static struct dummy *livepatch_fix1_dummy_alloc(void)
  63 {
  64         struct dummy *d;
  65         void *leak;
  66 
  67         d = kzalloc(sizeof(*d), GFP_KERNEL);
  68         if (!d)
  69                 return NULL;
  70 
  71         d->jiffies_expire = jiffies +
  72                 msecs_to_jiffies(1000 * EXPIRE_PERIOD);
  73 
  74         
  75 
  76 
  77 
  78 
  79         leak = kzalloc(sizeof(int), GFP_KERNEL);
  80         if (!leak) {
  81                 kfree(d);
  82                 return NULL;
  83         }
  84 
  85         klp_shadow_alloc(d, SV_LEAK, sizeof(leak), GFP_KERNEL,
  86                          shadow_leak_ctor, leak);
  87 
  88         pr_info("%s: dummy @ %p, expires @ %lx\n",
  89                 __func__, d, d->jiffies_expire);
  90 
  91         return d;
  92 }
  93 
  94 static void livepatch_fix1_dummy_leak_dtor(void *obj, void *shadow_data)
  95 {
  96         void *d = obj;
  97         void **shadow_leak = shadow_data;
  98 
  99         kfree(*shadow_leak);
 100         pr_info("%s: dummy @ %p, prevented leak @ %p\n",
 101                          __func__, d, *shadow_leak);
 102 }
 103 
 104 static void livepatch_fix1_dummy_free(struct dummy *d)
 105 {
 106         void **shadow_leak;
 107 
 108         
 109 
 110 
 111 
 112 
 113 
 114         shadow_leak = klp_shadow_get(d, SV_LEAK);
 115         if (shadow_leak)
 116                 klp_shadow_free(d, SV_LEAK, livepatch_fix1_dummy_leak_dtor);
 117         else
 118                 pr_info("%s: dummy @ %p leaked!\n", __func__, d);
 119 
 120         kfree(d);
 121 }
 122 
 123 static struct klp_func funcs[] = {
 124         {
 125                 .old_name = "dummy_alloc",
 126                 .new_func = livepatch_fix1_dummy_alloc,
 127         },
 128         {
 129                 .old_name = "dummy_free",
 130                 .new_func = livepatch_fix1_dummy_free,
 131         }, { }
 132 };
 133 
 134 static struct klp_object objs[] = {
 135         {
 136                 .name = "livepatch_shadow_mod",
 137                 .funcs = funcs,
 138         }, { }
 139 };
 140 
 141 static struct klp_patch patch = {
 142         .mod = THIS_MODULE,
 143         .objs = objs,
 144 };
 145 
 146 static int livepatch_shadow_fix1_init(void)
 147 {
 148         return klp_enable_patch(&patch);
 149 }
 150 
 151 static void livepatch_shadow_fix1_exit(void)
 152 {
 153         
 154         klp_shadow_free_all(SV_LEAK, livepatch_fix1_dummy_leak_dtor);
 155 }
 156 
 157 module_init(livepatch_shadow_fix1_init);
 158 module_exit(livepatch_shadow_fix1_exit);
 159 MODULE_LICENSE("GPL");
 160 MODULE_INFO(livepatch, "Y");