diff options
Diffstat (limited to 'security/selinux/hooks.c')
| -rw-r--r-- | security/selinux/hooks.c | 63 |
1 files changed, 40 insertions, 23 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b332e2cc0954..b4beb77967b1 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -106,7 +106,7 @@ int selinux_enforcing; | |||
| 106 | static int __init enforcing_setup(char *str) | 106 | static int __init enforcing_setup(char *str) |
| 107 | { | 107 | { |
| 108 | unsigned long enforcing; | 108 | unsigned long enforcing; |
| 109 | if (!strict_strtoul(str, 0, &enforcing)) | 109 | if (!kstrtoul(str, 0, &enforcing)) |
| 110 | selinux_enforcing = enforcing ? 1 : 0; | 110 | selinux_enforcing = enforcing ? 1 : 0; |
| 111 | return 1; | 111 | return 1; |
| 112 | } | 112 | } |
| @@ -119,7 +119,7 @@ int selinux_enabled = CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE; | |||
| 119 | static int __init selinux_enabled_setup(char *str) | 119 | static int __init selinux_enabled_setup(char *str) |
| 120 | { | 120 | { |
| 121 | unsigned long enabled; | 121 | unsigned long enabled; |
| 122 | if (!strict_strtoul(str, 0, &enabled)) | 122 | if (!kstrtoul(str, 0, &enabled)) |
| 123 | selinux_enabled = enabled ? 1 : 0; | 123 | selinux_enabled = enabled ? 1 : 0; |
| 124 | return 1; | 124 | return 1; |
| 125 | } | 125 | } |
| @@ -1418,15 +1418,33 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
| 1418 | isec->sid = sbsec->sid; | 1418 | isec->sid = sbsec->sid; |
| 1419 | 1419 | ||
| 1420 | if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) { | 1420 | if ((sbsec->flags & SE_SBPROC) && !S_ISLNK(inode->i_mode)) { |
| 1421 | if (opt_dentry) { | 1421 | /* We must have a dentry to determine the label on |
| 1422 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | 1422 | * procfs inodes */ |
| 1423 | rc = selinux_proc_get_sid(opt_dentry, | 1423 | if (opt_dentry) |
| 1424 | isec->sclass, | 1424 | /* Called from d_instantiate or |
| 1425 | &sid); | 1425 | * d_splice_alias. */ |
| 1426 | if (rc) | 1426 | dentry = dget(opt_dentry); |
| 1427 | goto out_unlock; | 1427 | else |
| 1428 | isec->sid = sid; | 1428 | /* Called from selinux_complete_init, try to |
| 1429 | } | 1429 | * find a dentry. */ |
| 1430 | dentry = d_find_alias(inode); | ||
| 1431 | /* | ||
| 1432 | * This can be hit on boot when a file is accessed | ||
| 1433 | * before the policy is loaded. When we load policy we | ||
| 1434 | * may find inodes that have no dentry on the | ||
| 1435 | * sbsec->isec_head list. No reason to complain as | ||
| 1436 | * these will get fixed up the next time we go through | ||
| 1437 | * inode_doinit() with a dentry, before these inodes | ||
| 1438 | * could be used again by userspace. | ||
| 1439 | */ | ||
| 1440 | if (!dentry) | ||
| 1441 | goto out_unlock; | ||
| 1442 | isec->sclass = inode_mode_to_security_class(inode->i_mode); | ||
| 1443 | rc = selinux_proc_get_sid(dentry, isec->sclass, &sid); | ||
| 1444 | dput(dentry); | ||
| 1445 | if (rc) | ||
| 1446 | goto out_unlock; | ||
| 1447 | isec->sid = sid; | ||
| 1430 | } | 1448 | } |
| 1431 | break; | 1449 | break; |
| 1432 | } | 1450 | } |
| @@ -3205,24 +3223,20 @@ error: | |||
| 3205 | 3223 | ||
| 3206 | static int selinux_mmap_addr(unsigned long addr) | 3224 | static int selinux_mmap_addr(unsigned long addr) |
| 3207 | { | 3225 | { |
| 3208 | int rc = 0; | 3226 | int rc; |
| 3209 | u32 sid = current_sid(); | 3227 | |
| 3228 | /* do DAC check on address space usage */ | ||
| 3229 | rc = cap_mmap_addr(addr); | ||
| 3230 | if (rc) | ||
| 3231 | return rc; | ||
| 3210 | 3232 | ||
| 3211 | /* | ||
| 3212 | * notice that we are intentionally putting the SELinux check before | ||
| 3213 | * the secondary cap_file_mmap check. This is such a likely attempt | ||
| 3214 | * at bad behaviour/exploit that we always want to get the AVC, even | ||
| 3215 | * if DAC would have also denied the operation. | ||
| 3216 | */ | ||
| 3217 | if (addr < CONFIG_LSM_MMAP_MIN_ADDR) { | 3233 | if (addr < CONFIG_LSM_MMAP_MIN_ADDR) { |
| 3234 | u32 sid = current_sid(); | ||
| 3218 | rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT, | 3235 | rc = avc_has_perm(sid, sid, SECCLASS_MEMPROTECT, |
| 3219 | MEMPROTECT__MMAP_ZERO, NULL); | 3236 | MEMPROTECT__MMAP_ZERO, NULL); |
| 3220 | if (rc) | ||
| 3221 | return rc; | ||
| 3222 | } | 3237 | } |
| 3223 | 3238 | ||
| 3224 | /* do DAC check on address space usage */ | 3239 | return rc; |
| 3225 | return cap_mmap_addr(addr); | ||
| 3226 | } | 3240 | } |
| 3227 | 3241 | ||
| 3228 | static int selinux_mmap_file(struct file *file, unsigned long reqprot, | 3242 | static int selinux_mmap_file(struct file *file, unsigned long reqprot, |
| @@ -3303,6 +3317,9 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd, | |||
| 3303 | case F_GETLK: | 3317 | case F_GETLK: |
| 3304 | case F_SETLK: | 3318 | case F_SETLK: |
| 3305 | case F_SETLKW: | 3319 | case F_SETLKW: |
| 3320 | case F_GETLKP: | ||
| 3321 | case F_SETLKP: | ||
| 3322 | case F_SETLKPW: | ||
| 3306 | #if BITS_PER_LONG == 32 | 3323 | #if BITS_PER_LONG == 32 |
| 3307 | case F_GETLK64: | 3324 | case F_GETLK64: |
| 3308 | case F_SETLK64: | 3325 | case F_SETLK64: |
