hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/samples/livepatch/livepatch-shadow-fix1.c
....@@ -1,18 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (C) 2017 Joe Lawrence <joe.lawrence@redhat.com>
3
- *
4
- * This program is free software; you can redistribute it and/or
5
- * modify it under the terms of the GNU General Public License
6
- * as published by the Free Software Foundation; either version 2
7
- * of the License, or (at your option) any later version.
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
13
- *
14
- * You should have received a copy of the GNU General Public License
15
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
164 */
175
186 /*
....@@ -64,17 +52,21 @@
6452 */
6553 static int shadow_leak_ctor(void *obj, void *shadow_data, void *ctor_data)
6654 {
67
- void **shadow_leak = shadow_data;
68
- void *leak = ctor_data;
55
+ int **shadow_leak = shadow_data;
56
+ int **leak = ctor_data;
6957
70
- *shadow_leak = leak;
58
+ if (!ctor_data)
59
+ return -EINVAL;
60
+
61
+ *shadow_leak = *leak;
7162 return 0;
7263 }
7364
74
-struct dummy *livepatch_fix1_dummy_alloc(void)
65
+static struct dummy *livepatch_fix1_dummy_alloc(void)
7566 {
7667 struct dummy *d;
77
- void *leak;
68
+ int *leak;
69
+ int **shadow_leak;
7870
7971 d = kzalloc(sizeof(*d), GFP_KERNEL);
8072 if (!d)
....@@ -88,34 +80,43 @@
8880 * variable. A patched dummy_free routine can later fetch this
8981 * pointer to handle resource release.
9082 */
91
- leak = kzalloc(sizeof(int), GFP_KERNEL);
92
- if (!leak) {
93
- kfree(d);
94
- return NULL;
95
- }
83
+ leak = kzalloc(sizeof(*leak), GFP_KERNEL);
84
+ if (!leak)
85
+ goto err_leak;
9686
97
- klp_shadow_alloc(d, SV_LEAK, sizeof(leak), GFP_KERNEL,
98
- shadow_leak_ctor, leak);
87
+ shadow_leak = klp_shadow_alloc(d, SV_LEAK, sizeof(leak), GFP_KERNEL,
88
+ shadow_leak_ctor, &leak);
89
+ if (!shadow_leak) {
90
+ pr_err("%s: failed to allocate shadow variable for the leaking pointer: dummy @ %p, leak @ %p\n",
91
+ __func__, d, leak);
92
+ goto err_shadow;
93
+ }
9994
10095 pr_info("%s: dummy @ %p, expires @ %lx\n",
10196 __func__, d, d->jiffies_expire);
10297
10398 return d;
99
+
100
+err_shadow:
101
+ kfree(leak);
102
+err_leak:
103
+ kfree(d);
104
+ return NULL;
104105 }
105106
106107 static void livepatch_fix1_dummy_leak_dtor(void *obj, void *shadow_data)
107108 {
108109 void *d = obj;
109
- void **shadow_leak = shadow_data;
110
+ int **shadow_leak = shadow_data;
110111
111112 kfree(*shadow_leak);
112113 pr_info("%s: dummy @ %p, prevented leak @ %p\n",
113114 __func__, d, *shadow_leak);
114115 }
115116
116
-void livepatch_fix1_dummy_free(struct dummy *d)
117
+static void livepatch_fix1_dummy_free(struct dummy *d)
117118 {
118
- void **shadow_leak;
119
+ int **shadow_leak;
119120
120121 /*
121122 * Patch: fetch the saved SV_LEAK shadow variable, detach and
....@@ -157,25 +158,13 @@
157158
158159 static int livepatch_shadow_fix1_init(void)
159160 {
160
- int ret;
161
-
162
- ret = klp_register_patch(&patch);
163
- if (ret)
164
- return ret;
165
- ret = klp_enable_patch(&patch);
166
- if (ret) {
167
- WARN_ON(klp_unregister_patch(&patch));
168
- return ret;
169
- }
170
- return 0;
161
+ return klp_enable_patch(&patch);
171162 }
172163
173164 static void livepatch_shadow_fix1_exit(void)
174165 {
175166 /* Cleanup any existing SV_LEAK shadow variables */
176167 klp_shadow_free_all(SV_LEAK, livepatch_fix1_dummy_leak_dtor);
177
-
178
- WARN_ON(klp_unregister_patch(&patch));
179168 }
180169
181170 module_init(livepatch_shadow_fix1_init);