diff options
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/hooks.c | 74 |
1 files changed, 47 insertions, 27 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 83a535b7bc60..221def6a0b1d 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -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,20 +2401,8 @@ 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. */ |
@@ -2464,6 +2460,16 @@ static int selinux_inode_listsecurity(struct inode *inode, char *buffer, size_t | |||
2464 | return len; | 2460 | return len; |
2465 | } | 2461 | } |
2466 | 2462 | ||
2463 | static int selinux_inode_need_killpriv(struct dentry *dentry) | ||
2464 | { | ||
2465 | return secondary_ops->inode_need_killpriv(dentry); | ||
2466 | } | ||
2467 | |||
2468 | static int selinux_inode_killpriv(struct dentry *dentry) | ||
2469 | { | ||
2470 | return secondary_ops->inode_killpriv(dentry); | ||
2471 | } | ||
2472 | |||
2467 | /* file security operations */ | 2473 | /* file security operations */ |
2468 | 2474 | ||
2469 | static int selinux_revalidate_file_permission(struct file *file, int mask) | 2475 | static int selinux_revalidate_file_permission(struct file *file, int mask) |
@@ -2882,6 +2888,12 @@ static int selinux_task_setnice(struct task_struct *p, int nice) | |||
2882 | 2888 | ||
2883 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) | 2889 | static int selinux_task_setioprio(struct task_struct *p, int ioprio) |
2884 | { | 2890 | { |
2891 | int rc; | ||
2892 | |||
2893 | rc = secondary_ops->task_setioprio(p, ioprio); | ||
2894 | if (rc) | ||
2895 | return rc; | ||
2896 | |||
2885 | return task_has_perm(current, p, PROCESS__SETSCHED); | 2897 | return task_has_perm(current, p, PROCESS__SETSCHED); |
2886 | } | 2898 | } |
2887 | 2899 | ||
@@ -2911,6 +2923,12 @@ static int selinux_task_setrlimit(unsigned int resource, struct rlimit *new_rlim | |||
2911 | 2923 | ||
2912 | static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp) | 2924 | static int selinux_task_setscheduler(struct task_struct *p, int policy, struct sched_param *lp) |
2913 | { | 2925 | { |
2926 | int rc; | ||
2927 | |||
2928 | rc = secondary_ops->task_setscheduler(p, policy, lp); | ||
2929 | if (rc) | ||
2930 | return rc; | ||
2931 | |||
2914 | return task_has_perm(current, p, PROCESS__SETSCHED); | 2932 | return task_has_perm(current, p, PROCESS__SETSCHED); |
2915 | } | 2933 | } |
2916 | 2934 | ||
@@ -4830,6 +4848,8 @@ static struct security_operations selinux_ops = { | |||
4830 | .inode_getsecurity = selinux_inode_getsecurity, | 4848 | .inode_getsecurity = selinux_inode_getsecurity, |
4831 | .inode_setsecurity = selinux_inode_setsecurity, | 4849 | .inode_setsecurity = selinux_inode_setsecurity, |
4832 | .inode_listsecurity = selinux_inode_listsecurity, | 4850 | .inode_listsecurity = selinux_inode_listsecurity, |
4851 | .inode_need_killpriv = selinux_inode_need_killpriv, | ||
4852 | .inode_killpriv = selinux_inode_killpriv, | ||
4833 | 4853 | ||
4834 | .file_permission = selinux_file_permission, | 4854 | .file_permission = selinux_file_permission, |
4835 | .file_alloc_security = selinux_file_alloc_security, | 4855 | .file_alloc_security = selinux_file_alloc_security, |