0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0026
0027 #include <linux/module.h>
0028 #include <linux/kernel.h>
0029 #include <linux/livepatch.h>
0030 #include <linux/slab.h>
0031
0032
0033 #define SV_LEAK 1
0034
0035
0036 #define ALLOC_PERIOD 1
0037
0038 #define CLEANUP_PERIOD (3 * ALLOC_PERIOD)
0039
0040 #define EXPIRE_PERIOD (4 * CLEANUP_PERIOD)
0041
0042 struct dummy {
0043 struct list_head list;
0044 unsigned long jiffies_expire;
0045 };
0046
0047
0048
0049
0050
0051
0052
0053 static int shadow_leak_ctor(void *obj, void *shadow_data, void *ctor_data)
0054 {
0055 int **shadow_leak = shadow_data;
0056 int **leak = ctor_data;
0057
0058 if (!ctor_data)
0059 return -EINVAL;
0060
0061 *shadow_leak = *leak;
0062 return 0;
0063 }
0064
0065 static struct dummy *livepatch_fix1_dummy_alloc(void)
0066 {
0067 struct dummy *d;
0068 int *leak;
0069 int **shadow_leak;
0070
0071 d = kzalloc(sizeof(*d), GFP_KERNEL);
0072 if (!d)
0073 return NULL;
0074
0075 d->jiffies_expire = jiffies +
0076 msecs_to_jiffies(1000 * EXPIRE_PERIOD);
0077
0078
0079
0080
0081
0082
0083 leak = kzalloc(sizeof(*leak), GFP_KERNEL);
0084 if (!leak)
0085 goto err_leak;
0086
0087 shadow_leak = klp_shadow_alloc(d, SV_LEAK, sizeof(leak), GFP_KERNEL,
0088 shadow_leak_ctor, &leak);
0089 if (!shadow_leak) {
0090 pr_err("%s: failed to allocate shadow variable for the leaking pointer: dummy @ %p, leak @ %p\n",
0091 __func__, d, leak);
0092 goto err_shadow;
0093 }
0094
0095 pr_info("%s: dummy @ %p, expires @ %lx\n",
0096 __func__, d, d->jiffies_expire);
0097
0098 return d;
0099
0100 err_shadow:
0101 kfree(leak);
0102 err_leak:
0103 kfree(d);
0104 return NULL;
0105 }
0106
0107 static void livepatch_fix1_dummy_leak_dtor(void *obj, void *shadow_data)
0108 {
0109 void *d = obj;
0110 int **shadow_leak = shadow_data;
0111
0112 pr_info("%s: dummy @ %p, prevented leak @ %p\n",
0113 __func__, d, *shadow_leak);
0114 kfree(*shadow_leak);
0115 }
0116
0117 static void livepatch_fix1_dummy_free(struct dummy *d)
0118 {
0119 int **shadow_leak;
0120
0121
0122
0123
0124
0125
0126
0127 shadow_leak = klp_shadow_get(d, SV_LEAK);
0128 if (shadow_leak)
0129 klp_shadow_free(d, SV_LEAK, livepatch_fix1_dummy_leak_dtor);
0130 else
0131 pr_info("%s: dummy @ %p leaked!\n", __func__, d);
0132
0133 kfree(d);
0134 }
0135
0136 static struct klp_func funcs[] = {
0137 {
0138 .old_name = "dummy_alloc",
0139 .new_func = livepatch_fix1_dummy_alloc,
0140 },
0141 {
0142 .old_name = "dummy_free",
0143 .new_func = livepatch_fix1_dummy_free,
0144 }, { }
0145 };
0146
0147 static struct klp_object objs[] = {
0148 {
0149 .name = "livepatch_shadow_mod",
0150 .funcs = funcs,
0151 }, { }
0152 };
0153
0154 static struct klp_patch patch = {
0155 .mod = THIS_MODULE,
0156 .objs = objs,
0157 };
0158
0159 static int livepatch_shadow_fix1_init(void)
0160 {
0161 return klp_enable_patch(&patch);
0162 }
0163
0164 static void livepatch_shadow_fix1_exit(void)
0165 {
0166
0167 klp_shadow_free_all(SV_LEAK, livepatch_fix1_dummy_leak_dtor);
0168 }
0169
0170 module_init(livepatch_shadow_fix1_init);
0171 module_exit(livepatch_shadow_fix1_exit);
0172 MODULE_LICENSE("GPL");
0173 MODULE_INFO(livepatch, "Y");