Skip to content

Commit 935d508

Browse files
committed
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>
1 parent 250898c commit 935d508

File tree

3 files changed

+41
-52
lines changed

3 files changed

+41
-52
lines changed

include/linux/lsm_hooks.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,6 @@ struct lsm_info {
172172

173173

174174
/* DO NOT tamper with these variables outside of the LSM framework */
175-
extern char *lsm_names;
176175
extern struct lsm_static_calls_table static_calls_table __ro_after_init;
177176

178177
/**

security/inode.c

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include <linux/lsm_hooks.h>
2323
#include <linux/magic.h>
2424

25+
#include "lsm.h"
26+
2527
static struct vfsmount *mount;
2628
static int mount_count;
2729

@@ -315,12 +317,49 @@ void securityfs_remove(struct dentry *dentry)
315317
EXPORT_SYMBOL_GPL(securityfs_remove);
316318

317319
#ifdef CONFIG_SECURITY
320+
#include <linux/spinlock.h>
321+
318322
static struct dentry *lsm_dentry;
323+
319324
static ssize_t lsm_read(struct file *filp, char __user *buf, size_t count,
320325
loff_t *ppos)
321326
{
322-
return simple_read_from_buffer(buf, count, ppos, lsm_names,
323-
strlen(lsm_names));
327+
int i;
328+
static char *str;
329+
static size_t len;
330+
static DEFINE_SPINLOCK(lock);
331+
332+
/* NOTE: we never free or modify the string once it is set */
333+
334+
if (unlikely(!str || !len)) {
335+
char *str_tmp;
336+
size_t len_tmp = 0;
337+
338+
for (i = 0; i < lsm_active_cnt; i++)
339+
/* the '+ 1' accounts for either a comma or a NUL */
340+
len_tmp += strlen(lsm_idlist[i]->name) + 1;
341+
342+
str_tmp = kmalloc(len_tmp, GFP_KERNEL);
343+
if (!str_tmp)
344+
return -ENOMEM;
345+
str_tmp[0] = '\0';
346+
347+
for (i = 0; i < lsm_active_cnt; i++) {
348+
if (i > 0)
349+
strcat(str_tmp, ",");
350+
strcat(str_tmp, lsm_idlist[i]->name);
351+
}
352+
353+
spin_lock(&lock);
354+
if (!str) {
355+
str = str_tmp;
356+
len = len_tmp - 1;
357+
} else
358+
kfree(str_tmp);
359+
spin_unlock(&lock);
360+
}
361+
362+
return simple_read_from_buffer(buf, count, ppos, str, len);
324363
}
325364

326365
static const struct file_operations lsm_ops = {

security/lsm_init.c

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
#include "lsm.h"
1212

13-
char *lsm_names;
14-
1513
/* Pointers to LSM sections defined in include/asm-generic/vmlinux.lds.h */
1614
extern struct lsm_info __start_lsm_info[], __end_lsm_info[];
1715
extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[];
@@ -371,42 +369,6 @@ static void __init lsm_init_ordered(void)
371369
}
372370
}
373371

374-
static bool match_last_lsm(const char *list, const char *lsm)
375-
{
376-
const char *last;
377-
378-
if (WARN_ON(!list || !lsm))
379-
return false;
380-
last = strrchr(list, ',');
381-
if (last)
382-
/* Pass the comma, strcmp() will check for '\0' */
383-
last++;
384-
else
385-
last = list;
386-
return !strcmp(last, lsm);
387-
}
388-
389-
static int lsm_append(const char *new, char **result)
390-
{
391-
char *cp;
392-
393-
if (*result == NULL) {
394-
*result = kstrdup(new, GFP_KERNEL);
395-
if (*result == NULL)
396-
return -ENOMEM;
397-
} else {
398-
/* Check if it is the last registered name */
399-
if (match_last_lsm(*result, new))
400-
return 0;
401-
cp = kasprintf(GFP_KERNEL, "%s,%s", *result, new);
402-
if (cp == NULL)
403-
return -ENOMEM;
404-
kfree(*result);
405-
*result = cp;
406-
}
407-
return 0;
408-
}
409-
410372
static void __init lsm_static_call_init(struct security_hook_list *hl)
411373
{
412374
struct lsm_static_call *scall = hl->scalls;
@@ -443,15 +405,6 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
443405
hooks[i].lsmid = lsmid;
444406
lsm_static_call_init(&hooks[i]);
445407
}
446-
447-
/*
448-
* Don't try to append during early_security_init(), we'll come back
449-
* and fix this up afterwards.
450-
*/
451-
if (slab_is_available()) {
452-
if (lsm_append(lsmid->name, &lsm_names) < 0)
453-
panic("%s - Cannot get early memory.\n", __func__);
454-
}
455408
}
456409

457410
int __init early_security_init(void)
@@ -488,8 +441,6 @@ int __init security_init(void)
488441
lsm_early_for_each_raw(lsm) {
489442
init_debug(" early started: %s (%s)\n", lsm->id->name,
490443
is_enabled(lsm) ? "enabled" : "disabled");
491-
if (lsm->enabled)
492-
lsm_append(lsm->id->name, &lsm_names);
493444
}
494445

495446
/* Load LSMs in specified order. */

0 commit comments

Comments
 (0)