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 #define SV_COUNTER 2
0035
0036 struct dummy {
0037 struct list_head list;
0038 unsigned long jiffies_expire;
0039 };
0040
0041 static bool livepatch_fix2_dummy_check(struct dummy *d, unsigned long jiffies)
0042 {
0043 int *shadow_count;
0044
0045
0046
0047
0048
0049
0050 shadow_count = klp_shadow_get_or_alloc(d, SV_COUNTER,
0051 sizeof(*shadow_count), GFP_NOWAIT,
0052 NULL, NULL);
0053 if (shadow_count)
0054 *shadow_count += 1;
0055
0056 return time_after(jiffies, d->jiffies_expire);
0057 }
0058
0059 static void livepatch_fix2_dummy_leak_dtor(void *obj, void *shadow_data)
0060 {
0061 void *d = obj;
0062 int **shadow_leak = shadow_data;
0063
0064 pr_info("%s: dummy @ %p, prevented leak @ %p\n",
0065 __func__, d, *shadow_leak);
0066 kfree(*shadow_leak);
0067 }
0068
0069 static void livepatch_fix2_dummy_free(struct dummy *d)
0070 {
0071 int **shadow_leak;
0072 int *shadow_count;
0073
0074
0075 shadow_leak = klp_shadow_get(d, SV_LEAK);
0076 if (shadow_leak)
0077 klp_shadow_free(d, SV_LEAK, livepatch_fix2_dummy_leak_dtor);
0078 else
0079 pr_info("%s: dummy @ %p leaked!\n", __func__, d);
0080
0081
0082
0083
0084
0085 shadow_count = klp_shadow_get(d, SV_COUNTER);
0086 if (shadow_count) {
0087 pr_info("%s: dummy @ %p, check counter = %d\n",
0088 __func__, d, *shadow_count);
0089 klp_shadow_free(d, SV_COUNTER, NULL);
0090 }
0091
0092 kfree(d);
0093 }
0094
0095 static struct klp_func funcs[] = {
0096 {
0097 .old_name = "dummy_check",
0098 .new_func = livepatch_fix2_dummy_check,
0099 },
0100 {
0101 .old_name = "dummy_free",
0102 .new_func = livepatch_fix2_dummy_free,
0103 }, { }
0104 };
0105
0106 static struct klp_object objs[] = {
0107 {
0108 .name = "livepatch_shadow_mod",
0109 .funcs = funcs,
0110 }, { }
0111 };
0112
0113 static struct klp_patch patch = {
0114 .mod = THIS_MODULE,
0115 .objs = objs,
0116 };
0117
0118 static int livepatch_shadow_fix2_init(void)
0119 {
0120 return klp_enable_patch(&patch);
0121 }
0122
0123 static void livepatch_shadow_fix2_exit(void)
0124 {
0125
0126 klp_shadow_free_all(SV_COUNTER, NULL);
0127 }
0128
0129 module_init(livepatch_shadow_fix2_init);
0130 module_exit(livepatch_shadow_fix2_exit);
0131 MODULE_LICENSE("GPL");
0132 MODULE_INFO(livepatch, "Y");