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: Identify modules by more than name

Create a struct lsm_id to contain identifying information about Linux
Security Modules (LSMs). At inception this contains the name of the
module and an identifier associated with the security module. Change
the security_add_hooks() interface to use this structure. Change the
individual modules to maintain their own struct lsm_id and pass it to
security_add_hooks().

The values are for LSM identifiers are defined in a new UAPI
header file linux/lsm.h. Each existing LSM has been updated to
include it's LSMID in the lsm_id.

The LSM ID values are sequential, with the oldest module
LSM_ID_CAPABILITY being the lowest value and the existing modules
numbered in the order they were included in the main line kernel.
This is an arbitrary convention for assigning the values, but
none better presents itself. The value 0 is defined as being invalid.
The values 1-99 are reserved for any special case uses which may
arise in the future. This may include attributes of the LSM
infrastructure itself, possibly related to namespacing or network
attribute management. A special range is identified for such attributes
to help reduce confusion for developers unfamiliar with LSMs.

LSM attribute values are defined for the attributes presented by
modules that are available today. As with the LSM IDs, The value 0
is defined as being invalid. The values 1-99 are reserved for any
special case uses which may arise in the future.

Cc: linux-security-module <linux-security-module@vger.kernel.org>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Serge Hallyn <serge@hallyn.com>
Reviewed-by: Mickael Salaun <mic@digikod.net>
Reviewed-by: John Johansen <john.johansen@canonical.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Nacked-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
[PM: forward ported beyond v6.6 due merge window changes]
Signed-off-by: Paul Moore <paul@paul-moore.com>

authored by

Casey Schaufler and committed by
Paul Moore
f3b8788c b85ea95d

