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