xref: /linux/lib/codetag.c (revision d3c82f618a9c2b764b7651afe16594ffeb50ade9)
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