hooks.c (e290861f99131fc42d98012a9ea2dc185f08f8f9) hooks.c (25354c4fee169710fd9da15f3bb2abaa24dcf933)
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
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 }
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 }
1295 kfree(context);
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
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
1858static int selinux_ptrace_may_access(struct task_struct *child,
1857static int selinux_ptrace_access_check(struct task_struct *child,
1859 unsigned int mode)
1860{
1861 int rc;
1862
1858 unsigned int mode)
1859{
1860 int rc;
1861
1863 rc = cap_ptrace_may_access(child, mode);
1862 rc = cap_ptrace_access_check(child, mode);
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
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
2942 if (!mask) {
2943 /* No permission to check. Existence test. */
2944 return 0;
2945 }
2946
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{
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{
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
2957 if (!mask)
2958 /* No permission to check. Existence test. */
2959 return 0;
2960
2956 if (!mask)
2957 /* No permission to check. Existence test. */
2958 return 0;
2959
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
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
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
3033 if (addr < mmap_min_addr)
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) {
3034 rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
3035 MEMPROTECT__MMAP_ZERO, NULL);
3044 rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT,
3045 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);
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);

--- 231 unchanged lines hidden (view full) ---

3275 KERNEL_SERVICE__CREATE_FILES_AS,
3276 NULL);
3277
3278 if (ret == 0)
3279 tsec->create_sid = isec->sid;
3280 return 0;
3281}
3282
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);

--- 231 unchanged lines hidden (view full) ---

3291 KERNEL_SERVICE__CREATE_FILES_AS,
3292 NULL);
3293
3294 if (ret == 0)
3295 tsec->create_sid = isec->sid;
3296 return 0;
3297}
3298
3299static int selinux_kernel_module_request(void)
3300{
3301 return task_has_system(current, SYSTEM__MODULE_REQUEST);
3302}
3303
3283static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
3284{
3285 return current_has_perm(p, PROCESS__SETPGID);
3286}
3287
3288static int selinux_task_getpgid(struct task_struct *p)
3289{
3290 return current_has_perm(p, PROCESS__GETPGID);

--- 1887 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;
3304static int selinux_task_setpgid(struct task_struct *p, pid_t pgid)
3305{
3306 return current_has_perm(p, PROCESS__SETPGID);
3307}
3308
3309static int selinux_task_getpgid(struct task_struct *p)
3310{
3311 return current_has_perm(p, PROCESS__GETPGID);

--- 1887 unchanged lines hidden (view full) ---

5199 tsec->sockcreate_sid = sid;
5200 } else if (!strcmp(name, "current")) {
5201 error = -EINVAL;
5202 if (sid == 0)
5203 goto abort_change;
5204
5205 /* Only allow single threaded processes to change context */
5206 error = -EPERM;
5186 if (!is_single_threaded(p)) {
5207 if (!current_is_single_threaded()) {
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
5208 error = security_bounded_transition(tsec->sid, sid);
5209 if (error)
5210 goto abort_change;
5211 }
5212
5213 /* Check permissions for the transition. */
5214 error = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,
5215 PROCESS__DYNTRANSITION, NULL);

--- 111 unchanged lines hidden (view full) ---

5327 return rc;
5328}
5329
5330#endif
5331
5332static struct security_operations selinux_ops = {
5333 .name = "selinux",
5334
5314 .ptrace_may_access = selinux_ptrace_may_access,
5335 .ptrace_access_check = selinux_ptrace_access_check,
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,

--- 60 unchanged lines hidden (view full) ---

5383
5384 .dentry_open = selinux_dentry_open,
5385
5386 .task_create = selinux_task_create,
5387 .cred_free = selinux_cred_free,
5388 .cred_prepare = selinux_cred_prepare,
5389 .kernel_act_as = selinux_kernel_act_as,
5390 .kernel_create_files_as = selinux_kernel_create_files_as,
5336 .ptrace_traceme = selinux_ptrace_traceme,
5337 .capget = selinux_capget,
5338 .capset = selinux_capset,
5339 .sysctl = selinux_sysctl,
5340 .capable = selinux_capable,
5341 .quotactl = selinux_quotactl,
5342 .quota_on = selinux_quota_on,
5343 .syslog = selinux_syslog,

--- 60 unchanged lines hidden (view full) ---

5404
5405 .dentry_open = selinux_dentry_open,
5406
5407 .task_create = selinux_task_create,
5408 .cred_free = selinux_cred_free,
5409 .cred_prepare = selinux_cred_prepare,
5410 .kernel_act_as = selinux_kernel_act_as,
5411 .kernel_create_files_as = selinux_kernel_create_files_as,
5412 .kernel_module_request = selinux_kernel_module_request,
5391 .task_setpgid = selinux_task_setpgid,
5392 .task_getpgid = selinux_task_getpgid,
5393 .task_getsid = selinux_task_getsid,
5394 .task_getsecid = selinux_task_getsecid,
5395 .task_setnice = selinux_task_setnice,
5396 .task_setioprio = selinux_task_setioprio,
5397 .task_getioprio = selinux_task_getioprio,
5398 .task_setrlimit = selinux_task_setrlimit,

--- 275 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
5413 .task_setpgid = selinux_task_setpgid,
5414 .task_getpgid = selinux_task_getpgid,
5415 .task_getsid = selinux_task_getsid,
5416 .task_getsecid = selinux_task_getsecid,
5417 .task_setnice = selinux_task_setnice,
5418 .task_setioprio = selinux_task_setioprio,
5419 .task_getioprio = selinux_task_getioprio,
5420 .task_setrlimit = selinux_task_setrlimit,

--- 275 unchanged lines hidden (view full) ---

5696 return -EINVAL;
5697 }
5698
5699 printk(KERN_INFO "SELinux: Disabled at runtime.\n");
5700
5701 selinux_disabled = 1;
5702 selinux_enabled = 0;
5703
5704 /* Try to destroy the avc node cache */
5705 avc_disable();
5706
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
5707 /* Reset security_ops to the secondary module, dummy or capability. */
5708 security_ops = secondary_ops;
5709
5710 /* Unregister netfilter hooks. */
5711 selinux_nf_ip_exit();
5712
5713 /* Unregister selinuxfs. */
5714 exit_sel_fs();
5715
5716 return 0;
5717}
5718#endif