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 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 39 bool codetag_trylock_module_list(struct codetag_type *cttype) 40 { 41 return down_read_trylock(&cttype->mod_lock) != 0; 42 } 43 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 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 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 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 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 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 128 #ifdef CONFIG_MODULES 129 static void *get_symbol(struct module *mod, const char *prefix, const char *name) 130 { 131 DECLARE_SEQ_BUF(sb, KSYM_NAME_LEN); 132 const char *buf; 133 void *ret; 134 135 seq_buf_printf(&sb, "%s%s", prefix, name); 136 if (seq_buf_has_overflowed(&sb)) 137 return NULL; 138 139 buf = seq_buf_str(&sb); 140 preempt_disable(); 141 ret = mod ? 142 (void *)find_kallsyms_symbol_value(mod, buf) : 143 (void *)kallsyms_lookup_name(buf); 144 preempt_enable(); 145 146 return ret; 147 } 148 149 static struct codetag_range get_section_range(struct module *mod, 150 const char *section) 151 { 152 return (struct codetag_range) { 153 get_symbol(mod, "__start_", section), 154 get_symbol(mod, "__stop_", section), 155 }; 156 } 157 158 static int codetag_module_init(struct codetag_type *cttype, struct module *mod) 159 { 160 struct codetag_range range; 161 struct codetag_module *cmod; 162 int err; 163 164 range = get_section_range(mod, cttype->desc.section); 165 if (!range.start || !range.stop) { 166 pr_warn("Failed to load code tags of type %s from the module %s\n", 167 cttype->desc.section, 168 mod ? mod->name : "(built-in)"); 169 return -EINVAL; 170 } 171 172 /* Ignore empty ranges */ 173 if (range.start == range.stop) 174 return 0; 175 176 BUG_ON(range.start > range.stop); 177 178 cmod = kmalloc(sizeof(*cmod), GFP_KERNEL); 179 if (unlikely(!cmod)) 180 return -ENOMEM; 181 182 cmod->mod = mod; 183 cmod->range = range; 184 185 down_write(&cttype->mod_lock); 186 err = idr_alloc(&cttype->mod_idr, cmod, 0, 0, GFP_KERNEL); 187 if (err >= 0) { 188 cttype->count += range_size(cttype, &range); 189 if (cttype->desc.module_load) 190 cttype->desc.module_load(cttype, cmod); 191 } 192 up_write(&cttype->mod_lock); 193 194 if (err < 0) { 195 kfree(cmod); 196 return err; 197 } 198 199 return 0; 200 } 201 202 void codetag_load_module(struct module *mod) 203 { 204 struct codetag_type *cttype; 205 206 if (!mod) 207 return; 208 209 mutex_lock(&codetag_lock); 210 list_for_each_entry(cttype, &codetag_types, link) 211 codetag_module_init(cttype, mod); 212 mutex_unlock(&codetag_lock); 213 } 214 215 bool codetag_unload_module(struct module *mod) 216 { 217 struct codetag_type *cttype; 218 bool unload_ok = true; 219 220 if (!mod) 221 return true; 222 223 mutex_lock(&codetag_lock); 224 list_for_each_entry(cttype, &codetag_types, link) { 225 struct codetag_module *found = NULL; 226 struct codetag_module *cmod; 227 unsigned long mod_id, tmp; 228 229 down_write(&cttype->mod_lock); 230 idr_for_each_entry_ul(&cttype->mod_idr, cmod, tmp, mod_id) { 231 if (cmod->mod && cmod->mod == mod) { 232 found = cmod; 233 break; 234 } 235 } 236 if (found) { 237 if (cttype->desc.module_unload) 238 if (!cttype->desc.module_unload(cttype, cmod)) 239 unload_ok = false; 240 241 cttype->count -= range_size(cttype, &cmod->range); 242 idr_remove(&cttype->mod_idr, mod_id); 243 kfree(cmod); 244 } 245 up_write(&cttype->mod_lock); 246 } 247 mutex_unlock(&codetag_lock); 248 249 return unload_ok; 250 } 251 252 #else /* CONFIG_MODULES */ 253 static int codetag_module_init(struct codetag_type *cttype, struct module *mod) { return 0; } 254 #endif /* CONFIG_MODULES */ 255 256 struct codetag_type * 257 codetag_register_type(const struct codetag_type_desc *desc) 258 { 259 struct codetag_type *cttype; 260 int err; 261 262 BUG_ON(desc->tag_size <= 0); 263 264 cttype = kzalloc(sizeof(*cttype), GFP_KERNEL); 265 if (unlikely(!cttype)) 266 return ERR_PTR(-ENOMEM); 267 268 cttype->desc = *desc; 269 idr_init(&cttype->mod_idr); 270 init_rwsem(&cttype->mod_lock); 271 272 err = codetag_module_init(cttype, NULL); 273 if (unlikely(err)) { 274 kfree(cttype); 275 return ERR_PTR(err); 276 } 277 278 mutex_lock(&codetag_lock); 279 list_add_tail(&cttype->link, &codetag_types); 280 mutex_unlock(&codetag_lock); 281 282 return cttype; 283 } 284