Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

lsm: get rid of the lsm_names list and do some cleanup

The LSM currently has a lot of code to maintain a list of the currently
active LSMs in a human readable string, with the only user being the
"/sys/kernel/security/lsm" code. Let's drop all of that code and
generate the string on first use and then cache it for subsequent use.

Signed-off-by: Paul Moore <paul@paul-moore.com>

+41 -52
-1
include/linux/lsm_hooks.h
··· 172 172 173 173 174 174 /* DO NOT tamper with these variables outside of the LSM framework */ 175 - extern char *lsm_names; 176 175 extern struct lsm_static_calls_table static_calls_table __ro_after_init; 177 176 178 177 /**
+41 -2
security/inode.c
··· 22 22 #include <linux/lsm_hooks.h> 23 23 #include <linux/magic.h> 24 24 25 + #include "lsm.h" 26 + 25 27 static struct vfsmount *mount; 26 28 static int mount_count; 27 29 ··· 317 315 EXPORT_SYMBOL_GPL(securityfs_remove); 318 316 319 317 #ifdef CONFIG_SECURITY 318 + #include <linux/spinlock.h> 319 + 320 320 static struct dentry *lsm_dentry; 321 + 321 322 static ssize_t lsm_read(struct file *filp, char __user *buf, size_t count, 322 323 loff_t *ppos) 323 324 { 324 - return simple_read_from_buffer(buf, count, ppos, lsm_names, 325 - strlen(lsm_names)); 325 + int i; 326 + static char *str; 327 + static size_t len; 328 + static DEFINE_SPINLOCK(lock); 329 + 330 + /* NOTE: we never free or modify the string once it is set */ 331 + 332 + if (unlikely(!str || !len)) { 333 + char *str_tmp; 334 + size_t len_tmp = 0; 335 + 336 + for (i = 0; i < lsm_active_cnt; i++) 337 + /* the '+ 1' accounts for either a comma or a NUL */ 338 + len_tmp += strlen(lsm_idlist[i]->name) + 1; 339 + 340 + str_tmp = kmalloc(len_tmp, GFP_KERNEL); 341 + if (!str_tmp) 342 + return -ENOMEM; 343 + str_tmp[0] = '\0'; 344 + 345 + for (i = 0; i < lsm_active_cnt; i++) { 346 + if (i > 0) 347 + strcat(str_tmp, ","); 348 + strcat(str_tmp, lsm_idlist[i]->name); 349 + } 350 + 351 + spin_lock(&lock); 352 + if (!str) { 353 + str = str_tmp; 354 + len = len_tmp - 1; 355 + } else 356 + kfree(str_tmp); 357 + spin_unlock(&lock); 358 + } 359 + 360 + return simple_read_from_buffer(buf, count, ppos, str, len); 326 361 } 327 362 328 363 static const struct file_operations lsm_ops = {
-49
security/lsm_init.c
··· 10 10 11 11 #include "lsm.h" 12 12 13 - char *lsm_names; 14 - 15 13 /* Pointers to LSM sections defined in include/asm-generic/vmlinux.lds.h */ 16 14 extern struct lsm_info __start_lsm_info[], __end_lsm_info[]; 17 15 extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[]; ··· 369 371 } 370 372 } 371 373 372 - static bool match_last_lsm(const char *list, const char *lsm) 373 - { 374 - const char *last; 375 - 376 - if (WARN_ON(!list || !lsm)) 377 - return false; 378 - last = strrchr(list, ','); 379 - if (last) 380 - /* Pass the comma, strcmp() will check for '\0' */ 381 - last++; 382 - else 383 - last = list; 384 - return !strcmp(last, lsm); 385 - } 386 - 387 - static int lsm_append(const char *new, char **result) 388 - { 389 - char *cp; 390 - 391 - if (*result == NULL) { 392 - *result = kstrdup(new, GFP_KERNEL); 393 - if (*result == NULL) 394 - return -ENOMEM; 395 - } else { 396 - /* Check if it is the last registered name */ 397 - if (match_last_lsm(*result, new)) 398 - return 0; 399 - cp = kasprintf(GFP_KERNEL, "%s,%s", *result, new); 400 - if (cp == NULL) 401 - return -ENOMEM; 402 - kfree(*result); 403 - *result = cp; 404 - } 405 - return 0; 406 - } 407 - 408 374 static void __init lsm_static_call_init(struct security_hook_list *hl) 409 375 { 410 376 struct lsm_static_call *scall = hl->scalls; ··· 404 442 for (i = 0; i < count; i++) { 405 443 hooks[i].lsmid = lsmid; 406 444 lsm_static_call_init(&hooks[i]); 407 - } 408 - 409 - /* 410 - * Don't try to append during early_security_init(), we'll come back 411 - * and fix this up afterwards. 412 - */ 413 - if (slab_is_available()) { 414 - if (lsm_append(lsmid->name, &lsm_names) < 0) 415 - panic("%s - Cannot get early memory.\n", __func__); 416 445 } 417 446 } 418 447 ··· 441 488 lsm_early_for_each_raw(lsm) { 442 489 init_debug(" early started: %s (%s)\n", lsm->id->name, 443 490 is_enabled(lsm) ? "enabled" : "disabled"); 444 - if (lsm->enabled) 445 - lsm_append(lsm->id->name, &lsm_names); 446 491 } 447 492 448 493 /* Load LSMs in specified order. */