1 // SPDX-License-Identifier: GPL-2.0-only
2 #include <linux/codetag.h>
3 #include <linux/idr.h>
4 #include <linux/kallsyms.h>
5 #include <linux/module.h>
6 #include <linux/seq_buf.h>
7 #include <linux/slab.h>
8 #include <linux/vmalloc.h>
9
10 struct codetag_type {
11 struct list_head link;
12 unsigned int count;
13 struct idr mod_idr;
14 struct rw_semaphore mod_lock; /* protects mod_idr */
15 struct codetag_type_desc desc;
16 };
17
18 struct codetag_range {
19 struct codetag *start;
20 struct codetag *stop;
21 };
22
23 struct codetag_module {
24 struct module *mod;
25 struct codetag_range range;
26 };
27
28 static DEFINE_MUTEX(codetag_lock);
29 static LIST_HEAD(codetag_types);
30
codetag_lock_module_list(struct codetag_type * cttype,bool lock)31 void codetag_lock_module_list(struct codetag_type *cttype, bool lock)
32 {
33 if (lock)
34 down_read(&cttype->mod_lock);
35 else
36 up_read(&cttype->mod_lock);
37 }
38
codetag_trylock_module_list(struct codetag_type * cttype)39 bool codetag_trylock_module_list(struct codetag_type *cttype)
40 {
41 return down_read_trylock(&cttype->mod_lock) != 0;
42 }
43
codetag_get_ct_iter(struct codetag_type * cttype)44 struct codetag_iterator codetag_get_ct_iter(struct codetag_type *cttype)
45 {
46 struct codetag_iterator iter = {
47 .cttype = cttype,
48 .cmod = NULL,
49 .mod_id = 0,
50 .ct = NULL,
51 };
52
53 return iter;
54 }
55
get_first_module_ct(struct codetag_module * cmod)56 static inline struct codetag *get_first_module_ct(struct codetag_module *cmod)
57 {
58 return cmod->range.start < cmod->range.stop ? cmod->range.start : NULL;
59 }
60
61 static inline
get_next_module_ct(struct codetag_iterator * iter)62 struct codetag *get_next_module_ct(struct codetag_iterator *iter)
63 {
64 struct codetag *res = (struct codetag *)
65 ((char *)iter->ct + iter->cttype->desc.tag_size);
66
67 return res < iter->cmod->range.stop ? res : NULL;
68 }
69
codetag_next_ct(struct codetag_iterator * iter)70 struct codetag *codetag_next_ct(struct codetag_iterator *iter)
71 {
72 struct codetag_type *cttype = iter->cttype;
73 struct codetag_module *cmod;
74 struct codetag *ct;
75
76 lockdep_assert_held(&cttype->mod_lock);
77
78 if (unlikely(idr_is_empty(&cttype->mod_idr)))
79 return NULL;
80
81 ct = NULL;
82 while (true) {
83 cmod = idr_find(&cttype->mod_idr, iter->mod_id);
84
85 /* If module was removed move to the next one */
86 if (!cmod)
87 cmod = idr_get_next_ul(&cttype->mod_idr,
88 &iter->mod_id);
89
90 /* Exit if no more modules */
91 if (!cmod)
92 break;
93
94 if (cmod != iter->cmod) {
95 iter->cmod = cmod;
96 ct = get_first_module_ct(cmod);
97 } else
98 ct = get_next_module_ct(iter);
99
100 if (ct)
101 break;
102
103 iter->mod_id++;
104 }
105
106 iter->ct = ct;
107 return ct;
108 }
109
codetag_to_text(struct seq_buf * out,struct codetag * ct)110 void codetag_to_text(struct seq_buf *out, struct codetag *ct)
111 {
112 if (ct->modname)
113 seq_buf_printf(out, "%s:%u [%s] func:%s",
114 ct->filename, ct->lineno,
115 ct->modname, ct->function);
116 else
117 seq_buf_printf(out, "%s:%u func:%s",
118 ct->filename, ct->lineno, ct->function);
119 }
120
range_size(const struct codetag_type * cttype,const struct codetag_range * range)121 static inline size_t range_size(const struct codetag_type *cttype,
122 const struct codetag_range *range)
123 {
124 return ((char *)range->stop - (char *)range->start) /
125 cttype->desc.tag_size;
126 }
127
get_symbol(struct module * mod,const char * prefix,const char * name)128 static void *get_symbol(struct module *mod, const char *prefix, const char *name)
129 {
130 DECLARE_SEQ_BUF(sb, KSYM_NAME_LEN);
131 const char *buf;
132 void *ret;
133
134 seq_buf_printf(&sb, "%s%s", prefix, name);
135 if (seq_buf_has_overflowed(&sb))
136 return NULL;
137
138 buf = seq_buf_str(&sb);
139 preempt_disable();
140 ret = mod ?
141 (void *)find_kallsyms_symbol_value(mod, buf) :
142 (void *)kallsyms_lookup_name(buf);
143 preempt_enable();
144
145 return ret;
146 }
147
get_section_range(struct module * mod,const char * section)148 static struct codetag_range get_section_range(struct module *mod,
149 const char *section)
150 {
151 return (struct codetag_range) {
152 get_symbol(mod, CODETAG_SECTION_START_PREFIX, section),
153 get_symbol(mod, CODETAG_SECTION_STOP_PREFIX, section),
154 };
155 }
156
get_mod_name(__maybe_unused struct module * mod)157 static const char *get_mod_name(__maybe_unused struct module *mod)
158 {
159 #ifdef CONFIG_MODULES
160 if (mod)
161 return mod->name;
162 #endif
163 return "(built-in)";
164 }
165
codetag_module_init(struct codetag_type * cttype,struct module * mod)166 static int codetag_module_init(struct codetag_type *cttype, struct module *mod)
167 {
168 struct codetag_range range;
169 struct codetag_module *cmod;
170 int mod_id;
171 int err;
172
173 range = get_section_range(mod, cttype->desc.section);
174 if (!range.start || !range.stop) {
175 pr_warn("Failed to load code tags of type %s from the module %s\n",
176 cttype->desc.section, get_mod_name(mod));
177 return -EINVAL;
178 }
179
180 /* Ignore empty ranges */
181 if (range.start == range.stop)
182 return 0;
183
184 BUG_ON(range.start > range.stop);
185
186 cmod = kmalloc(sizeof(*cmod), GFP_KERNEL);
187 if (unlikely(!cmod))
188 return -ENOMEM;
189
190 cmod->mod = mod;
191 cmod->range = range;
192
193 down_write(&cttype->mod_lock);
194 mod_id = idr_alloc(&cttype->mod_idr, cmod, 0, 0, GFP_KERNEL);
195 if (mod_id >= 0) {
196 if (cttype->desc.module_load) {
197 err = cttype->desc.module_load(mod, range.start, range.stop);
198 if (!err)
199 cttype->count += range_size(cttype, &range);
200 else
201 idr_remove(&cttype->mod_idr, mod_id);
202 } else {
203 cttype->count += range_size(cttype, &range);
204 err = 0;
205 }
206 } else {
207 err = mod_id;
208 }
209 up_write(&cttype->mod_lock);
210
211 if (err < 0) {
212 kfree(cmod);
213 return err;
214 }
215
216 return 0;
217 }
218
219 #ifdef CONFIG_MODULES
220 #define CODETAG_SECTION_PREFIX ".codetag."
221
222 /* Some codetag types need a separate module section */
codetag_needs_module_section(struct module * mod,const char * name,unsigned long size)223 bool codetag_needs_module_section(struct module *mod, const char *name,
224 unsigned long size)
225 {
226 const char *type_name;
227 struct codetag_type *cttype;
228 bool ret = false;
229
230 if (strncmp(name, CODETAG_SECTION_PREFIX, strlen(CODETAG_SECTION_PREFIX)))
231 return false;
232
233 type_name = name + strlen(CODETAG_SECTION_PREFIX);
234 mutex_lock(&codetag_lock);
235 list_for_each_entry(cttype, &codetag_types, link) {
236 if (strcmp(type_name, cttype->desc.section) == 0) {
237 if (!cttype->desc.needs_section_mem)
238 break;
239
240 down_write(&cttype->mod_lock);
241 ret = cttype->desc.needs_section_mem(mod, size);
242 up_write(&cttype->mod_lock);
243 break;
244 }
245 }
246 mutex_unlock(&codetag_lock);
247
248 return ret;
249 }
250
codetag_alloc_module_section(struct module * mod,const char * name,unsigned long size,unsigned int prepend,unsigned long align)251 void *codetag_alloc_module_section(struct module *mod, const char *name,
252 unsigned long size, unsigned int prepend,
253 unsigned long align)
254 {
255 const char *type_name = name + strlen(CODETAG_SECTION_PREFIX);
256 struct codetag_type *cttype;
257 void *ret = ERR_PTR(-EINVAL);
258
259 mutex_lock(&codetag_lock);
260 list_for_each_entry(cttype, &codetag_types, link) {
261 if (strcmp(type_name, cttype->desc.section) == 0) {
262 if (WARN_ON(!cttype->desc.alloc_section_mem))
263 break;
264
265 down_write(&cttype->mod_lock);
266 ret = cttype->desc.alloc_section_mem(mod, size, prepend, align);
267 up_write(&cttype->mod_lock);
268 break;
269 }
270 }
271 mutex_unlock(&codetag_lock);
272
273 return ret;
274 }
275
codetag_free_module_sections(struct module * mod)276 void codetag_free_module_sections(struct module *mod)
277 {
278 struct codetag_type *cttype;
279
280 mutex_lock(&codetag_lock);
281 list_for_each_entry(cttype, &codetag_types, link) {
282 if (!cttype->desc.free_section_mem)
283 continue;
284
285 down_write(&cttype->mod_lock);
286 cttype->desc.free_section_mem(mod, false);
287 up_write(&cttype->mod_lock);
288 }
289 mutex_unlock(&codetag_lock);
290 }
291
codetag_module_replaced(struct module * mod,struct module * new_mod)292 void codetag_module_replaced(struct module *mod, struct module *new_mod)
293 {
294 struct codetag_type *cttype;
295
296 mutex_lock(&codetag_lock);
297 list_for_each_entry(cttype, &codetag_types, link) {
298 if (!cttype->desc.module_replaced)
299 continue;
300
301 down_write(&cttype->mod_lock);
302 cttype->desc.module_replaced(mod, new_mod);
303 up_write(&cttype->mod_lock);
304 }
305 mutex_unlock(&codetag_lock);
306 }
307
codetag_load_module(struct module * mod)308 int codetag_load_module(struct module *mod)
309 {
310 struct codetag_type *cttype;
311 int ret = 0;
312
313 if (!mod)
314 return 0;
315
316 mutex_lock(&codetag_lock);
317 list_for_each_entry(cttype, &codetag_types, link) {
318 ret = codetag_module_init(cttype, mod);
319 if (ret)
320 break;
321 }
322 mutex_unlock(&codetag_lock);
323
324 return ret;
325 }
326
codetag_unload_module(struct module * mod)327 void codetag_unload_module(struct module *mod)
328 {
329 struct codetag_type *cttype;
330
331 if (!mod)
332 return;
333
334 /* await any module's kfree_rcu() operations to complete */
335 kvfree_rcu_barrier();
336
337 mutex_lock(&codetag_lock);
338 list_for_each_entry(cttype, &codetag_types, link) {
339 struct codetag_module *found = NULL;
340 struct codetag_module *cmod;
341 unsigned long mod_id, tmp;
342
343 down_write(&cttype->mod_lock);
344 idr_for_each_entry_ul(&cttype->mod_idr, cmod, tmp, mod_id) {
345 if (cmod->mod && cmod->mod == mod) {
346 found = cmod;
347 break;
348 }
349 }
350 if (found) {
351 if (cttype->desc.module_unload)
352 cttype->desc.module_unload(cmod->mod,
353 cmod->range.start, cmod->range.stop);
354
355 cttype->count -= range_size(cttype, &cmod->range);
356 idr_remove(&cttype->mod_idr, mod_id);
357 kfree(cmod);
358 }
359 up_write(&cttype->mod_lock);
360 if (found && cttype->desc.free_section_mem)
361 cttype->desc.free_section_mem(mod, true);
362 }
363 mutex_unlock(&codetag_lock);
364 }
365 #endif /* CONFIG_MODULES */
366
367 struct codetag_type *
codetag_register_type(const struct codetag_type_desc * desc)368 codetag_register_type(const struct codetag_type_desc *desc)
369 {
370 struct codetag_type *cttype;
371 int err;
372
373 BUG_ON(desc->tag_size <= 0);
374
375 cttype = kzalloc(sizeof(*cttype), GFP_KERNEL);
376 if (unlikely(!cttype))
377 return ERR_PTR(-ENOMEM);
378
379 cttype->desc = *desc;
380 idr_init(&cttype->mod_idr);
381 init_rwsem(&cttype->mod_lock);
382
383 err = codetag_module_init(cttype, NULL);
384 if (unlikely(err)) {
385 kfree(cttype);
386 return ERR_PTR(err);
387 }
388
389 mutex_lock(&codetag_lock);
390 list_add_tail(&cttype->link, &codetag_types);
391 mutex_unlock(&codetag_lock);
392
393 return cttype;
394 }
395