diff options
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 96 |
1 files changed, 48 insertions, 48 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 97b7e2738097..24e1b1885de7 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | * as published by the Free Software Foundation. | 22 | * as published by the Free Software Foundation. |
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| 27 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
| 28 | #include <linux/ptrace.h> | 27 | #include <linux/ptrace.h> |
| @@ -86,6 +85,7 @@ | |||
| 86 | extern unsigned int policydb_loaded_version; | 85 | extern unsigned int policydb_loaded_version; |
| 87 | extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); | 86 | extern int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm); |
| 88 | extern int selinux_compat_net; | 87 | extern int selinux_compat_net; |
| 88 | extern struct security_operations *security_ops; | ||
| 89 | 89 | ||
| 90 | #ifdef CONFIG_SECURITY_SELINUX_DEVELOP | 90 | #ifdef CONFIG_SECURITY_SELINUX_DEVELOP |
| 91 | int selinux_enforcing = 0; | 91 | int selinux_enforcing = 0; |
| @@ -2297,6 +2297,25 @@ static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) | |||
| 2297 | return dentry_has_perm(current, mnt, dentry, FILE__GETATTR); | 2297 | return dentry_has_perm(current, mnt, dentry, FILE__GETATTR); |
| 2298 | } | 2298 | } |
| 2299 | 2299 | ||
| 2300 | static int selinux_inode_setotherxattr(struct dentry *dentry, char *name) | ||
| 2301 | { | ||
| 2302 | if (!strncmp(name, XATTR_SECURITY_PREFIX, | ||
| 2303 | sizeof XATTR_SECURITY_PREFIX - 1)) { | ||
| 2304 | if (!strcmp(name, XATTR_NAME_CAPS)) { | ||
| 2305 | if (!capable(CAP_SETFCAP)) | ||
| 2306 | return -EPERM; | ||
| 2307 | } else if (!capable(CAP_SYS_ADMIN)) { | ||
| 2308 | /* A different attribute in the security namespace. | ||
| 2309 | Restrict to administrator. */ | ||
| 2310 | return -EPERM; | ||
| 2311 | } | ||
| 2312 | } | ||
| 2313 | |||
| 2314 | /* Not an attribute we recognize, so just check the | ||
| 2315 | ordinary setattr permission. */ | ||
| 2316 | return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); | ||
| 2317 | } | ||
| 2318 | |||
| 2300 | static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags) | 2319 | static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value, size_t size, int flags) |
| 2301 | { | 2320 | { |
| 2302 | struct task_security_struct *tsec = current->security; | 2321 | struct task_security_struct *tsec = current->security; |
| @@ -2307,19 +2326,8 @@ static int selinux_inode_setxattr(struct dentry *dentry, char *name, void *value | |||
| 2307 | u32 newsid; | 2326 | u32 newsid; |
| 2308 | int rc = 0; | 2327 | int rc = 0; |
| 2309 | 2328 | ||
| 2310 | if (strcmp(name, XATTR_NAME_SELINUX)) { | 2329 | if (strcmp(name, XATTR_NAME_SELINUX)) |
| 2311 | if (!strncmp(name, XATTR_SECURITY_PREFIX, | 2330 | return selinux_inode_setotherxattr(dentry, name); |
| 2312 | sizeof XATTR_SECURITY_PREFIX - 1) && | ||
| 2313 | !capable(CAP_SYS_ADMIN)) { | ||
| 2314 | /* A different attribute in the security namespace. | ||
| 2315 | Restrict to administrator. */ | ||
| 2316 | return -EPERM; | ||
| 2317 | } | ||
| 2318 | |||
| 2319 | /* Not an attribute we recognize, so just check the | ||
| 2320 | ordinary setattr permission. */ | ||
| 2321 | return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); | ||
| 2322 | } | ||
| 2323 | 2331 | ||
| 2324 | sbsec = inode->i_sb->s_security; | 2332 | sbsec = inode->i_sb->s_security; |
| 2325 | if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) | 2333 | if (sbsec->behavior == SECURITY_FS_USE_MNTPOINT) |
| @@ -2393,31 +2401,14 @@ static int selinux_inode_listxattr (struct dentry *dentry) | |||
| 2393 | 2401 | ||
| 2394 | static int selinux_inode_removexattr (struct dentry *dentry, char *name) | 2402 | static int selinux_inode_removexattr (struct dentry *dentry, char *name) |
| 2395 | { | 2403 | { |
| 2396 | if (strcmp(name, XATTR_NAME_SELINUX)) { | 2404 | if (strcmp(name, XATTR_NAME_SELINUX)) |
| 2397 | if (!strncmp(name, XATTR_SECURITY_PREFIX, | 2405 | return selinux_inode_setotherxattr(dentry, name); |
| 2398 | sizeof XATTR_SECURITY_PREFIX - 1) && | ||
| 2399 | !capable(CAP_SYS_ADMIN)) { | ||
| 2400 | /* A different attribute in the security namespace. | ||
| 2401 | Restrict to administrator. */ | ||
| 2402 | return -EPERM; | ||
| 2403 | } | ||
| 2404 | |||
| 2405 | /* Not an attribute we recognize, so just check the | ||
| 2406 | ordinary setattr permission. Might want a separate | ||
| 2407 | permission for removexattr. */ | ||
| 2408 | return dentry_has_perm(current, NULL, dentry, FILE__SETATTR); | ||
| 2409 | } | ||
| 2410 | 2406 | ||
| 2411 | /* No one is allowed to remove a SELinux security label. | 2407 | /* No one is allowed to remove a SELinux security label. |
| 2412 | You can change the label, but all data must be labeled. */ | 2408 | You can change the label, but all data must be labeled. */ |
| 2413 | return -EACCES; | 2409 | return -EACCES; |
| 2414 | } | 2410 | } |
| 2415 | 2411 | ||
| 2416 | static const char *selinux_inode_xattr_getsuffix(void) | ||
| 2417 | { | ||
| 2418 | return XATTR_SELINUX_SUFFIX; | ||
| 2419 | } | ||
| 2420 | |||
| 2421 | /* | 2412 | /* |
| 2422 | * Copy the in-core inode security context value to the user. If the | 2413 | * Copy the in-core inode security context value to the user. If the |
| 2423 | * getxattr() prior to this succeeded, check to see if we need to | 2414 | * getxattr() prior to this succeeded, check to see if we need to |
| @@ -2464,6 +2455,16 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t | |||
| 2464 | return len; | 2455 | return len; |
| 2465 | } | 2456 | } |
| 2466 | 2457 | ||
| 2458 | static int selinux_inode_need_killpriv(struct dentry *dentry) | ||
| 2459 | { | ||
| 2460 | return secondary_ops->inode_need_killpriv(dentry); | ||
| 2461 | } | ||
| 2462 | |||
| 2463 | static int selinux_inode_killpriv(struct dentry *dentry) | ||
| 2464 | { | ||
| 2465 | return secondary_ops->inode_killpriv(dentry); | ||
| 2466 | } | ||
| 2467 | |||
| 2467 | /* file security operations */ | 2468 | /* file security operations */ |
| 2468 | 2469 | ||
| 2469 | static int selinux_revalidate_file_permission(struct file *file, int mask) | 2470 | static int selinux_revalidate_file_permission(struct file *file, int mask) |
| @@ -2882,6 +2883,12 @@ static int selinux_task_setnice(struct task_struct *p, int nice) | |||
| 2882 | 2883 | ||
| 2883 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) | 2884 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) |
| 2884 | { | 2885 | { |
| 2886 | int rc; | ||
| 2887 | |||
| 2888 | rc = secondary_ops->task_setioprio(p, ioprio); | ||
| 2889 | if (rc) | ||
| 2890 | return rc; | ||
| 2891 | |||
| 2885 | return task_has_perm(current, p, PROCESS__SETSCHED); | 2892 | return task_has_perm(current, p, PROCESS__SETSCHED); |
| 2886 | } | 2893 | } |
| 2887 | 2894 | ||
| @@ -2911,6 +2918,12 @@ static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim | |||
| 2911 | 2918 | ||
| 2912 | static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp) | 2919 | static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp) |
| 2913 | { | 2920 | { |
| 2921 | int rc; | ||
| 2922 | |||
| 2923 | rc = secondary_ops->task_setscheduler(p, policy, lp); | ||
| 2924 | if (rc) | ||
| 2925 | return rc; | ||
| 2926 | |||
| 2914 | return task_has_perm(current, p, PROCESS__SETSCHED); | 2927 | return task_has_perm(current, p, PROCESS__SETSCHED); |
| 2915 | } | 2928 | } |
| 2916 | 2929 | ||
| @@ -4536,19 +4549,6 @@ static int selinux_register_security (const char *name, struct security_operatio | |||
| 4536 | return 0; | 4549 | return 0; |
| 4537 | } | 4550 | } |
| 4538 | 4551 | ||
| 4539 | static int selinux_unregister_security (const char *name, struct security_operations *ops) | ||
| 4540 | { | ||
| 4541 | if (ops != secondary_ops) { | ||
| 4542 | printk(KERN_ERR "%s: trying to unregister a security module " | ||
| 4543 | "that is not registered.\n", __FUNCTION__); | ||
| 4544 | return -EINVAL; | ||
| 4545 | } | ||
| 4546 | |||
| 4547 | secondary_ops = original_ops; | ||
| 4548 | |||
| 4549 | return 0; | ||
| 4550 | } | ||
| 4551 | |||
| 4552 | static void selinux_d_instantiate (struct dentry *dentry, struct inode *inode) | 4552 | static void selinux_d_instantiate (struct dentry *dentry, struct inode *inode) |
| 4553 | { | 4553 | { |
| 4554 | if (inode) | 4554 | if (inode) |
| @@ -4826,10 +4826,11 @@ static struct security_operations selinux_ops = { | |||
| 4826 | .inode_getxattr = selinux_inode_getxattr, | 4826 | .inode_getxattr = selinux_inode_getxattr, |
| 4827 | .inode_listxattr = selinux_inode_listxattr, | 4827 | .inode_listxattr = selinux_inode_listxattr, |
| 4828 | .inode_removexattr = selinux_inode_removexattr, | 4828 | .inode_removexattr = selinux_inode_removexattr, |
| 4829 | .inode_xattr_getsuffix = selinux_inode_xattr_getsuffix, | ||
| 4830 | .inode_getsecurity = selinux_inode_getsecurity, | 4829 | .inode_getsecurity = selinux_inode_getsecurity, |
| 4831 | .inode_setsecurity = selinux_inode_setsecurity, | 4830 | .inode_setsecurity = selinux_inode_setsecurity, |
| 4832 | .inode_listsecurity = selinux_inode_listsecurity, | 4831 | .inode_listsecurity = selinux_inode_listsecurity, |
| 4832 | .inode_need_killpriv = selinux_inode_need_killpriv, | ||
| 4833 | .inode_killpriv = selinux_inode_killpriv, | ||
| 4833 | 4834 | ||
| 4834 | .file_permission = selinux_file_permission, | 4835 | .file_permission = selinux_file_permission, |
| 4835 | .file_alloc_security = selinux_file_alloc_security, | 4836 | .file_alloc_security = selinux_file_alloc_security, |
| @@ -4894,7 +4895,6 @@ static struct security_operations selinux_ops = { | |||
| 4894 | .sem_semop = selinux_sem_semop, | 4895 | .sem_semop = selinux_sem_semop, |
| 4895 | 4896 | ||
| 4896 | .register_security = selinux_register_security, | 4897 | .register_security = selinux_register_security, |
| 4897 | .unregister_security = selinux_unregister_security, | ||
| 4898 | 4898 | ||
| 4899 | .d_instantiate = selinux_d_instantiate, | 4899 | .d_instantiate = selinux_d_instantiate, |
| 4900 | 4900 | ||
