diff options
Diffstat (limited to 'security/security.c')
-rw-r--r-- | security/security.c | 145 |
1 files changed, 111 insertions, 34 deletions
diff --git a/security/security.c b/security/security.c index b1387a6b416d..59838a99b80e 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; |
@@ -57,7 +59,7 @@ int __init security_init(void) | |||
57 | 59 | ||
58 | if (verify(&dummy_security_ops)) { | 60 | if (verify(&dummy_security_ops)) { |
59 | printk(KERN_ERR "%s could not verify " | 61 | printk(KERN_ERR "%s could not verify " |
60 | "dummy_security_ops structure.\n", __FUNCTION__); | 62 | "dummy_security_ops structure.\n", __func__); |
61 | return -EIO; | 63 | return -EIO; |
62 | } | 64 | } |
63 | 65 | ||
@@ -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 during kernel initialization. | ||
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. |
@@ -82,7 +118,7 @@ int register_security(struct security_operations *ops) | |||
82 | { | 118 | { |
83 | if (verify(ops)) { | 119 | if (verify(ops)) { |
84 | printk(KERN_DEBUG "%s could not verify " | 120 | printk(KERN_DEBUG "%s could not verify " |
85 | "security_operations structure.\n", __FUNCTION__); | 121 | "security_operations structure.\n", __func__); |
86 | return -EINVAL; | 122 | return -EINVAL; |
87 | } | 123 | } |
88 | 124 | ||
@@ -110,13 +146,13 @@ int mod_reg_security(const char *name, struct security_operations *ops) | |||
110 | { | 146 | { |
111 | if (verify(ops)) { | 147 | if (verify(ops)) { |
112 | printk(KERN_INFO "%s could not verify " | 148 | printk(KERN_INFO "%s could not verify " |
113 | "security operations.\n", __FUNCTION__); | 149 | "security operations.\n", __func__); |
114 | return -EINVAL; | 150 | return -EINVAL; |
115 | } | 151 | } |
116 | 152 | ||
117 | if (ops == security_ops) { | 153 | if (ops == security_ops) { |
118 | printk(KERN_INFO "%s security operations " | 154 | printk(KERN_INFO "%s security operations " |
119 | "already registered.\n", __FUNCTION__); | 155 | "already registered.\n", __func__); |
120 | return -EINVAL; | 156 | return -EINVAL; |
121 | } | 157 | } |
122 | 158 | ||
@@ -260,15 +296,15 @@ int security_sb_statfs(struct dentry *dentry) | |||
260 | return security_ops->sb_statfs(dentry); | 296 | return security_ops->sb_statfs(dentry); |
261 | } | 297 | } |
262 | 298 | ||
263 | int security_sb_mount(char *dev_name, struct nameidata *nd, | 299 | int security_sb_mount(char *dev_name, struct path *path, |
264 | char *type, unsigned long flags, void *data) | 300 | char *type, unsigned long flags, void *data) |
265 | { | 301 | { |
266 | return security_ops->sb_mount(dev_name, nd, type, flags, data); | 302 | return security_ops->sb_mount(dev_name, path, type, flags, data); |
267 | } | 303 | } |
268 | 304 | ||
269 | int security_sb_check_sb(struct vfsmount *mnt, struct nameidata *nd) | 305 | int security_sb_check_sb(struct vfsmount *mnt, struct path *path) |
270 | { | 306 | { |
271 | return security_ops->sb_check_sb(mnt, nd); | 307 | return security_ops->sb_check_sb(mnt, path); |
272 | } | 308 | } |
273 | 309 | ||
274 | int security_sb_umount(struct vfsmount *mnt, int flags) | 310 | int security_sb_umount(struct vfsmount *mnt, int flags) |
@@ -291,19 +327,19 @@ void security_sb_post_remount(struct vfsmount *mnt, unsigned long flags, void *d | |||
291 | security_ops->sb_post_remount(mnt, flags, data); | 327 | security_ops->sb_post_remount(mnt, flags, data); |
292 | } | 328 | } |
293 | 329 | ||
294 | void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata *mountpoint_nd) | 330 | void security_sb_post_addmount(struct vfsmount *mnt, struct path *mountpoint) |
295 | { | 331 | { |
296 | security_ops->sb_post_addmount(mnt, mountpoint_nd); | 332 | security_ops->sb_post_addmount(mnt, mountpoint); |
297 | } | 333 | } |
298 | 334 | ||
299 | int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd) | 335 | int security_sb_pivotroot(struct path *old_path, struct path *new_path) |
300 | { | 336 | { |
301 | return security_ops->sb_pivotroot(old_nd, new_nd); | 337 | return security_ops->sb_pivotroot(old_path, new_path); |
302 | } | 338 | } |
303 | 339 | ||
304 | void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd) | 340 | void security_sb_post_pivotroot(struct path *old_path, struct path *new_path) |
305 | { | 341 | { |
306 | security_ops->sb_post_pivotroot(old_nd, new_nd); | 342 | security_ops->sb_post_pivotroot(old_path, new_path); |
307 | } | 343 | } |
308 | 344 | ||
309 | int security_sb_get_mnt_opts(const struct super_block *sb, | 345 | int security_sb_get_mnt_opts(const struct super_block *sb, |
@@ -455,23 +491,23 @@ void security_inode_delete(struct inode *inode) | |||
455 | security_ops->inode_delete(inode); | 491 | security_ops->inode_delete(inode); |
456 | } | 492 | } |
457 | 493 | ||
458 | int security_inode_setxattr(struct dentry *dentry, char *name, | 494 | int security_inode_setxattr(struct dentry *dentry, const char *name, |
459 | void *value, size_t size, int flags) | 495 | const void *value, size_t size, int flags) |
460 | { | 496 | { |
461 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 497 | if (unlikely(IS_PRIVATE(dentry->d_inode))) |
462 | return 0; | 498 | return 0; |
463 | return security_ops->inode_setxattr(dentry, name, value, size, flags); | 499 | return security_ops->inode_setxattr(dentry, name, value, size, flags); |
464 | } | 500 | } |
465 | 501 | ||
466 | void security_inode_post_setxattr(struct dentry *dentry, char *name, | 502 | void security_inode_post_setxattr(struct dentry *dentry, const char *name, |
467 | void *value, size_t size, int flags) | 503 | const void *value, size_t size, int flags) |
468 | { | 504 | { |
469 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 505 | if (unlikely(IS_PRIVATE(dentry->d_inode))) |
470 | return; | 506 | return; |
471 | security_ops->inode_post_setxattr(dentry, name, value, size, flags); | 507 | security_ops->inode_post_setxattr(dentry, name, value, size, flags); |
472 | } | 508 | } |
473 | 509 | ||
474 | int security_inode_getxattr(struct dentry *dentry, char *name) | 510 | int security_inode_getxattr(struct dentry *dentry, const char *name) |
475 | { | 511 | { |
476 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 512 | if (unlikely(IS_PRIVATE(dentry->d_inode))) |
477 | return 0; | 513 | return 0; |
@@ -485,7 +521,7 @@ int security_inode_listxattr(struct dentry *dentry) | |||
485 | return security_ops->inode_listxattr(dentry); | 521 | return security_ops->inode_listxattr(dentry); |
486 | } | 522 | } |
487 | 523 | ||
488 | int security_inode_removexattr(struct dentry *dentry, char *name) | 524 | int security_inode_removexattr(struct dentry *dentry, const char *name) |
489 | { | 525 | { |
490 | if (unlikely(IS_PRIVATE(dentry->d_inode))) | 526 | if (unlikely(IS_PRIVATE(dentry->d_inode))) |
491 | return 0; | 527 | return 0; |
@@ -523,6 +559,11 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer | |||
523 | return security_ops->inode_listsecurity(inode, buffer, buffer_size); | 559 | return security_ops->inode_listsecurity(inode, buffer, buffer_size); |
524 | } | 560 | } |
525 | 561 | ||
562 | void security_inode_getsecid(const struct inode *inode, u32 *secid) | ||
563 | { | ||
564 | security_ops->inode_getsecid(inode, secid); | ||
565 | } | ||
566 | |||
526 | int security_file_permission(struct file *file, int mask) | 567 | int security_file_permission(struct file *file, int mask) |
527 | { | 568 | { |
528 | return security_ops->file_permission(file, mask); | 569 | return security_ops->file_permission(file, mask); |
@@ -692,9 +733,9 @@ int security_task_wait(struct task_struct *p) | |||
692 | } | 733 | } |
693 | 734 | ||
694 | int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, | 735 | int security_task_prctl(int option, unsigned long arg2, unsigned long arg3, |
695 | unsigned long arg4, unsigned long arg5) | 736 | unsigned long arg4, unsigned long arg5, long *rc_p) |
696 | { | 737 | { |
697 | return security_ops->task_prctl(option, arg2, arg3, arg4, arg5); | 738 | return security_ops->task_prctl(option, arg2, arg3, arg4, arg5, rc_p); |
698 | } | 739 | } |
699 | 740 | ||
700 | void security_task_reparent_to_init(struct task_struct *p) | 741 | void security_task_reparent_to_init(struct task_struct *p) |
@@ -712,6 +753,11 @@ int security_ipc_permission(struct kern_ipc_perm *ipcp, short flag) | |||
712 | return security_ops->ipc_permission(ipcp, flag); | 753 | return security_ops->ipc_permission(ipcp, flag); |
713 | } | 754 | } |
714 | 755 | ||
756 | void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) | ||
757 | { | ||
758 | security_ops->ipc_getsecid(ipcp, secid); | ||
759 | } | ||
760 | |||
715 | int security_msg_msg_alloc(struct msg_msg *msg) | 761 | int security_msg_msg_alloc(struct msg_msg *msg) |
716 | { | 762 | { |
717 | return security_ops->msg_msg_alloc_security(msg); | 763 | return security_ops->msg_msg_alloc_security(msg); |
@@ -840,7 +886,7 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | |||
840 | } | 886 | } |
841 | EXPORT_SYMBOL(security_secid_to_secctx); | 887 | EXPORT_SYMBOL(security_secid_to_secctx); |
842 | 888 | ||
843 | int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid) | 889 | int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) |
844 | { | 890 | { |
845 | return security_ops->secctx_to_secid(secdata, seclen, secid); | 891 | return security_ops->secctx_to_secid(secdata, seclen, secid); |
846 | } | 892 | } |
@@ -1014,26 +1060,27 @@ void security_inet_conn_established(struct sock *sk, | |||
1014 | 1060 | ||
1015 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1061 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
1016 | 1062 | ||
1017 | int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx) | 1063 | int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx) |
1018 | { | 1064 | { |
1019 | return security_ops->xfrm_policy_alloc_security(xp, sec_ctx); | 1065 | return security_ops->xfrm_policy_alloc_security(ctxp, sec_ctx); |
1020 | } | 1066 | } |
1021 | EXPORT_SYMBOL(security_xfrm_policy_alloc); | 1067 | EXPORT_SYMBOL(security_xfrm_policy_alloc); |
1022 | 1068 | ||
1023 | int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new) | 1069 | int security_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, |
1070 | struct xfrm_sec_ctx **new_ctxp) | ||
1024 | { | 1071 | { |
1025 | return security_ops->xfrm_policy_clone_security(old, new); | 1072 | return security_ops->xfrm_policy_clone_security(old_ctx, new_ctxp); |
1026 | } | 1073 | } |
1027 | 1074 | ||
1028 | void security_xfrm_policy_free(struct xfrm_policy *xp) | 1075 | void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx) |
1029 | { | 1076 | { |
1030 | security_ops->xfrm_policy_free_security(xp); | 1077 | security_ops->xfrm_policy_free_security(ctx); |
1031 | } | 1078 | } |
1032 | EXPORT_SYMBOL(security_xfrm_policy_free); | 1079 | EXPORT_SYMBOL(security_xfrm_policy_free); |
1033 | 1080 | ||
1034 | int security_xfrm_policy_delete(struct xfrm_policy *xp) | 1081 | int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) |
1035 | { | 1082 | { |
1036 | return security_ops->xfrm_policy_delete_security(xp); | 1083 | return security_ops->xfrm_policy_delete_security(ctx); |
1037 | } | 1084 | } |
1038 | 1085 | ||
1039 | int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) | 1086 | int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) |
@@ -1065,9 +1112,9 @@ void security_xfrm_state_free(struct xfrm_state *x) | |||
1065 | security_ops->xfrm_state_free_security(x); | 1112 | security_ops->xfrm_state_free_security(x); |
1066 | } | 1113 | } |
1067 | 1114 | ||
1068 | int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) | 1115 | int security_xfrm_policy_lookup(struct xfrm_sec_ctx *ctx, u32 fl_secid, u8 dir) |
1069 | { | 1116 | { |
1070 | return security_ops->xfrm_policy_lookup(xp, fl_secid, dir); | 1117 | return security_ops->xfrm_policy_lookup(ctx, fl_secid, dir); |
1071 | } | 1118 | } |
1072 | 1119 | ||
1073 | int security_xfrm_state_pol_flow_match(struct xfrm_state *x, | 1120 | int security_xfrm_state_pol_flow_match(struct xfrm_state *x, |
@@ -1109,4 +1156,34 @@ int security_key_permission(key_ref_t key_ref, | |||
1109 | return security_ops->key_permission(key_ref, context, perm); | 1156 | return security_ops->key_permission(key_ref, context, perm); |
1110 | } | 1157 | } |
1111 | 1158 | ||
1159 | int security_key_getsecurity(struct key *key, char **_buffer) | ||
1160 | { | ||
1161 | return security_ops->key_getsecurity(key, _buffer); | ||
1162 | } | ||
1163 | |||
1112 | #endif /* CONFIG_KEYS */ | 1164 | #endif /* CONFIG_KEYS */ |
1165 | |||
1166 | #ifdef CONFIG_AUDIT | ||
1167 | |||
1168 | int security_audit_rule_init(u32 field, u32 op, char *rulestr, void **lsmrule) | ||
1169 | { | ||
1170 | return security_ops->audit_rule_init(field, op, rulestr, lsmrule); | ||
1171 | } | ||
1172 | |||
1173 | int security_audit_rule_known(struct audit_krule *krule) | ||
1174 | { | ||
1175 | return security_ops->audit_rule_known(krule); | ||
1176 | } | ||
1177 | |||
1178 | void security_audit_rule_free(void *lsmrule) | ||
1179 | { | ||
1180 | security_ops->audit_rule_free(lsmrule); | ||
1181 | } | ||
1182 | |||
1183 | int security_audit_rule_match(u32 secid, u32 field, u32 op, void *lsmrule, | ||
1184 | struct audit_context *actx) | ||
1185 | { | ||
1186 | return security_ops->audit_rule_match(secid, field, op, lsmrule, actx); | ||
1187 | } | ||
1188 | |||
1189 | #endif /* CONFIG_AUDIT */ | ||