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