diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 6 | ||||
-rw-r--r-- | include/linux/security.h | 12 | ||||
-rw-r--r-- | security/dummy.c | 4 | ||||
-rw-r--r-- | security/security.c | 38 | ||||
-rw-r--r-- | security/selinux/hooks.c | 7 | ||||
-rw-r--r-- | security/smack/smack.h | 2 | ||||
-rw-r--r-- | security/smack/smack_lsm.c | 7 | ||||
-rw-r--r-- | security/smack/smackfs.c | 11 |
8 files changed, 83 insertions, 4 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 256a2162503c..4b0f1ae31a4c 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -366,6 +366,12 @@ and is between 256 and 4096 characters. It is defined in the file | |||
366 | possible to determine what the correct size should be. | 366 | possible to determine what the correct size should be. |
367 | This option provides an override for these situations. | 367 | This option provides an override for these situations. |
368 | 368 | ||
369 | security= [SECURITY] Choose a security module to enable at boot. | ||
370 | If this boot parameter is not specified, only the first | ||
371 | security module asking for security registration will be | ||
372 | loaded. An invalid security module name will be treated | ||
373 | as if no module has been chosen. | ||
374 | |||
369 | capability.disable= | 375 | capability.disable= |
370 | [SECURITY] Disable capabilities. This would normally | 376 | [SECURITY] Disable capabilities. This would normally |
371 | be used only if an alternative security model is to be | 377 | be used only if an alternative security model is to be |
diff --git a/include/linux/security.h b/include/linux/security.h index 697f228daf19..f4116d6ed64b 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -36,6 +36,9 @@ | |||
36 | 36 | ||
37 | extern unsigned securebits; | 37 | extern unsigned securebits; |
38 | 38 | ||
39 | /* Maximum number of letters for an LSM name string */ | ||
40 | #define SECURITY_NAME_MAX 10 | ||
41 | |||
39 | struct ctl_table; | 42 | struct ctl_table; |
40 | struct audit_krule; | 43 | struct audit_krule; |
41 | 44 | ||
@@ -137,6 +140,12 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
137 | /** | 140 | /** |
138 | * struct security_operations - main security structure | 141 | * struct security_operations - main security structure |
139 | * | 142 | * |
143 | * Security module identifier. | ||
144 | * | ||
145 | * @name: | ||
146 | * A string that acts as a unique identifeir for the LSM with max number | ||
147 | * of characters = SECURITY_NAME_MAX. | ||
148 | * | ||
140 | * Security hooks for program execution operations. | 149 | * Security hooks for program execution operations. |
141 | * | 150 | * |
142 | * @bprm_alloc_security: | 151 | * @bprm_alloc_security: |
@@ -1270,6 +1279,8 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
1270 | * This is the main security structure. | 1279 | * This is the main security structure. |
1271 | */ | 1280 | */ |
1272 | struct security_operations { | 1281 | struct security_operations { |
1282 | char name[SECURITY_NAME_MAX + 1]; | ||
1283 | |||
1273 | int (*ptrace) (struct task_struct * parent, struct task_struct * child); | 1284 | int (*ptrace) (struct task_struct * parent, struct task_struct * child); |
1274 | int (*capget) (struct task_struct * target, | 1285 | int (*capget) (struct task_struct * target, |
1275 | kernel_cap_t * effective, | 1286 | kernel_cap_t * effective, |
@@ -1537,6 +1548,7 @@ struct security_operations { | |||
1537 | 1548 | ||
1538 | /* prototypes */ | 1549 | /* prototypes */ |
1539 | extern int security_init (void); | 1550 | extern int security_init (void); |
1551 | extern int security_module_enable(struct security_operations *ops); | ||
1540 | extern int register_security (struct security_operations *ops); | 1552 | extern int register_security (struct security_operations *ops); |
1541 | extern int mod_reg_security (const char *name, struct security_operations *ops); | 1553 | extern int mod_reg_security (const char *name, struct security_operations *ops); |
1542 | extern struct dentry *securityfs_create_file(const char *name, mode_t mode, | 1554 | extern struct dentry *securityfs_create_file(const char *name, mode_t mode, |
diff --git a/security/dummy.c b/security/dummy.c index 1ac9f8e66aa2..d797a4196b89 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
@@ -1017,7 +1017,9 @@ static inline void dummy_audit_rule_free(void *lsmrule) | |||
1017 | 1017 | ||
1018 | #endif /* CONFIG_AUDIT */ | 1018 | #endif /* CONFIG_AUDIT */ |
1019 | 1019 | ||
1020 | struct security_operations dummy_security_ops; | 1020 | struct security_operations dummy_security_ops = { |
1021 | .name = "dummy", | ||
1022 | }; | ||
1021 | 1023 | ||
1022 | #define set_to_dummy_if_null(ops, function) \ | 1024 | #define set_to_dummy_if_null(ops, function) \ |
1023 | do { \ | 1025 | do { \ |
diff --git a/security/security.c b/security/security.c index 2ef593ec70f3..dd0c6baed494 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/security.h> | 18 | #include <linux/security.h> |
19 | 19 | ||
20 | /* Boot-time LSM user choice */ | ||
21 | static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1]; | ||
20 | 22 | ||
21 | /* things that live in dummy.c */ | 23 | /* things that live in dummy.c */ |
22 | extern struct security_operations dummy_security_ops; | 24 | extern struct security_operations dummy_security_ops; |
@@ -67,13 +69,47 @@ int __init security_init(void) | |||
67 | return 0; | 69 | return 0; |
68 | } | 70 | } |
69 | 71 | ||
72 | /* Save user chosen LSM */ | ||
73 | static int __init choose_lsm(char *str) | ||
74 | { | ||
75 | strncpy(chosen_lsm, str, SECURITY_NAME_MAX); | ||
76 | return 1; | ||
77 | } | ||
78 | __setup("security=", choose_lsm); | ||
79 | |||
80 | /** | ||
81 | * security_module_enable - Load given security module on boot ? | ||
82 | * @ops: a pointer to the struct security_operations that is to be checked. | ||
83 | * | ||
84 | * Each LSM must pass this method before registering its own operations | ||
85 | * to avoid security registration races. This method may also be used | ||
86 | * to check if your LSM is currently loaded. | ||
87 | * | ||
88 | * Return true if: | ||
89 | * -The passed LSM is the one chosen by user at boot time, | ||
90 | * -or user didsn't specify a specific LSM and we're the first to ask | ||
91 | * for registeration permissoin, | ||
92 | * -or the passed LSM is currently loaded. | ||
93 | * Otherwise, return false. | ||
94 | */ | ||
95 | int __init security_module_enable(struct security_operations *ops) | ||
96 | { | ||
97 | if (!*chosen_lsm) | ||
98 | strncpy(chosen_lsm, ops->name, SECURITY_NAME_MAX); | ||
99 | else if (strncmp(ops->name, chosen_lsm, SECURITY_NAME_MAX)) | ||
100 | return 0; | ||
101 | |||
102 | return 1; | ||
103 | } | ||
104 | |||
70 | /** | 105 | /** |
71 | * register_security - registers a security framework with the kernel | 106 | * register_security - registers a security framework with the kernel |
72 | * @ops: a pointer to the struct security_options that is to be registered | 107 | * @ops: a pointer to the struct security_options that is to be registered |
73 | * | 108 | * |
74 | * This function is to allow a security module to register itself with the | 109 | * This function is to allow a security module to register itself with the |
75 | * kernel security subsystem. Some rudimentary checking is done on the @ops | 110 | * kernel security subsystem. Some rudimentary checking is done on the @ops |
76 | * value passed to this function. | 111 | * value passed to this function. You'll need to check first if your LSM |
112 | * is allowed to register its @ops by calling security_module_enable(@ops). | ||
77 | * | 113 | * |
78 | * If there is already a security module registered with the kernel, | 114 | * If there is already a security module registered with the kernel, |
79 | * an error will be returned. Otherwise 0 is returned on success. | 115 | * an error will be returned. Otherwise 0 is returned on success. |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index a2f7e9cf78c5..f9927f02bc3d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -5295,6 +5295,8 @@ static int selinux_key_permission(key_ref_t key_ref, | |||
5295 | #endif | 5295 | #endif |
5296 | 5296 | ||
5297 | static struct security_operations selinux_ops = { | 5297 | static struct security_operations selinux_ops = { |
5298 | .name = "selinux", | ||
5299 | |||
5298 | .ptrace = selinux_ptrace, | 5300 | .ptrace = selinux_ptrace, |
5299 | .capget = selinux_capget, | 5301 | .capget = selinux_capget, |
5300 | .capset_check = selinux_capset_check, | 5302 | .capset_check = selinux_capset_check, |
@@ -5492,6 +5494,11 @@ static __init int selinux_init(void) | |||
5492 | { | 5494 | { |
5493 | struct task_security_struct *tsec; | 5495 | struct task_security_struct *tsec; |
5494 | 5496 | ||
5497 | if (!security_module_enable(&selinux_ops)) { | ||
5498 | selinux_enabled = 0; | ||
5499 | return 0; | ||
5500 | } | ||
5501 | |||
5495 | if (!selinux_enabled) { | 5502 | if (!selinux_enabled) { |
5496 | printk(KERN_INFO "SELinux: Disabled at boot.\n"); | 5503 | printk(KERN_INFO "SELinux: Disabled at boot.\n"); |
5497 | return 0; | 5504 | return 0; |
diff --git a/security/smack/smack.h b/security/smack/smack.h index 62c1e982849d..4a4477f5afdc 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #include <linux/capability.h> | 16 | #include <linux/capability.h> |
17 | #include <linux/spinlock.h> | 17 | #include <linux/spinlock.h> |
18 | #include <linux/security.h> | ||
18 | #include <net/netlabel.h> | 19 | #include <net/netlabel.h> |
19 | 20 | ||
20 | /* | 21 | /* |
@@ -187,6 +188,7 @@ extern struct smack_known smack_known_star; | |||
187 | extern struct smack_known smack_known_unset; | 188 | extern struct smack_known smack_known_unset; |
188 | 189 | ||
189 | extern struct smk_list_entry *smack_list; | 190 | extern struct smk_list_entry *smack_list; |
191 | extern struct security_operations smack_ops; | ||
190 | 192 | ||
191 | /* | 193 | /* |
192 | * Stricly for CIPSO level manipulation. | 194 | * Stricly for CIPSO level manipulation. |
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 732ba27923c4..904bdc01a12b 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c | |||
@@ -2424,7 +2424,9 @@ static void smack_release_secctx(char *secdata, u32 seclen) | |||
2424 | { | 2424 | { |
2425 | } | 2425 | } |
2426 | 2426 | ||
2427 | static struct security_operations smack_ops = { | 2427 | struct security_operations smack_ops = { |
2428 | .name = "smack", | ||
2429 | |||
2428 | .ptrace = smack_ptrace, | 2430 | .ptrace = smack_ptrace, |
2429 | .capget = cap_capget, | 2431 | .capget = cap_capget, |
2430 | .capset_check = cap_capset_check, | 2432 | .capset_check = cap_capset_check, |
@@ -2557,6 +2559,9 @@ static struct security_operations smack_ops = { | |||
2557 | */ | 2559 | */ |
2558 | static __init int smack_init(void) | 2560 | static __init int smack_init(void) |
2559 | { | 2561 | { |
2562 | if (!security_module_enable(&smack_ops)) | ||
2563 | return 0; | ||
2564 | |||
2560 | printk(KERN_INFO "Smack: Initializing.\n"); | 2565 | printk(KERN_INFO "Smack: Initializing.\n"); |
2561 | 2566 | ||
2562 | /* | 2567 | /* |
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c index cfae8afcc262..6ba283783b70 100644 --- a/security/smack/smackfs.c +++ b/security/smack/smackfs.c | |||
@@ -965,12 +965,21 @@ static struct vfsmount *smackfs_mount; | |||
965 | * | 965 | * |
966 | * register the smackfs | 966 | * register the smackfs |
967 | * | 967 | * |
968 | * Returns 0 unless the registration fails. | 968 | * Do not register smackfs if Smack wasn't enabled |
969 | * on boot. We can not put this method normally under the | ||
970 | * smack_init() code path since the security subsystem get | ||
971 | * initialized before the vfs caches. | ||
972 | * | ||
973 | * Returns true if we were not chosen on boot or if | ||
974 | * we were chosen and filesystem registration succeeded. | ||
969 | */ | 975 | */ |
970 | static int __init init_smk_fs(void) | 976 | static int __init init_smk_fs(void) |
971 | { | 977 | { |
972 | int err; | 978 | int err; |
973 | 979 | ||
980 | if (!security_module_enable(&smack_ops)) | ||
981 | return 0; | ||
982 | |||
974 | err = register_filesystem(&smk_fs_type); | 983 | err = register_filesystem(&smk_fs_type); |
975 | if (!err) { | 984 | if (!err) { |
976 | smackfs_mount = kern_mount(&smk_fs_type); | 985 | smackfs_mount = kern_mount(&smk_fs_type); |