hooks.c (a2551df7ec568d87793d2eea4ca744e86318f205) | hooks.c (314dabb83a547ec4da819e8cbc78fac9cec605cd) |
---|---|
1/* 2 * NSA Security-Enhanced Linux (SELinux) security module 3 * 4 * This file contains the SELinux hook function implementations. 5 * 6 * Authors: Stephen Smalley, <sds@epoch.ncsc.mil> 7 * Chris Vance, <cvance@nai.com> 8 * Wayne Salamon, <wsalamon@nai.com> --- 1271 unchanged lines hidden (view full) --- 1280 rc = -ENOMEM; 1281 dput(dentry); 1282 goto out_unlock; 1283 } 1284 context[len] = '\0'; 1285 rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, 1286 context, len); 1287 if (rc == -ERANGE) { | 1/* 2 * NSA Security-Enhanced Linux (SELinux) security module 3 * 4 * This file contains the SELinux hook function implementations. 5 * 6 * Authors: Stephen Smalley, <sds@epoch.ncsc.mil> 7 * Chris Vance, <cvance@nai.com> 8 * Wayne Salamon, <wsalamon@nai.com> --- 1271 unchanged lines hidden (view full) --- 1280 rc = -ENOMEM; 1281 dput(dentry); 1282 goto out_unlock; 1283 } 1284 context[len] = '\0'; 1285 rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, 1286 context, len); 1287 if (rc == -ERANGE) { |
1288 kfree(context); 1289 |
|
1288 /* Need a larger buffer. Query for the right size. */ 1289 rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, 1290 NULL, 0); 1291 if (rc < 0) { 1292 dput(dentry); 1293 goto out_unlock; 1294 } | 1290 /* Need a larger buffer. Query for the right size. */ 1291 rc = inode->i_op->getxattr(dentry, XATTR_NAME_SELINUX, 1292 NULL, 0); 1293 if (rc < 0) { 1294 dput(dentry); 1295 goto out_unlock; 1296 } |
1295 kfree(context); | |
1296 len = rc; 1297 context = kmalloc(len+1, GFP_NOFS); 1298 if (!context) { 1299 rc = -ENOMEM; 1300 dput(dentry); 1301 goto out_unlock; 1302 } 1303 context[len] = '\0'; --- 545 unchanged lines hidden (view full) --- 1849 printk(KERN_ERR "SELinux: WARNING: inside %s with " 1850 "unknown mode:%o\n", __func__, mode); 1851 } 1852 return av; 1853} 1854 1855/* Hook functions begin here. */ 1856 | 1297 len = rc; 1298 context = kmalloc(len+1, GFP_NOFS); 1299 if (!context) { 1300 rc = -ENOMEM; 1301 dput(dentry); 1302 goto out_unlock; 1303 } 1304 context[len] = '\0'; --- 545 unchanged lines hidden (view full) --- 1850 printk(KERN_ERR "SELinux: WARNING: inside %s with " 1851 "unknown mode:%o\n", __func__, mode); 1852 } 1853 return av; 1854} 1855 1856/* Hook functions begin here. */ 1857 |
1857static int selinux_ptrace_access_check(struct task_struct *child, | 1858static int selinux_ptrace_may_access(struct task_struct *child, |
1858 unsigned int mode) 1859{ 1860 int rc; 1861 | 1859 unsigned int mode) 1860{ 1861 int rc; 1862 |
1862 rc = cap_ptrace_access_check(child, mode); | 1863 rc = cap_ptrace_may_access(child, mode); |
1863 if (rc) 1864 return rc; 1865 1866 if (mode == PTRACE_MODE_READ) { 1867 u32 sid = current_sid(); 1868 u32 csid = task_sid(child); 1869 return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ, NULL); 1870 } --- 1062 unchanged lines hidden (view full) --- 2933 2934/* file security operations */ 2935 2936static int selinux_revalidate_file_permission(struct file *file, int mask) 2937{ 2938 const struct cred *cred = current_cred(); 2939 struct inode *inode = file->f_path.dentry->d_inode; 2940 | 1864 if (rc) 1865 return rc; 1866 1867 if (mode == PTRACE_MODE_READ) { 1868 u32 sid = current_sid(); 1869 u32 csid = task_sid(child); 1870 return avc_has_perm(sid, csid, SECCLASS_FILE, FILE__READ, NULL); 1871 } --- 1062 unchanged lines hidden (view full) --- 2934 2935/* file security operations */ 2936 2937static int selinux_revalidate_file_permission(struct file *file, int mask) 2938{ 2939 const struct cred *cred = current_cred(); 2940 struct inode *inode = file->f_path.dentry->d_inode; 2941 |
2942 if (!mask) { 2943 /* No permission to check. Existence test. */ 2944 return 0; 2945 } 2946 |
|
2941 /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */ 2942 if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) 2943 mask |= MAY_APPEND; 2944 2945 return file_has_perm(cred, file, 2946 file_mask_to_av(inode->i_mode, mask)); 2947} 2948 2949static int selinux_file_permission(struct file *file, int mask) 2950{ | 2947 /* file_mask_to_av won't add FILE__WRITE if MAY_APPEND is set */ 2948 if ((file->f_flags & O_APPEND) && (mask & MAY_WRITE)) 2949 mask |= MAY_APPEND; 2950 2951 return file_has_perm(cred, file, 2952 file_mask_to_av(inode->i_mode, mask)); 2953} 2954 2955static int selinux_file_permission(struct file *file, int mask) 2956{ |
2951 struct inode *inode = file->f_path.dentry->d_inode; 2952 struct file_security_struct *fsec = file->f_security; 2953 struct inode_security_struct *isec = inode->i_security; 2954 u32 sid = current_sid(); 2955 | |
2956 if (!mask) 2957 /* No permission to check. Existence test. */ 2958 return 0; 2959 | 2957 if (!mask) 2958 /* No permission to check. Existence test. */ 2959 return 0; 2960 |
2960 if (sid == fsec->sid && fsec->isid == isec->sid && 2961 fsec->pseqno == avc_policy_seqno()) 2962 /* No change since dentry_open check. */ 2963 return 0; 2964 | |
2965 return selinux_revalidate_file_permission(file, mask); 2966} 2967 2968static int selinux_file_alloc_security(struct file *file) 2969{ 2970 return file_alloc_security(file); 2971} 2972 --- 56 unchanged lines hidden (view full) --- 3029 3030static int selinux_file_mmap(struct file *file, unsigned long reqprot, 3031 unsigned long prot, unsigned long flags, 3032 unsigned long addr, unsigned long addr_only) 3033{ 3034 int rc = 0; 3035 u32 sid = current_sid(); 3036 | 2961 return selinux_revalidate_file_permission(file, mask); 2962} 2963 2964static int selinux_file_alloc_security(struct file *file) 2965{ 2966 return file_alloc_security(file); 2967} 2968 --- 56 unchanged lines hidden (view full) --- 3025 3026static int selinux_file_mmap(struct file *file, unsigned long reqprot, 3027 unsigned long prot, unsigned long flags, 3028 unsigned long addr, unsigned long addr_only) 3029{ 3030 int rc = 0; 3031 u32 sid = current_sid(); 3032 |
3037 /* 3038 * notice that we are intentionally putting the SELinux check before 3039 * the secondary cap_file_mmap check. This is such a likely attempt 3040 * at bad behaviour/exploit that we always want to get the AVC, even 3041 * if DAC would have also denied the operation. 3042 */ 3043 if (addr < CONFIG_LSM_MMAP_MIN_ADDR) { | 3033 if (addr < mmap_min_addr) |
3044 rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT, 3045 MEMPROTECT__MMAP_ZERO, NULL); | 3034 rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT, 3035 MEMPROTECT__MMAP_ZERO, NULL); |
3046 if (rc) 3047 return rc; 3048 } 3049 3050 /* do DAC check on address space usage */ 3051 rc = cap_file_mmap(file, reqprot, prot, flags, addr, addr_only); | |
3052 if (rc || addr_only) 3053 return rc; 3054 3055 if (selinux_checkreqprot) 3056 prot = reqprot; 3057 3058 return file_map_prot_check(file, prot, 3059 (flags & MAP_TYPE) == MAP_SHARED); --- 2134 unchanged lines hidden (view full) --- 5194 tsec->sockcreate_sid = sid; 5195 } else if (!strcmp(name, "current")) { 5196 error = -EINVAL; 5197 if (sid == 0) 5198 goto abort_change; 5199 5200 /* Only allow single threaded processes to change context */ 5201 error = -EPERM; | 3036 if (rc || addr_only) 3037 return rc; 3038 3039 if (selinux_checkreqprot) 3040 prot = reqprot; 3041 3042 return file_map_prot_check(file, prot, 3043 (flags & MAP_TYPE) == MAP_SHARED); --- 2134 unchanged lines hidden (view full) --- 5178 tsec->sockcreate_sid = sid; 5179 } else if (!strcmp(name, "current")) { 5180 error = -EINVAL; 5181 if (sid == 0) 5182 goto abort_change; 5183 5184 /* Only allow single threaded processes to change context */ 5185 error = -EPERM; |
5202 if (!current_is_single_threaded()) { | 5186 if (!is_single_threaded(p)) { |
5203 error = security_bounded_transition(tsec->sid, sid); 5204 if (error) 5205 goto abort_change; 5206 } 5207 5208 /* Check permissions for the transition. */ 5209 error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS, 5210 PROCESS__DYNTRANSITION, NULL); --- 111 unchanged lines hidden (view full) --- 5322 return rc; 5323} 5324 5325#endif 5326 5327static struct security_operations selinux_ops = { 5328 .name = "selinux", 5329 | 5187 error = security_bounded_transition(tsec->sid, sid); 5188 if (error) 5189 goto abort_change; 5190 } 5191 5192 /* Check permissions for the transition. */ 5193 error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS, 5194 PROCESS__DYNTRANSITION, NULL); --- 111 unchanged lines hidden (view full) --- 5306 return rc; 5307} 5308 5309#endif 5310 5311static struct security_operations selinux_ops = { 5312 .name = "selinux", 5313 |
5330 .ptrace_access_check = selinux_ptrace_access_check, | 5314 .ptrace_may_access = selinux_ptrace_may_access, |
5331 .ptrace_traceme = selinux_ptrace_traceme, 5332 .capget = selinux_capget, 5333 .capset = selinux_capset, 5334 .sysctl = selinux_sysctl, 5335 .capable = selinux_capable, 5336 .quotactl = selinux_quotactl, 5337 .quota_on = selinux_quota_on, 5338 .syslog = selinux_syslog, --- 351 unchanged lines hidden (view full) --- 5690 return -EINVAL; 5691 } 5692 5693 printk(KERN_INFO "SELinux: Disabled at runtime.\n"); 5694 5695 selinux_disabled = 1; 5696 selinux_enabled = 0; 5697 | 5315 .ptrace_traceme = selinux_ptrace_traceme, 5316 .capget = selinux_capget, 5317 .capset = selinux_capset, 5318 .sysctl = selinux_sysctl, 5319 .capable = selinux_capable, 5320 .quotactl = selinux_quotactl, 5321 .quota_on = selinux_quota_on, 5322 .syslog = selinux_syslog, --- 351 unchanged lines hidden (view full) --- 5674 return -EINVAL; 5675 } 5676 5677 printk(KERN_INFO "SELinux: Disabled at runtime.\n"); 5678 5679 selinux_disabled = 1; 5680 selinux_enabled = 0; 5681 |
5698 /* Try to destroy the avc node cache */ 5699 avc_disable(); 5700 | |
5701 /* Reset security_ops to the secondary module, dummy or capability. */ 5702 security_ops = secondary_ops; 5703 5704 /* Unregister netfilter hooks. */ 5705 selinux_nf_ip_exit(); 5706 5707 /* Unregister selinuxfs. */ 5708 exit_sel_fs(); 5709 5710 return 0; 5711} 5712#endif | 5682 /* Reset security_ops to the secondary module, dummy or capability. */ 5683 security_ops = secondary_ops; 5684 5685 /* Unregister netfilter hooks. */ 5686 selinux_nf_ip_exit(); 5687 5688 /* Unregister selinuxfs. */ 5689 exit_sel_fs(); 5690 5691 return 0; 5692} 5693#endif |