diff options
author | James Morris <james.l.morris@oracle.com> | 2016-05-05 19:31:34 -0400 |
---|---|---|
committer | James Morris <james.l.morris@oracle.com> | 2016-05-05 19:31:34 -0400 |
commit | a6926cc989eb8e3349ae9b858177608e86f7257c (patch) | |
tree | 201583130b6b5d323ba3c5b3ef44565bf113f5f1 /security | |
parent | 0250abcd726b4eba8a6175f09656fe544ed6491a (diff) | |
parent | c2316dbf124257ae19fd2e29cb5ec51060649d38 (diff) |
Merge branch 'stable-4.7' of git://git.infradead.org/users/pcmoore/selinux into next
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/hooks.c | 144 | ||||
-rw-r--r-- | security/selinux/include/classmap.h | 30 | ||||
-rw-r--r-- | security/selinux/include/conditional.h | 2 | ||||
-rw-r--r-- | security/selinux/include/objsec.h | 5 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 6 |
5 files changed, 127 insertions, 60 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 912deee3f01e..a00ab81ab719 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -259,7 +259,7 @@ static int __inode_security_revalidate(struct inode *inode, | |||
259 | 259 | ||
260 | might_sleep_if(may_sleep); | 260 | might_sleep_if(may_sleep); |
261 | 261 | ||
262 | if (isec->initialized == LABEL_INVALID) { | 262 | if (ss_initialized && isec->initialized != LABEL_INITIALIZED) { |
263 | if (!may_sleep) | 263 | if (!may_sleep) |
264 | return -ECHILD; | 264 | return -ECHILD; |
265 | 265 | ||
@@ -297,6 +297,13 @@ static struct inode_security_struct *inode_security(struct inode *inode) | |||
297 | return inode->i_security; | 297 | return inode->i_security; |
298 | } | 298 | } |
299 | 299 | ||
300 | static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry) | ||
301 | { | ||
302 | struct inode *inode = d_backing_inode(dentry); | ||
303 | |||
304 | return inode->i_security; | ||
305 | } | ||
306 | |||
300 | /* | 307 | /* |
301 | * Get the security label of a dentry's backing inode. | 308 | * Get the security label of a dentry's backing inode. |
302 | */ | 309 | */ |
@@ -686,7 +693,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
686 | struct superblock_security_struct *sbsec = sb->s_security; | 693 | struct superblock_security_struct *sbsec = sb->s_security; |
687 | const char *name = sb->s_type->name; | 694 | const char *name = sb->s_type->name; |
688 | struct dentry *root = sbsec->sb->s_root; | 695 | struct dentry *root = sbsec->sb->s_root; |
689 | struct inode_security_struct *root_isec = backing_inode_security(root); | 696 | struct inode_security_struct *root_isec; |
690 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; | 697 | u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0; |
691 | u32 defcontext_sid = 0; | 698 | u32 defcontext_sid = 0; |
692 | char **mount_options = opts->mnt_opts; | 699 | char **mount_options = opts->mnt_opts; |
@@ -729,6 +736,8 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
729 | && (num_opts == 0)) | 736 | && (num_opts == 0)) |
730 | goto out; | 737 | goto out; |
731 | 738 | ||
739 | root_isec = backing_inode_security_novalidate(root); | ||
740 | |||
732 | /* | 741 | /* |
733 | * parse the mount options, check if they are valid sids. | 742 | * parse the mount options, check if they are valid sids. |
734 | * also check if someone is trying to mount the same sb more | 743 | * also check if someone is trying to mount the same sb more |
@@ -1622,7 +1631,7 @@ static int current_has_perm(const struct task_struct *tsk, | |||
1622 | 1631 | ||
1623 | /* Check whether a task is allowed to use a capability. */ | 1632 | /* Check whether a task is allowed to use a capability. */ |
1624 | static int cred_has_capability(const struct cred *cred, | 1633 | static int cred_has_capability(const struct cred *cred, |
1625 | int cap, int audit) | 1634 | int cap, int audit, bool initns) |
1626 | { | 1635 | { |
1627 | struct common_audit_data ad; | 1636 | struct common_audit_data ad; |
1628 | struct av_decision avd; | 1637 | struct av_decision avd; |
@@ -1636,10 +1645,10 @@ static int cred_has_capability(const struct cred *cred, | |||
1636 | 1645 | ||
1637 | switch (CAP_TO_INDEX(cap)) { | 1646 | switch (CAP_TO_INDEX(cap)) { |
1638 | case 0: | 1647 | case 0: |
1639 | sclass = SECCLASS_CAPABILITY; | 1648 | sclass = initns ? SECCLASS_CAPABILITY : SECCLASS_CAP_USERNS; |
1640 | break; | 1649 | break; |
1641 | case 1: | 1650 | case 1: |
1642 | sclass = SECCLASS_CAPABILITY2; | 1651 | sclass = initns ? SECCLASS_CAPABILITY2 : SECCLASS_CAP2_USERNS; |
1643 | break; | 1652 | break; |
1644 | default: | 1653 | default: |
1645 | printk(KERN_ERR | 1654 | printk(KERN_ERR |
@@ -1781,7 +1790,6 @@ static int selinux_determine_inode_label(struct inode *dir, | |||
1781 | u32 *_new_isid) | 1790 | u32 *_new_isid) |
1782 | { | 1791 | { |
1783 | const struct superblock_security_struct *sbsec = dir->i_sb->s_security; | 1792 | const struct superblock_security_struct *sbsec = dir->i_sb->s_security; |
1784 | const struct inode_security_struct *dsec = inode_security(dir); | ||
1785 | const struct task_security_struct *tsec = current_security(); | 1793 | const struct task_security_struct *tsec = current_security(); |
1786 | 1794 | ||
1787 | if ((sbsec->flags & SE_SBINITIALIZED) && | 1795 | if ((sbsec->flags & SE_SBINITIALIZED) && |
@@ -1791,6 +1799,7 @@ static int selinux_determine_inode_label(struct inode *dir, | |||
1791 | tsec->create_sid) { | 1799 | tsec->create_sid) { |
1792 | *_new_isid = tsec->create_sid; | 1800 | *_new_isid = tsec->create_sid; |
1793 | } else { | 1801 | } else { |
1802 | const struct inode_security_struct *dsec = inode_security(dir); | ||
1794 | return security_transition_sid(tsec->sid, dsec->sid, tclass, | 1803 | return security_transition_sid(tsec->sid, dsec->sid, tclass, |
1795 | name, _new_isid); | 1804 | name, _new_isid); |
1796 | } | 1805 | } |
@@ -2075,7 +2084,7 @@ static int selinux_binder_transfer_file(struct task_struct *from, | |||
2075 | u32 sid = task_sid(to); | 2084 | u32 sid = task_sid(to); |
2076 | struct file_security_struct *fsec = file->f_security; | 2085 | struct file_security_struct *fsec = file->f_security; |
2077 | struct dentry *dentry = file->f_path.dentry; | 2086 | struct dentry *dentry = file->f_path.dentry; |
2078 | struct inode_security_struct *isec = backing_inode_security(dentry); | 2087 | struct inode_security_struct *isec; |
2079 | struct common_audit_data ad; | 2088 | struct common_audit_data ad; |
2080 | int rc; | 2089 | int rc; |
2081 | 2090 | ||
@@ -2094,6 +2103,7 @@ static int selinux_binder_transfer_file(struct task_struct *from, | |||
2094 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) | 2103 | if (unlikely(IS_PRIVATE(d_backing_inode(dentry)))) |
2095 | return 0; | 2104 | return 0; |
2096 | 2105 | ||
2106 | isec = backing_inode_security(dentry); | ||
2097 | return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file), | 2107 | return avc_has_perm(sid, isec->sid, isec->sclass, file_to_av(file), |
2098 | &ad); | 2108 | &ad); |
2099 | } | 2109 | } |
@@ -2142,7 +2152,7 @@ static int selinux_capset(struct cred *new, const struct cred *old, | |||
2142 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, | 2152 | static int selinux_capable(const struct cred *cred, struct user_namespace *ns, |
2143 | int cap, int audit) | 2153 | int cap, int audit) |
2144 | { | 2154 | { |
2145 | return cred_has_capability(cred, cap, audit); | 2155 | return cred_has_capability(cred, cap, audit, ns == &init_user_ns); |
2146 | } | 2156 | } |
2147 | 2157 | ||
2148 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) | 2158 | static int selinux_quotactl(int cmds, int type, int id, struct super_block *sb) |
@@ -2220,7 +2230,7 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
2220 | int rc, cap_sys_admin = 0; | 2230 | int rc, cap_sys_admin = 0; |
2221 | 2231 | ||
2222 | rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN, | 2232 | rc = cred_has_capability(current_cred(), CAP_SYS_ADMIN, |
2223 | SECURITY_CAP_NOAUDIT); | 2233 | SECURITY_CAP_NOAUDIT, true); |
2224 | if (rc == 0) | 2234 | if (rc == 0) |
2225 | cap_sys_admin = 1; | 2235 | cap_sys_admin = 1; |
2226 | 2236 | ||
@@ -2229,6 +2239,20 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages) | |||
2229 | 2239 | ||
2230 | /* binprm security operations */ | 2240 | /* binprm security operations */ |
2231 | 2241 | ||
2242 | static u32 ptrace_parent_sid(struct task_struct *task) | ||
2243 | { | ||
2244 | u32 sid = 0; | ||
2245 | struct task_struct *tracer; | ||
2246 | |||
2247 | rcu_read_lock(); | ||
2248 | tracer = ptrace_parent(task); | ||
2249 | if (tracer) | ||
2250 | sid = task_sid(tracer); | ||
2251 | rcu_read_unlock(); | ||
2252 | |||
2253 | return sid; | ||
2254 | } | ||
2255 | |||
2232 | static int check_nnp_nosuid(const struct linux_binprm *bprm, | 2256 | static int check_nnp_nosuid(const struct linux_binprm *bprm, |
2233 | const struct task_security_struct *old_tsec, | 2257 | const struct task_security_struct *old_tsec, |
2234 | const struct task_security_struct *new_tsec) | 2258 | const struct task_security_struct *new_tsec) |
@@ -2350,18 +2374,7 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) | |||
2350 | * changes its SID has the appropriate permit */ | 2374 | * changes its SID has the appropriate permit */ |
2351 | if (bprm->unsafe & | 2375 | if (bprm->unsafe & |
2352 | (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { | 2376 | (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) { |
2353 | struct task_struct *tracer; | 2377 | u32 ptsid = ptrace_parent_sid(current); |
2354 | struct task_security_struct *sec; | ||
2355 | u32 ptsid = 0; | ||
2356 | |||
2357 | rcu_read_lock(); | ||
2358 | tracer = ptrace_parent(current); | ||
2359 | if (likely(tracer != NULL)) { | ||
2360 | sec = __task_cred(tracer)->security; | ||
2361 | ptsid = sec->sid; | ||
2362 | } | ||
2363 | rcu_read_unlock(); | ||
2364 | |||
2365 | if (ptsid != 0) { | 2378 | if (ptsid != 0) { |
2366 | rc = avc_has_perm(ptsid, new_tsec->sid, | 2379 | rc = avc_has_perm(ptsid, new_tsec->sid, |
2367 | SECCLASS_PROCESS, | 2380 | SECCLASS_PROCESS, |
@@ -3045,7 +3058,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
3045 | const void *value, size_t size, int flags) | 3058 | const void *value, size_t size, int flags) |
3046 | { | 3059 | { |
3047 | struct inode *inode = d_backing_inode(dentry); | 3060 | struct inode *inode = d_backing_inode(dentry); |
3048 | struct inode_security_struct *isec = backing_inode_security(dentry); | 3061 | struct inode_security_struct *isec; |
3049 | struct superblock_security_struct *sbsec; | 3062 | struct superblock_security_struct *sbsec; |
3050 | struct common_audit_data ad; | 3063 | struct common_audit_data ad; |
3051 | u32 newsid, sid = current_sid(); | 3064 | u32 newsid, sid = current_sid(); |
@@ -3064,6 +3077,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
3064 | ad.type = LSM_AUDIT_DATA_DENTRY; | 3077 | ad.type = LSM_AUDIT_DATA_DENTRY; |
3065 | ad.u.dentry = dentry; | 3078 | ad.u.dentry = dentry; |
3066 | 3079 | ||
3080 | isec = backing_inode_security(dentry); | ||
3067 | rc = avc_has_perm(sid, isec->sid, isec->sclass, | 3081 | rc = avc_has_perm(sid, isec->sid, isec->sclass, |
3068 | FILE__RELABELFROM, &ad); | 3082 | FILE__RELABELFROM, &ad); |
3069 | if (rc) | 3083 | if (rc) |
@@ -3122,7 +3136,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, | |||
3122 | int flags) | 3136 | int flags) |
3123 | { | 3137 | { |
3124 | struct inode *inode = d_backing_inode(dentry); | 3138 | struct inode *inode = d_backing_inode(dentry); |
3125 | struct inode_security_struct *isec = backing_inode_security(dentry); | 3139 | struct inode_security_struct *isec; |
3126 | u32 newsid; | 3140 | u32 newsid; |
3127 | int rc; | 3141 | int rc; |
3128 | 3142 | ||
@@ -3139,6 +3153,7 @@ static void selinux_inode_post_setxattr(struct dentry *dentry, const char *name, | |||
3139 | return; | 3153 | return; |
3140 | } | 3154 | } |
3141 | 3155 | ||
3156 | isec = backing_inode_security(dentry); | ||
3142 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 3157 | isec->sclass = inode_mode_to_security_class(inode->i_mode); |
3143 | isec->sid = newsid; | 3158 | isec->sid = newsid; |
3144 | isec->initialized = LABEL_INITIALIZED; | 3159 | isec->initialized = LABEL_INITIALIZED; |
@@ -3180,7 +3195,7 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void | |||
3180 | u32 size; | 3195 | u32 size; |
3181 | int error; | 3196 | int error; |
3182 | char *context = NULL; | 3197 | char *context = NULL; |
3183 | struct inode_security_struct *isec = inode_security(inode); | 3198 | struct inode_security_struct *isec; |
3184 | 3199 | ||
3185 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) | 3200 | if (strcmp(name, XATTR_SELINUX_SUFFIX)) |
3186 | return -EOPNOTSUPP; | 3201 | return -EOPNOTSUPP; |
@@ -3198,7 +3213,8 @@ static int selinux_inode_getsecurity(struct inode *inode, const char *name, void | |||
3198 | SECURITY_CAP_NOAUDIT); | 3213 | SECURITY_CAP_NOAUDIT); |
3199 | if (!error) | 3214 | if (!error) |
3200 | error = cred_has_capability(current_cred(), CAP_MAC_ADMIN, | 3215 | error = cred_has_capability(current_cred(), CAP_MAC_ADMIN, |
3201 | SECURITY_CAP_NOAUDIT); | 3216 | SECURITY_CAP_NOAUDIT, true); |
3217 | isec = inode_security(inode); | ||
3202 | if (!error) | 3218 | if (!error) |
3203 | error = security_sid_to_context_force(isec->sid, &context, | 3219 | error = security_sid_to_context_force(isec->sid, &context, |
3204 | &size); | 3220 | &size); |
@@ -3219,7 +3235,7 @@ out_nofree: | |||
3219 | static int selinux_inode_setsecurity(struct inode *inode, const char *name, | 3235 | static int selinux_inode_setsecurity(struct inode *inode, const char *name, |
3220 | const void *value, size_t size, int flags) | 3236 | const void *value, size_t size, int flags) |
3221 | { | 3237 | { |
3222 | struct inode_security_struct *isec = inode_security(inode); | 3238 | struct inode_security_struct *isec = inode_security_novalidate(inode); |
3223 | u32 newsid; | 3239 | u32 newsid; |
3224 | int rc; | 3240 | int rc; |
3225 | 3241 | ||
@@ -3308,7 +3324,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file, | |||
3308 | struct common_audit_data ad; | 3324 | struct common_audit_data ad; |
3309 | struct file_security_struct *fsec = file->f_security; | 3325 | struct file_security_struct *fsec = file->f_security; |
3310 | struct inode *inode = file_inode(file); | 3326 | struct inode *inode = file_inode(file); |
3311 | struct inode_security_struct *isec = inode_security(inode); | 3327 | struct inode_security_struct *isec; |
3312 | struct lsm_ioctlop_audit ioctl; | 3328 | struct lsm_ioctlop_audit ioctl; |
3313 | u32 ssid = cred_sid(cred); | 3329 | u32 ssid = cred_sid(cred); |
3314 | int rc; | 3330 | int rc; |
@@ -3332,6 +3348,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file, | |||
3332 | if (unlikely(IS_PRIVATE(inode))) | 3348 | if (unlikely(IS_PRIVATE(inode))) |
3333 | return 0; | 3349 | return 0; |
3334 | 3350 | ||
3351 | isec = inode_security(inode); | ||
3335 | rc = avc_has_extended_perms(ssid, isec->sid, isec->sclass, | 3352 | rc = avc_has_extended_perms(ssid, isec->sid, isec->sclass, |
3336 | requested, driver, xperm, &ad); | 3353 | requested, driver, xperm, &ad); |
3337 | out: | 3354 | out: |
@@ -3373,7 +3390,7 @@ static int selinux_file_ioctl(struct file *file, unsigned int cmd, | |||
3373 | case KDSKBENT: | 3390 | case KDSKBENT: |
3374 | case KDSKBSENT: | 3391 | case KDSKBSENT: |
3375 | error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, | 3392 | error = cred_has_capability(cred, CAP_SYS_TTY_CONFIG, |
3376 | SECURITY_CAP_AUDIT); | 3393 | SECURITY_CAP_AUDIT, true); |
3377 | break; | 3394 | break; |
3378 | 3395 | ||
3379 | /* default case assumes that the command will go | 3396 | /* default case assumes that the command will go |
@@ -3462,8 +3479,9 @@ static int selinux_file_mprotect(struct vm_area_struct *vma, | |||
3462 | vma->vm_end <= vma->vm_mm->brk) { | 3479 | vma->vm_end <= vma->vm_mm->brk) { |
3463 | rc = cred_has_perm(cred, cred, PROCESS__EXECHEAP); | 3480 | rc = cred_has_perm(cred, cred, PROCESS__EXECHEAP); |
3464 | } else if (!vma->vm_file && | 3481 | } else if (!vma->vm_file && |
3465 | vma->vm_start <= vma->vm_mm->start_stack && | 3482 | ((vma->vm_start <= vma->vm_mm->start_stack && |
3466 | vma->vm_end >= vma->vm_mm->start_stack) { | 3483 | vma->vm_end >= vma->vm_mm->start_stack) || |
3484 | vma_is_stack_for_task(vma, current))) { | ||
3467 | rc = current_has_perm(current, PROCESS__EXECSTACK); | 3485 | rc = current_has_perm(current, PROCESS__EXECSTACK); |
3468 | } else if (vma->vm_file && vma->anon_vma) { | 3486 | } else if (vma->vm_file && vma->anon_vma) { |
3469 | /* | 3487 | /* |
@@ -3719,6 +3737,52 @@ static int selinux_kernel_module_request(char *kmod_name) | |||
3719 | SYSTEM__MODULE_REQUEST, &ad); | 3737 | SYSTEM__MODULE_REQUEST, &ad); |
3720 | } | 3738 | } |
3721 | 3739 | ||
3740 | static int selinux_kernel_module_from_file(struct file *file) | ||
3741 | { | ||
3742 | struct common_audit_data ad; | ||
3743 | struct inode_security_struct *isec; | ||
3744 | struct file_security_struct *fsec; | ||
3745 | u32 sid = current_sid(); | ||
3746 | int rc; | ||
3747 | |||
3748 | /* init_module */ | ||
3749 | if (file == NULL) | ||
3750 | return avc_has_perm(sid, sid, SECCLASS_SYSTEM, | ||
3751 | SYSTEM__MODULE_LOAD, NULL); | ||
3752 | |||
3753 | /* finit_module */ | ||
3754 | |||
3755 | ad.type = LSM_AUDIT_DATA_PATH; | ||
3756 | ad.u.path = file->f_path; | ||
3757 | |||
3758 | fsec = file->f_security; | ||
3759 | if (sid != fsec->sid) { | ||
3760 | rc = avc_has_perm(sid, fsec->sid, SECCLASS_FD, FD__USE, &ad); | ||
3761 | if (rc) | ||
3762 | return rc; | ||
3763 | } | ||
3764 | |||
3765 | isec = inode_security(file_inode(file)); | ||
3766 | return avc_has_perm(sid, isec->sid, SECCLASS_SYSTEM, | ||
3767 | SYSTEM__MODULE_LOAD, &ad); | ||
3768 | } | ||
3769 | |||
3770 | static int selinux_kernel_read_file(struct file *file, | ||
3771 | enum kernel_read_file_id id) | ||
3772 | { | ||
3773 | int rc = 0; | ||
3774 | |||
3775 | switch (id) { | ||
3776 | case READING_MODULE: | ||
3777 | rc = selinux_kernel_module_from_file(file); | ||
3778 | break; | ||
3779 | default: | ||
3780 | break; | ||
3781 | } | ||
3782 | |||
3783 | return rc; | ||
3784 | } | ||
3785 | |||
3722 | static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) | 3786 | static int selinux_task_setpgid(struct task_struct *p, pid_t pgid) |
3723 | { | 3787 | { |
3724 | return current_has_perm(p, PROCESS__SETPGID); | 3788 | return current_has_perm(p, PROCESS__SETPGID); |
@@ -4598,6 +4662,7 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff * | |||
4598 | { | 4662 | { |
4599 | u32 peer_secid = SECSID_NULL; | 4663 | u32 peer_secid = SECSID_NULL; |
4600 | u16 family; | 4664 | u16 family; |
4665 | struct inode_security_struct *isec; | ||
4601 | 4666 | ||
4602 | if (skb && skb->protocol == htons(ETH_P_IP)) | 4667 | if (skb && skb->protocol == htons(ETH_P_IP)) |
4603 | family = PF_INET; | 4668 | family = PF_INET; |
@@ -4608,9 +4673,10 @@ static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff * | |||
4608 | else | 4673 | else |
4609 | goto out; | 4674 | goto out; |
4610 | 4675 | ||
4611 | if (sock && family == PF_UNIX) | 4676 | if (sock && family == PF_UNIX) { |
4612 | selinux_inode_getsecid(SOCK_INODE(sock), &peer_secid); | 4677 | isec = inode_security_novalidate(SOCK_INODE(sock)); |
4613 | else if (skb) | 4678 | peer_secid = isec->sid; |
4679 | } else if (skb) | ||
4614 | selinux_skb_peerlbl_sid(skb, family, &peer_secid); | 4680 | selinux_skb_peerlbl_sid(skb, family, &peer_secid); |
4615 | 4681 | ||
4616 | out: | 4682 | out: |
@@ -5675,7 +5741,6 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5675 | char *name, void *value, size_t size) | 5741 | char *name, void *value, size_t size) |
5676 | { | 5742 | { |
5677 | struct task_security_struct *tsec; | 5743 | struct task_security_struct *tsec; |
5678 | struct task_struct *tracer; | ||
5679 | struct cred *new; | 5744 | struct cred *new; |
5680 | u32 sid = 0, ptsid; | 5745 | u32 sid = 0, ptsid; |
5681 | int error; | 5746 | int error; |
@@ -5782,14 +5847,8 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5782 | 5847 | ||
5783 | /* Check for ptracing, and update the task SID if ok. | 5848 | /* Check for ptracing, and update the task SID if ok. |
5784 | Otherwise, leave SID unchanged and fail. */ | 5849 | Otherwise, leave SID unchanged and fail. */ |
5785 | ptsid = 0; | 5850 | ptsid = ptrace_parent_sid(p); |
5786 | rcu_read_lock(); | 5851 | if (ptsid != 0) { |
5787 | tracer = ptrace_parent(p); | ||
5788 | if (tracer) | ||
5789 | ptsid = task_sid(tracer); | ||
5790 | rcu_read_unlock(); | ||
5791 | |||
5792 | if (tracer) { | ||
5793 | error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS, | 5852 | error = avc_has_perm(ptsid, sid, SECCLASS_PROCESS, |
5794 | PROCESS__PTRACE, NULL); | 5853 | PROCESS__PTRACE, NULL); |
5795 | if (error) | 5854 | if (error) |
@@ -6020,6 +6079,7 @@ static struct security_hook_list selinux_hooks[] = { | |||
6020 | LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as), | 6079 | LSM_HOOK_INIT(kernel_act_as, selinux_kernel_act_as), |
6021 | LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as), | 6080 | LSM_HOOK_INIT(kernel_create_files_as, selinux_kernel_create_files_as), |
6022 | LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request), | 6081 | LSM_HOOK_INIT(kernel_module_request, selinux_kernel_module_request), |
6082 | LSM_HOOK_INIT(kernel_read_file, selinux_kernel_read_file), | ||
6023 | LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid), | 6083 | LSM_HOOK_INIT(task_setpgid, selinux_task_setpgid), |
6024 | LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid), | 6084 | LSM_HOOK_INIT(task_getpgid, selinux_task_getpgid), |
6025 | LSM_HOOK_INIT(task_getsid, selinux_task_getsid), | 6085 | LSM_HOOK_INIT(task_getsid, selinux_task_getsid), |
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h index ef83c4b85a33..1f1f4b2f6018 100644 --- a/security/selinux/include/classmap.h +++ b/security/selinux/include/classmap.h | |||
@@ -12,6 +12,18 @@ | |||
12 | #define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \ | 12 | #define COMMON_IPC_PERMS "create", "destroy", "getattr", "setattr", "read", \ |
13 | "write", "associate", "unix_read", "unix_write" | 13 | "write", "associate", "unix_read", "unix_write" |
14 | 14 | ||
15 | #define COMMON_CAP_PERMS "chown", "dac_override", "dac_read_search", \ | ||
16 | "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap", \ | ||
17 | "linux_immutable", "net_bind_service", "net_broadcast", \ | ||
18 | "net_admin", "net_raw", "ipc_lock", "ipc_owner", "sys_module", \ | ||
19 | "sys_rawio", "sys_chroot", "sys_ptrace", "sys_pacct", "sys_admin", \ | ||
20 | "sys_boot", "sys_nice", "sys_resource", "sys_time", \ | ||
21 | "sys_tty_config", "mknod", "lease", "audit_write", \ | ||
22 | "audit_control", "setfcap" | ||
23 | |||
24 | #define COMMON_CAP2_PERMS "mac_override", "mac_admin", "syslog", \ | ||
25 | "wake_alarm", "block_suspend", "audit_read" | ||
26 | |||
15 | /* | 27 | /* |
16 | * Note: The name for any socket class should be suffixed by "socket", | 28 | * Note: The name for any socket class should be suffixed by "socket", |
17 | * and doesn't contain more than one substr of "socket". | 29 | * and doesn't contain more than one substr of "socket". |
@@ -32,16 +44,9 @@ struct security_class_mapping secclass_map[] = { | |||
32 | "setsockcreate", NULL } }, | 44 | "setsockcreate", NULL } }, |
33 | { "system", | 45 | { "system", |
34 | { "ipc_info", "syslog_read", "syslog_mod", | 46 | { "ipc_info", "syslog_read", "syslog_mod", |
35 | "syslog_console", "module_request", NULL } }, | 47 | "syslog_console", "module_request", "module_load", NULL } }, |
36 | { "capability", | 48 | { "capability", |
37 | { "chown", "dac_override", "dac_read_search", | 49 | { COMMON_CAP_PERMS, NULL } }, |
38 | "fowner", "fsetid", "kill", "setgid", "setuid", "setpcap", | ||
39 | "linux_immutable", "net_bind_service", "net_broadcast", | ||
40 | "net_admin", "net_raw", "ipc_lock", "ipc_owner", "sys_module", | ||
41 | "sys_rawio", "sys_chroot", "sys_ptrace", "sys_pacct", "sys_admin", | ||
42 | "sys_boot", "sys_nice", "sys_resource", "sys_time", | ||
43 | "sys_tty_config", "mknod", "lease", "audit_write", | ||
44 | "audit_control", "setfcap", NULL } }, | ||
45 | { "filesystem", | 50 | { "filesystem", |
46 | { "mount", "remount", "unmount", "getattr", | 51 | { "mount", "remount", "unmount", "getattr", |
47 | "relabelfrom", "relabelto", "associate", "quotamod", | 52 | "relabelfrom", "relabelto", "associate", "quotamod", |
@@ -150,12 +155,15 @@ struct security_class_mapping secclass_map[] = { | |||
150 | { "memprotect", { "mmap_zero", NULL } }, | 155 | { "memprotect", { "mmap_zero", NULL } }, |
151 | { "peer", { "recv", NULL } }, | 156 | { "peer", { "recv", NULL } }, |
152 | { "capability2", | 157 | { "capability2", |
153 | { "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend", | 158 | { COMMON_CAP2_PERMS, NULL } }, |
154 | "audit_read", NULL } }, | ||
155 | { "kernel_service", { "use_as_override", "create_files_as", NULL } }, | 159 | { "kernel_service", { "use_as_override", "create_files_as", NULL } }, |
156 | { "tun_socket", | 160 | { "tun_socket", |
157 | { COMMON_SOCK_PERMS, "attach_queue", NULL } }, | 161 | { COMMON_SOCK_PERMS, "attach_queue", NULL } }, |
158 | { "binder", { "impersonate", "call", "set_context_mgr", "transfer", | 162 | { "binder", { "impersonate", "call", "set_context_mgr", "transfer", |
159 | NULL } }, | 163 | NULL } }, |
164 | { "cap_userns", | ||
165 | { COMMON_CAP_PERMS, NULL } }, | ||
166 | { "cap2_userns", | ||
167 | { COMMON_CAP2_PERMS, NULL } }, | ||
160 | { NULL } | 168 | { NULL } |
161 | }; | 169 | }; |
diff --git a/security/selinux/include/conditional.h b/security/selinux/include/conditional.h index 67ce7a8d8301..ff4fddca9050 100644 --- a/security/selinux/include/conditional.h +++ b/security/selinux/include/conditional.h | |||
@@ -17,6 +17,6 @@ int security_get_bools(int *len, char ***names, int **values); | |||
17 | 17 | ||
18 | int security_set_bools(int len, int *values); | 18 | int security_set_bools(int len, int *values); |
19 | 19 | ||
20 | int security_get_bool_value(int bool); | 20 | int security_get_bool_value(int index); |
21 | 21 | ||
22 | #endif | 22 | #endif |
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index a2ae05414ba1..c21e135460a5 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h | |||
@@ -38,9 +38,8 @@ struct task_security_struct { | |||
38 | }; | 38 | }; |
39 | 39 | ||
40 | enum label_initialized { | 40 | enum label_initialized { |
41 | LABEL_MISSING, /* not initialized */ | 41 | LABEL_INVALID, /* invalid or not initialized */ |
42 | LABEL_INITIALIZED, /* inizialized */ | 42 | LABEL_INITIALIZED /* initialized */ |
43 | LABEL_INVALID /* invalid */ | ||
44 | }; | 43 | }; |
45 | 44 | ||
46 | struct inode_security_struct { | 45 | struct inode_security_struct { |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index ebda97333f1b..89df64672b89 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -2696,7 +2696,7 @@ out: | |||
2696 | return rc; | 2696 | return rc; |
2697 | } | 2697 | } |
2698 | 2698 | ||
2699 | int security_get_bool_value(int bool) | 2699 | int security_get_bool_value(int index) |
2700 | { | 2700 | { |
2701 | int rc; | 2701 | int rc; |
2702 | int len; | 2702 | int len; |
@@ -2705,10 +2705,10 @@ int security_get_bool_value(int bool) | |||
2705 | 2705 | ||
2706 | rc = -EFAULT; | 2706 | rc = -EFAULT; |
2707 | len = policydb.p_bools.nprim; | 2707 | len = policydb.p_bools.nprim; |
2708 | if (bool >= len) | 2708 | if (index >= len) |
2709 | goto out; | 2709 | goto out; |
2710 | 2710 | ||
2711 | rc = policydb.bool_val_to_struct[bool]->state; | 2711 | rc = policydb.bool_val_to_struct[index]->state; |
2712 | out: | 2712 | out: |
2713 | read_unlock(&policy_rwlock); | 2713 | read_unlock(&policy_rwlock); |
2714 | return rc; | 2714 | return rc; |