diff options
Diffstat (limited to 'samples/livepatch/livepatch-shadow-fix2.c')
-rw-r--r-- | samples/livepatch/livepatch-shadow-fix2.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/samples/livepatch/livepatch-shadow-fix2.c b/samples/livepatch/livepatch-shadow-fix2.c index d6c62844dc15..b34c7bf83356 100644 --- a/samples/livepatch/livepatch-shadow-fix2.c +++ b/samples/livepatch/livepatch-shadow-fix2.c | |||
@@ -68,22 +68,27 @@ bool livepatch_fix2_dummy_check(struct dummy *d, unsigned long jiffies) | |||
68 | return time_after(jiffies, d->jiffies_expire); | 68 | return time_after(jiffies, d->jiffies_expire); |
69 | } | 69 | } |
70 | 70 | ||
71 | static void livepatch_fix2_dummy_leak_dtor(void *obj, void *shadow_data) | ||
72 | { | ||
73 | void *d = obj; | ||
74 | void **shadow_leak = shadow_data; | ||
75 | |||
76 | kfree(*shadow_leak); | ||
77 | pr_info("%s: dummy @ %p, prevented leak @ %p\n", | ||
78 | __func__, d, *shadow_leak); | ||
79 | } | ||
80 | |||
71 | void livepatch_fix2_dummy_free(struct dummy *d) | 81 | void livepatch_fix2_dummy_free(struct dummy *d) |
72 | { | 82 | { |
73 | void **shadow_leak, *leak; | 83 | void **shadow_leak; |
74 | int *shadow_count; | 84 | int *shadow_count; |
75 | 85 | ||
76 | /* Patch: copy the memory leak patch from the fix1 module. */ | 86 | /* Patch: copy the memory leak patch from the fix1 module. */ |
77 | shadow_leak = klp_shadow_get(d, SV_LEAK); | 87 | shadow_leak = klp_shadow_get(d, SV_LEAK); |
78 | if (shadow_leak) { | 88 | if (shadow_leak) |
79 | leak = *shadow_leak; | 89 | klp_shadow_free(d, SV_LEAK, livepatch_fix2_dummy_leak_dtor); |
80 | klp_shadow_free(d, SV_LEAK); | 90 | else |
81 | kfree(leak); | ||
82 | pr_info("%s: dummy @ %p, prevented leak @ %p\n", | ||
83 | __func__, d, leak); | ||
84 | } else { | ||
85 | pr_info("%s: dummy @ %p leaked!\n", __func__, d); | 91 | pr_info("%s: dummy @ %p leaked!\n", __func__, d); |
86 | } | ||
87 | 92 | ||
88 | /* | 93 | /* |
89 | * Patch: fetch the SV_COUNTER shadow variable and display | 94 | * Patch: fetch the SV_COUNTER shadow variable and display |
@@ -93,7 +98,7 @@ void livepatch_fix2_dummy_free(struct dummy *d) | |||
93 | if (shadow_count) { | 98 | if (shadow_count) { |
94 | pr_info("%s: dummy @ %p, check counter = %d\n", | 99 | pr_info("%s: dummy @ %p, check counter = %d\n", |
95 | __func__, d, *shadow_count); | 100 | __func__, d, *shadow_count); |
96 | klp_shadow_free(d, SV_COUNTER); | 101 | klp_shadow_free(d, SV_COUNTER, NULL); |
97 | } | 102 | } |
98 | 103 | ||
99 | kfree(d); | 104 | kfree(d); |
@@ -140,7 +145,7 @@ static int livepatch_shadow_fix2_init(void) | |||
140 | static void livepatch_shadow_fix2_exit(void) | 145 | static void livepatch_shadow_fix2_exit(void) |
141 | { | 146 | { |
142 | /* Cleanup any existing SV_COUNTER shadow variables */ | 147 | /* Cleanup any existing SV_COUNTER shadow variables */ |
143 | klp_shadow_free_all(SV_COUNTER); | 148 | klp_shadow_free_all(SV_COUNTER, NULL); |
144 | 149 | ||
145 | WARN_ON(klp_unregister_patch(&patch)); | 150 | WARN_ON(klp_unregister_patch(&patch)); |
146 | } | 151 | } |