+162 -22
+1
Documentation/userspace-api/index.rst
··· 33 33 sysfs-platform_profile 34 34 vduse 35 35 futex2 36 + lsm 36 37 37 38 .. only:: subproject and html 38 39
+1
MAINTAINERS
··· 19511 19511 S: Supported 19512 19512 W: http://kernsec.org/ 19513 19513 T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm.git 19514 + F: include/uapi/linux/lsm.h 19514 19515 F: security/ 19515 19516 X: security/selinux/ 19516 19517
+14 -2
include/linux/lsm_hooks.h
··· 42 42 #undef LSM_HOOK 43 43 } __randomize_layout; 44 44 45 + /** 46 + * struct lsm_id - Identify a Linux Security Module. 47 + * @lsm: name of the LSM, must be approved by the LSM maintainers 48 + * @id: LSM ID number from uapi/linux/lsm.h 49 + * 50 + * Contains the information that identifies the LSM. 51 + */ 52 + struct lsm_id { 53 + const char *name; 54 + u64 id; 55 + }; 56 + 45 57 /* 46 58 * Security module hook list structure. 47 59 * For use with generic list macros for common operations. ··· 62 50 struct hlist_node list; 63 51 struct hlist_head *head; 64 52 union security_list_options hook; 65 - const char *lsm; 53 + const struct lsm_id *lsmid; 66 54 } __randomize_layout; 67 55 68 56 /* ··· 116 104 extern char *lsm_names; 117 105 118 106 extern void security_add_hooks(struct security_hook_list *hooks, int count, 119 - const char *lsm); 107 + const struct lsm_id *lsmid); 120 108 121 109 #define LSM_FLAG_LEGACY_MAJOR BIT(0) 122 110 #define LSM_FLAG_EXCLUSIVE BIT(1)
+54
include/uapi/linux/lsm.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 + /* 3 + * Linux Security Modules (LSM) - User space API 4 + * 5 + * Copyright (C) 2022 Casey Schaufler <casey@schaufler-ca.com> 6 + * Copyright (C) 2022 Intel Corporation 7 + */ 8 + 9 + #ifndef _UAPI_LINUX_LSM_H 10 + #define _UAPI_LINUX_LSM_H 11 + 12 + /* 13 + * ID tokens to identify Linux Security Modules (LSMs) 14 + * 15 + * These token values are used to uniquely identify specific LSMs 16 + * in the kernel as well as in the kernel's LSM userspace API. 17 + * 18 + * A value of zero/0 is considered undefined and should not be used 19 + * outside the kernel. Values 1-99 are reserved for potential 20 + * future use. 21 + */ 22 + #define LSM_ID_UNDEF 0 23 + #define LSM_ID_CAPABILITY 100 24 + #define LSM_ID_SELINUX 101 25 + #define LSM_ID_SMACK 102 26 + #define LSM_ID_TOMOYO 103 27 + #define LSM_ID_IMA 104 28 + #define LSM_ID_APPARMOR 105 29 + #define LSM_ID_YAMA 106 30 + #define LSM_ID_LOADPIN 107 31 + #define LSM_ID_SAFESETID 108 32 + #define LSM_ID_LOCKDOWN 109 33 + #define LSM_ID_BPF 110 34 + #define LSM_ID_LANDLOCK 111 35 + 36 + /* 37 + * LSM_ATTR_XXX definitions identify different LSM attributes 38 + * which are used in the kernel's LSM userspace API. Support 39 + * for these attributes vary across the different LSMs. None 40 + * are required. 41 + * 42 + * A value of zero/0 is considered undefined and should not be used 43 + * outside the kernel. Values 1-99 are reserved for potential 44 + * future use. 45 + */ 46 + #define LSM_ATTR_UNDEF 0 47 + #define LSM_ATTR_CURRENT 100 48 + #define LSM_ATTR_EXEC 101 49 + #define LSM_ATTR_FSCREATE 102 50 + #define LSM_ATTR_KEYCREATE 103 51 + #define LSM_ATTR_PREV 104 52 + #define LSM_ATTR_SOCKCREATE 105 53 + 54 + #endif /* _UAPI_LINUX_LSM_H */
+7 -1
security/apparmor/lsm.c
··· 24 24 #include <linux/zstd.h> 25 25 #include <net/sock.h> 26 26 #include <uapi/linux/mount.h> 27 + #include <uapi/linux/lsm.h> 27 28 28 29 #include "include/apparmor.h" 29 30 #include "include/apparmorfs.h" ··· 1386 1385 .lbs_task = sizeof(struct aa_task_ctx), 1387 1386 }; 1388 1387 1388 + const struct lsm_id apparmor_lsmid = { 1389 + .name = "apparmor", 1390 + .id = LSM_ID_APPARMOR, 1391 + }; 1392 + 1389 1393 static struct security_hook_list apparmor_hooks[] __ro_after_init = { 1390 1394 LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), 1391 1395 LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), ··· 2208 2202 goto buffers_out; 2209 2203 } 2210 2204 security_add_hooks(apparmor_hooks, ARRAY_SIZE(apparmor_hooks), 2211 - "apparmor"); 2205 + &apparmor_lsmid); 2212 2206 2213 2207 /* Report that AppArmor successfully initialized */ 2214 2208 apparmor_initialized = 1;
+8 -1
security/bpf/hooks.c
··· 5 5 */ 6 6 #include <linux/lsm_hooks.h> 7 7 #include <linux/bpf_lsm.h> 8 + #include <uapi/linux/lsm.h> 8 9 9 10 static struct security_hook_list bpf_lsm_hooks[] __ro_after_init = { 10 11 #define LSM_HOOK(RET, DEFAULT, NAME, ...) \ ··· 16 15 LSM_HOOK_INIT(task_free, bpf_task_storage_free), 17 16 }; 18 17 18 + const struct lsm_id bpf_lsmid = { 19 + .name = "bpf", 20 + .id = LSM_ID_BPF, 21 + }; 22 + 19 23 static int __init bpf_lsm_init(void) 20 24 { 21 - security_add_hooks(bpf_lsm_hooks, ARRAY_SIZE(bpf_lsm_hooks), "bpf"); 25 + security_add_hooks(bpf_lsm_hooks, ARRAY_SIZE(bpf_lsm_hooks), 26 + &bpf_lsmid); 22 27 pr_info("LSM support for eBPF active\n"); 23 28 return 0; 24 29 }
+7 -1
security/commoncap.c
··· 25 25 #include <linux/binfmts.h> 26 26 #include <linux/personality.h> 27 27 #include <linux/mnt_idmapping.h> 28 + #include <uapi/linux/lsm.h> 28 29 29 30 /* 30 31 * If a non-root user executes a setuid-root binary in ··· 1441 1440 1442 1441 #ifdef CONFIG_SECURITY 1443 1442 1443 + const struct lsm_id capability_lsmid = { 1444 + .name = "capability", 1445 + .id = LSM_ID_CAPABILITY, 1446 + }; 1447 + 1444 1448 static struct security_hook_list capability_hooks[] __ro_after_init = { 1445 1449 LSM_HOOK_INIT(capable, cap_capable), 1446 1450 LSM_HOOK_INIT(settime, cap_settime), ··· 1470 1464 static int __init capability_init(void) 1471 1465 { 1472 1466 security_add_hooks(capability_hooks, ARRAY_SIZE(capability_hooks), 1473 - "capability"); 1467 + &capability_lsmid); 1474 1468 return 0; 1475 1469 } 1476 1470
+1 -1
security/landlock/cred.c
··· 42 42 __init void landlock_add_cred_hooks(void) 43 43 { 44 44 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), 45 - LANDLOCK_NAME); 45 + &landlock_lsmid); 46 46 }
+1 -1
security/landlock/fs.c
··· 1223 1223 __init void landlock_add_fs_hooks(void) 1224 1224 { 1225 1225 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), 1226 - LANDLOCK_NAME); 1226 + &landlock_lsmid); 1227 1227 }
+1 -1
security/landlock/net.c
··· 196 196 __init void landlock_add_net_hooks(void) 197 197 { 198 198 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), 199 - LANDLOCK_NAME); 199 + &landlock_lsmid); 200 200 }
+1 -1
security/landlock/ptrace.c
··· 116 116 __init void landlock_add_ptrace_hooks(void) 117 117 { 118 118 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), 119 - LANDLOCK_NAME); 119 + &landlock_lsmid); 120 120 }
+6
security/landlock/setup.c
··· 8 8 9 9 #include <linux/init.h> 10 10 #include <linux/lsm_hooks.h> 11 + #include <uapi/linux/lsm.h> 11 12 12 13 #include "common.h" 13 14 #include "cred.h" ··· 24 23 .lbs_file = sizeof(struct landlock_file_security), 25 24 .lbs_inode = sizeof(struct landlock_inode_security), 26 25 .lbs_superblock = sizeof(struct landlock_superblock_security), 26 + }; 27 + 28 + const struct lsm_id landlock_lsmid = { 29 + .name = LANDLOCK_NAME, 30 + .id = LSM_ID_LANDLOCK, 27 31 }; 28 32 29 33 static int __init landlock_init(void)
+1
security/landlock/setup.h
··· 14 14 extern bool landlock_initialized; 15 15 16 16 extern struct lsm_blob_sizes landlock_blob_sizes; 17 + extern const struct lsm_id landlock_lsmid; 17 18 18 19 #endif /* _SECURITY_LANDLOCK_SETUP_H */
+8 -1
security/loadpin/loadpin.c
··· 20 20 #include <linux/string_helpers.h> 21 21 #include <linux/dm-verity-loadpin.h> 22 22 #include <uapi/linux/loadpin.h> 23 + #include <uapi/linux/lsm.h> 23 24 24 25 #define VERITY_DIGEST_FILE_HEADER "# LOADPIN_TRUSTED_VERITY_ROOT_DIGESTS" 25 26 ··· 209 208 return loadpin_check(NULL, (enum kernel_read_file_id) id); 210 209 } 211 210 211 + const struct lsm_id loadpin_lsmid = { 212 + .name = "loadpin", 213 + .id = LSM_ID_LOADPIN, 214 + }; 215 + 212 216 static struct security_hook_list loadpin_hooks[] __ro_after_init = { 213 217 LSM_HOOK_INIT(sb_free_security, loadpin_sb_free_security), 214 218 LSM_HOOK_INIT(kernel_read_file, loadpin_read_file), ··· 265 259 if (!register_sysctl("kernel/loadpin", loadpin_sysctl_table)) 266 260 pr_notice("sysctl registration failed!\n"); 267 261 #endif 268 - security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), "loadpin"); 262 + security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), 263 + &loadpin_lsmid); 269 264 270 265 return 0; 271 266 }
+7 -1
security/lockdown/lockdown.c
··· 13 13 #include <linux/security.h> 14 14 #include <linux/export.h> 15 15 #include <linux/lsm_hooks.h> 16 + #include <uapi/linux/lsm.h> 16 17 17 18 static enum lockdown_reason kernel_locked_down; 18 19 ··· 76 75 LSM_HOOK_INIT(locked_down, lockdown_is_locked_down), 77 76 }; 78 77 78 + const struct lsm_id lockdown_lsmid = { 79 + .name = "lockdown", 80 + .id = LSM_ID_LOCKDOWN, 81 + }; 82 + 79 83 static int __init lockdown_lsm_init(void) 80 84 { 81 85 #if defined(CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY) ··· 89 83 lock_kernel_down("Kernel configuration", LOCKDOWN_CONFIDENTIALITY_MAX); 90 84 #endif 91 85 security_add_hooks(lockdown_hooks, ARRAY_SIZE(lockdown_hooks), 92 - "lockdown"); 86 + &lockdown_lsmid); 93 87 return 0; 94 88 } 95 89
+8 -1
security/safesetid/lsm.c
··· 19 19 #include <linux/ptrace.h> 20 20 #include <linux/sched/task_stack.h> 21 21 #include <linux/security.h> 22 + #include <uapi/linux/lsm.h> 22 23 #include "lsm.h" 23 24 24 25 /* Flag indicating whether initialization completed */ ··· 262 261 return 0; 263 262 } 264 263 264 + const struct lsm_id safesetid_lsmid = { 265 + .name = "safesetid", 266 + .id = LSM_ID_SAFESETID, 267 + }; 268 + 265 269 static struct security_hook_list safesetid_security_hooks[] = { 266 270 LSM_HOOK_INIT(task_fix_setuid, safesetid_task_fix_setuid), 267 271 LSM_HOOK_INIT(task_fix_setgid, safesetid_task_fix_setgid), ··· 277 271 static int __init safesetid_security_init(void) 278 272 { 279 273 security_add_hooks(safesetid_security_hooks, 280 - ARRAY_SIZE(safesetid_security_hooks), "safesetid"); 274 + ARRAY_SIZE(safesetid_security_hooks), 275 + &safesetid_lsmid); 281 276 282 277 /* Report that SafeSetID successfully initialized */ 283 278 safesetid_initialized = 1;
+6 -6
security/security.c
··· 513 513 * security_add_hooks - Add a modules hooks to the hook lists. 514 514 * @hooks: the hooks to add 515 515 * @count: the number of hooks to add 516 - * @lsm: the name of the security module 516 + * @lsmid: the identification information for the security module 517 517 * 518 518 * Each LSM has to register its hooks with the infrastructure. 519 519 */ 520 520 void __init security_add_hooks(struct security_hook_list *hooks, int count, 521 - const char *lsm) 521 + const struct lsm_id *lsmid) 522 522 { 523 523 int i; 524 524 525 525 for (i = 0; i < count; i++) { 526 - hooks[i].lsm = lsm; 526 + hooks[i].lsmid = lsmid; 527 527 hlist_add_tail_rcu(&hooks[i].list, hooks[i].head); 528 528 } 529 529 ··· 532 532 * and fix this up afterwards. 533 533 */ 534 534 if (slab_is_available()) { 535 - if (lsm_append(lsm, &lsm_names) < 0) 535 + if (lsm_append(lsmid->name, &lsm_names) < 0) 536 536 panic("%s - Cannot get early memory.\n", __func__); 537 537 } 538 538 } ··· 3817 3817 struct security_hook_list *hp; 3818 3818 3819 3819 hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) { 3820 - if (lsm != NULL && strcmp(lsm, hp->lsm)) 3820 + if (lsm != NULL && strcmp(lsm, hp->lsmid->name)) 3821 3821 continue; 3822 3822 return hp->hook.getprocattr(p, name, value); 3823 3823 } ··· 3842 3842 struct security_hook_list *hp; 3843 3843 3844 3844 hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) { 3845 - if (lsm != NULL && strcmp(lsm, hp->lsm)) 3845 + if (lsm != NULL && strcmp(lsm, hp->lsmid->name)) 3846 3846 continue; 3847 3847 return hp->hook.setprocattr(name, value, size); 3848 3848 }
+8 -1
security/selinux/hooks.c
··· 92 92 #include <linux/fsnotify.h> 93 93 #include <linux/fanotify.h> 94 94 #include <linux/io_uring.h> 95 + #include <uapi/linux/lsm.h> 95 96 96 97 #include "avc.h" 97 98 #include "objsec.h" ··· 6951 6950 } 6952 6951 #endif /* CONFIG_IO_URING */ 6953 6952 6953 + const struct lsm_id selinux_lsmid = { 6954 + .name = "selinux", 6955 + .id = LSM_ID_SELINUX, 6956 + }; 6957 + 6954 6958 /* 6955 6959 * IMPORTANT NOTE: When adding new hooks, please be careful to keep this order: 6956 6960 * 1. any hooks that don't belong to (2.) or (3.) below, ··· 7276 7270 7277 7271 hashtab_cache_init(); 7278 7272 7279 - security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), "selinux"); 7273 + security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), 7274 + &selinux_lsmid); 7280 7275 7281 7276 if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET)) 7282 7277 panic("SELinux: Unable to register AVC netcache callback\n");
+7 -1
security/smack/smack_lsm.c
··· 43 43 #include <linux/fs_parser.h> 44 44 #include <linux/watch_queue.h> 45 45 #include <linux/io_uring.h> 46 + #include <uapi/linux/lsm.h> 46 47 #include "smack.h" 47 48 48 49 #define TRANS_TRUE "TRUE" ··· 4934 4933 .lbs_xattr_count = SMACK_INODE_INIT_XATTRS, 4935 4934 }; 4936 4935 4936 + const struct lsm_id smack_lsmid = { 4937 + .name = "smack", 4938 + .id = LSM_ID_SMACK, 4939 + }; 4940 + 4937 4941 static struct security_hook_list smack_hooks[] __ro_after_init = { 4938 4942 LSM_HOOK_INIT(ptrace_access_check, smack_ptrace_access_check), 4939 4943 LSM_HOOK_INIT(ptrace_traceme, smack_ptrace_traceme), ··· 5146 5140 /* 5147 5141 * Register with LSM 5148 5142 */ 5149 - security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), "smack"); 5143 + security_add_hooks(smack_hooks, ARRAY_SIZE(smack_hooks), &smack_lsmid); 5150 5144 smack_enabled = 1; 5151 5145 5152 5146 pr_info("Smack: Initializing.\n");
+8 -1
security/tomoyo/tomoyo.c
··· 6 6 */ 7 7 8 8 #include <linux/lsm_hooks.h> 9 + #include <uapi/linux/lsm.h> 9 10 #include "common.h" 10 11 11 12 /** ··· 543 542 } 544 543 } 545 544 545 + const struct lsm_id tomoyo_lsmid = { 546 + .name = "tomoyo", 547 + .id = LSM_ID_TOMOYO, 548 + }; 549 + 546 550 /* 547 551 * tomoyo_security_ops is a "struct security_operations" which is used for 548 552 * registering TOMOYO. ··· 601 595 struct tomoyo_task *s = tomoyo_task(current); 602 596 603 597 /* register ourselves with the security framework */ 604 - security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), "tomoyo"); 598 + security_add_hooks(tomoyo_hooks, ARRAY_SIZE(tomoyo_hooks), 599 + &tomoyo_lsmid); 605 600 pr_info("TOMOYO Linux initialized\n"); 606 601 s->domain_info = &tomoyo_kernel_domain; 607 602 atomic_inc(&tomoyo_kernel_domain.users);
+7 -1
security/yama/yama_lsm.c
··· 18 18 #include <linux/task_work.h> 19 19 #include <linux/sched.h> 20 20 #include <linux/spinlock.h> 21 + #include <uapi/linux/lsm.h> 21 22 22 23 #define YAMA_SCOPE_DISABLED 0 23 24 #define YAMA_SCOPE_RELATIONAL 1 ··· 422 421 return rc; 423 422 } 424 423 424 + const struct lsm_id yama_lsmid = { 425 + .name = "yama", 426 + .id = LSM_ID_YAMA, 427 + }; 428 + 425 429 static struct security_hook_list yama_hooks[] __ro_after_init = { 426 430 LSM_HOOK_INIT(ptrace_access_check, yama_ptrace_access_check), 427 431 LSM_HOOK_INIT(ptrace_traceme, yama_ptrace_traceme), ··· 477 471 static int __init yama_init(void) 478 472 { 479 473 pr_info("Yama: becoming mindful.\n"); 480 - security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama"); 474 + security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), &yama_lsmid); 481 475 yama_init_sysctl(); 482 476 return 0; 483 477 }