diff options
| author | James Morris <james.l.morris@oracle.com> | 2015-10-21 20:17:50 -0400 |
|---|---|---|
| committer | James Morris <james.l.morris@oracle.com> | 2015-10-21 20:17:50 -0400 |
| commit | a47c7a6c8aff0563c0ef4adf299268f3c27af0f6 (patch) | |
| tree | 0b9233d8daac506b094307683fe27edba0a1f00d /security | |
| parent | 083c1290ca73666ce1b551cc89d080d060f02ad6 (diff) | |
| parent | 63205654c0e05e5ffa1c6eef2fbef21dcabd2185 (diff) | |
Merge branch 'upstream' of git://git.infradead.org/users/pcmoore/selinux into next
Diffstat (limited to 'security')
| -rw-r--r-- | security/selinux/Kconfig | 4 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 27 | ||||
| -rw-r--r-- | security/selinux/include/security.h | 2 | ||||
| -rw-r--r-- | security/selinux/selinuxfs.c | 26 | ||||
| -rw-r--r-- | security/selinux/ss/services.c | 22 |
5 files changed, 36 insertions, 45 deletions
diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig index bca1b74a4a2f..8691e92f27e5 100644 --- a/security/selinux/Kconfig +++ b/security/selinux/Kconfig | |||
| @@ -78,7 +78,7 @@ config SECURITY_SELINUX_CHECKREQPROT_VALUE | |||
| 78 | int "NSA SELinux checkreqprot default value" | 78 | int "NSA SELinux checkreqprot default value" |
| 79 | depends on SECURITY_SELINUX | 79 | depends on SECURITY_SELINUX |
| 80 | range 0 1 | 80 | range 0 1 |
| 81 | default 1 | 81 | default 0 |
| 82 | help | 82 | help |
| 83 | This option sets the default value for the 'checkreqprot' flag | 83 | This option sets the default value for the 'checkreqprot' flag |
| 84 | that determines whether SELinux checks the protection requested | 84 | that determines whether SELinux checks the protection requested |
| @@ -92,7 +92,7 @@ config SECURITY_SELINUX_CHECKREQPROT_VALUE | |||
| 92 | 'checkreqprot=' boot parameter. It may also be changed at runtime | 92 | 'checkreqprot=' boot parameter. It may also be changed at runtime |
| 93 | via /selinux/checkreqprot if authorized by policy. | 93 | via /selinux/checkreqprot if authorized by policy. |
| 94 | 94 | ||
| 95 | If you are unsure how to answer this question, answer 1. | 95 | If you are unsure how to answer this question, answer 0. |
| 96 | 96 | ||
| 97 | config SECURITY_SELINUX_POLICYDB_VERSION_MAX | 97 | config SECURITY_SELINUX_POLICYDB_VERSION_MAX |
| 98 | bool "NSA SELinux maximum supported policy format version" | 98 | bool "NSA SELinux maximum supported policy format version" |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index e4369d86e588..305399225010 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -126,6 +126,7 @@ int selinux_enabled = 1; | |||
| 126 | #endif | 126 | #endif |
| 127 | 127 | ||
| 128 | static struct kmem_cache *sel_inode_cache; | 128 | static struct kmem_cache *sel_inode_cache; |
| 129 | static struct kmem_cache *file_security_cache; | ||
| 129 | 130 | ||
| 130 | /** | 131 | /** |
| 131 | * selinux_secmark_enabled - Check to see if SECMARK is currently enabled | 132 | * selinux_secmark_enabled - Check to see if SECMARK is currently enabled |
| @@ -287,7 +288,7 @@ static int file_alloc_security(struct file *file) | |||
| 287 | struct file_security_struct *fsec; | 288 | struct file_security_struct *fsec; |
| 288 | u32 sid = current_sid(); | 289 | u32 sid = current_sid(); |
| 289 | 290 | ||
| 290 | fsec = kzalloc(sizeof(struct file_security_struct), GFP_KERNEL); | 291 | fsec = kmem_cache_zalloc(file_security_cache, GFP_KERNEL); |
| 291 | if (!fsec) | 292 | if (!fsec) |
| 292 | return -ENOMEM; | 293 | return -ENOMEM; |
| 293 | 294 | ||
| @@ -302,7 +303,7 @@ static void file_free_security(struct file *file) | |||
| 302 | { | 303 | { |
| 303 | struct file_security_struct *fsec = file->f_security; | 304 | struct file_security_struct *fsec = file->f_security; |
| 304 | file->f_security = NULL; | 305 | file->f_security = NULL; |
| 305 | kfree(fsec); | 306 | kmem_cache_free(file_security_cache, fsec); |
| 306 | } | 307 | } |
| 307 | 308 | ||
| 308 | static int superblock_alloc_security(struct super_block *sb) | 309 | static int superblock_alloc_security(struct super_block *sb) |
| @@ -674,10 +675,9 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
| 674 | 675 | ||
| 675 | if (flags[i] == SBLABEL_MNT) | 676 | if (flags[i] == SBLABEL_MNT) |
| 676 | continue; | 677 | continue; |
| 677 | rc = security_context_to_sid(mount_options[i], | 678 | rc = security_context_str_to_sid(mount_options[i], &sid, GFP_KERNEL); |
| 678 | strlen(mount_options[i]), &sid, GFP_KERNEL); | ||
| 679 | if (rc) { | 679 | if (rc) { |
| 680 | printk(KERN_WARNING "SELinux: security_context_to_sid" | 680 | printk(KERN_WARNING "SELinux: security_context_str_to_sid" |
| 681 | "(%s) failed for (dev %s, type %s) errno=%d\n", | 681 | "(%s) failed for (dev %s, type %s) errno=%d\n", |
| 682 | mount_options[i], sb->s_id, name, rc); | 682 | mount_options[i], sb->s_id, name, rc); |
| 683 | goto out; | 683 | goto out; |
| @@ -2617,15 +2617,12 @@ static int selinux_sb_remount(struct super_block *sb, void *data) | |||
| 2617 | 2617 | ||
| 2618 | for (i = 0; i < opts.num_mnt_opts; i++) { | 2618 | for (i = 0; i < opts.num_mnt_opts; i++) { |
| 2619 | u32 sid; | 2619 | u32 sid; |
| 2620 | size_t len; | ||
| 2621 | 2620 | ||
| 2622 | if (flags[i] == SBLABEL_MNT) | 2621 | if (flags[i] == SBLABEL_MNT) |
| 2623 | continue; | 2622 | continue; |
| 2624 | len = strlen(mount_options[i]); | 2623 | rc = security_context_str_to_sid(mount_options[i], &sid, GFP_KERNEL); |
| 2625 | rc = security_context_to_sid(mount_options[i], len, &sid, | ||
| 2626 | GFP_KERNEL); | ||
| 2627 | if (rc) { | 2624 | if (rc) { |
| 2628 | printk(KERN_WARNING "SELinux: security_context_to_sid" | 2625 | printk(KERN_WARNING "SELinux: security_context_str_to_sid" |
| 2629 | "(%s) failed for (dev %s, type %s) errno=%d\n", | 2626 | "(%s) failed for (dev %s, type %s) errno=%d\n", |
| 2630 | mount_options[i], sb->s_id, sb->s_type->name, rc); | 2627 | mount_options[i], sb->s_id, sb->s_type->name, rc); |
| 2631 | goto out_free_opts; | 2628 | goto out_free_opts; |
| @@ -2946,7 +2943,8 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) | |||
| 2946 | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) | 2943 | ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) |
| 2947 | return dentry_has_perm(cred, dentry, FILE__SETATTR); | 2944 | return dentry_has_perm(cred, dentry, FILE__SETATTR); |
| 2948 | 2945 | ||
| 2949 | if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE)) | 2946 | if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE) |
| 2947 | && !(ia_valid & ATTR_FILE)) | ||
| 2950 | av |= FILE__OPEN; | 2948 | av |= FILE__OPEN; |
| 2951 | 2949 | ||
| 2952 | return dentry_has_perm(cred, dentry, av); | 2950 | return dentry_has_perm(cred, dentry, av); |
| @@ -3166,7 +3164,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, | |||
| 3166 | if (!value || !size) | 3164 | if (!value || !size) |
| 3167 | return -EACCES; | 3165 | return -EACCES; |
| 3168 | 3166 | ||
| 3169 | rc = security_context_to_sid((void *)value, size, &newsid, GFP_KERNEL); | 3167 | rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL); |
| 3170 | if (rc) | 3168 | if (rc) |
| 3171 | return rc; | 3169 | return rc; |
| 3172 | 3170 | ||
| @@ -3238,7 +3236,7 @@ static void selinux_file_free_security(struct file *file) | |||
| 3238 | * Check whether a task has the ioctl permission and cmd | 3236 | * Check whether a task has the ioctl permission and cmd |
| 3239 | * operation to an inode. | 3237 | * operation to an inode. |
| 3240 | */ | 3238 | */ |
| 3241 | int ioctl_has_perm(const struct cred *cred, struct file *file, | 3239 | static int ioctl_has_perm(const struct cred *cred, struct file *file, |
| 3242 | u32 requested, u16 cmd) | 3240 | u32 requested, u16 cmd) |
| 3243 | { | 3241 | { |
| 3244 | struct common_audit_data ad; | 3242 | struct common_audit_data ad; |
| @@ -6089,6 +6087,9 @@ static __init int selinux_init(void) | |||
| 6089 | sel_inode_cache = kmem_cache_create("selinux_inode_security", | 6087 | sel_inode_cache = kmem_cache_create("selinux_inode_security", |
| 6090 | sizeof(struct inode_security_struct), | 6088 | sizeof(struct inode_security_struct), |
| 6091 | 0, SLAB_PANIC, NULL); | 6089 | 0, SLAB_PANIC, NULL); |
| 6090 | file_security_cache = kmem_cache_create("selinux_file_security", | ||
| 6091 | sizeof(struct file_security_struct), | ||
| 6092 | 0, SLAB_PANIC, NULL); | ||
| 6092 | avc_init(); | 6093 | avc_init(); |
| 6093 | 6094 | ||
| 6094 | security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks)); | 6095 | security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks)); |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 6a681d26bf20..223e9fd15d66 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
| @@ -166,6 +166,8 @@ int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len); | |||
| 166 | int security_context_to_sid(const char *scontext, u32 scontext_len, | 166 | int security_context_to_sid(const char *scontext, u32 scontext_len, |
| 167 | u32 *out_sid, gfp_t gfp); | 167 | u32 *out_sid, gfp_t gfp); |
| 168 | 168 | ||
| 169 | int security_context_str_to_sid(const char *scontext, u32 *out_sid, gfp_t gfp); | ||
| 170 | |||
| 169 | int security_context_to_sid_default(const char *scontext, u32 scontext_len, | 171 | int security_context_to_sid_default(const char *scontext, u32 scontext_len, |
| 170 | u32 *out_sid, u32 def_sid, gfp_t gfp_flags); | 172 | u32 *out_sid, u32 def_sid, gfp_t gfp_flags); |
| 171 | 173 | ||
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 5bed7716f8ab..c02da25d7b63 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
| @@ -731,13 +731,11 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size) | |||
| 731 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) | 731 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) |
| 732 | goto out; | 732 | goto out; |
| 733 | 733 | ||
| 734 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, | 734 | length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL); |
| 735 | GFP_KERNEL); | ||
| 736 | if (length) | 735 | if (length) |
| 737 | goto out; | 736 | goto out; |
| 738 | 737 | ||
| 739 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, | 738 | length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL); |
| 740 | GFP_KERNEL); | ||
| 741 | if (length) | 739 | if (length) |
| 742 | goto out; | 740 | goto out; |
| 743 | 741 | ||
| @@ -819,13 +817,11 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) | |||
| 819 | objname = namebuf; | 817 | objname = namebuf; |
| 820 | } | 818 | } |
| 821 | 819 | ||
| 822 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, | 820 | length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL); |
| 823 | GFP_KERNEL); | ||
| 824 | if (length) | 821 | if (length) |
| 825 | goto out; | 822 | goto out; |
| 826 | 823 | ||
| 827 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, | 824 | length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL); |
| 828 | GFP_KERNEL); | ||
| 829 | if (length) | 825 | if (length) |
| 830 | goto out; | 826 | goto out; |
| 831 | 827 | ||
| @@ -882,13 +878,11 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size) | |||
| 882 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) | 878 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) |
| 883 | goto out; | 879 | goto out; |
| 884 | 880 | ||
| 885 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, | 881 | length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL); |
| 886 | GFP_KERNEL); | ||
| 887 | if (length) | 882 | if (length) |
| 888 | goto out; | 883 | goto out; |
| 889 | 884 | ||
| 890 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, | 885 | length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL); |
| 891 | GFP_KERNEL); | ||
| 892 | if (length) | 886 | if (length) |
| 893 | goto out; | 887 | goto out; |
| 894 | 888 | ||
| @@ -940,7 +934,7 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size) | |||
| 940 | if (sscanf(buf, "%s %s", con, user) != 2) | 934 | if (sscanf(buf, "%s %s", con, user) != 2) |
| 941 | goto out; | 935 | goto out; |
| 942 | 936 | ||
| 943 | length = security_context_to_sid(con, strlen(con) + 1, &sid, GFP_KERNEL); | 937 | length = security_context_str_to_sid(con, &sid, GFP_KERNEL); |
| 944 | if (length) | 938 | if (length) |
| 945 | goto out; | 939 | goto out; |
| 946 | 940 | ||
| @@ -1000,13 +994,11 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size) | |||
| 1000 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) | 994 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) |
| 1001 | goto out; | 995 | goto out; |
| 1002 | 996 | ||
| 1003 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, | 997 | length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL); |
| 1004 | GFP_KERNEL); | ||
| 1005 | if (length) | 998 | if (length) |
| 1006 | goto out; | 999 | goto out; |
| 1007 | 1000 | ||
| 1008 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, | 1001 | length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL); |
| 1009 | GFP_KERNEL); | ||
| 1010 | if (length) | 1002 | if (length) |
| 1011 | goto out; | 1003 | goto out; |
| 1012 | 1004 | ||
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index b7df12ba61d8..ebb5eb3c318c 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
| @@ -1218,13 +1218,10 @@ static int context_struct_to_string(struct context *context, char **scontext, u3 | |||
| 1218 | /* | 1218 | /* |
| 1219 | * Copy the user name, role name and type name into the context. | 1219 | * Copy the user name, role name and type name into the context. |
| 1220 | */ | 1220 | */ |
| 1221 | sprintf(scontextp, "%s:%s:%s", | 1221 | scontextp += sprintf(scontextp, "%s:%s:%s", |
| 1222 | sym_name(&policydb, SYM_USERS, context->user - 1), | 1222 | sym_name(&policydb, SYM_USERS, context->user - 1), |
| 1223 | sym_name(&policydb, SYM_ROLES, context->role - 1), | 1223 | sym_name(&policydb, SYM_ROLES, context->role - 1), |
| 1224 | sym_name(&policydb, SYM_TYPES, context->type - 1)); | 1224 | sym_name(&policydb, SYM_TYPES, context->type - 1)); |
| 1225 | scontextp += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) + | ||
| 1226 | 1 + strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) + | ||
| 1227 | 1 + strlen(sym_name(&policydb, SYM_TYPES, context->type - 1)); | ||
| 1228 | 1225 | ||
| 1229 | mls_sid_to_context(context, &scontextp); | 1226 | mls_sid_to_context(context, &scontextp); |
| 1230 | 1227 | ||
| @@ -1259,12 +1256,12 @@ static int security_sid_to_context_core(u32 sid, char **scontext, | |||
| 1259 | *scontext_len = strlen(initial_sid_to_string[sid]) + 1; | 1256 | *scontext_len = strlen(initial_sid_to_string[sid]) + 1; |
| 1260 | if (!scontext) | 1257 | if (!scontext) |
| 1261 | goto out; | 1258 | goto out; |
| 1262 | scontextp = kmalloc(*scontext_len, GFP_ATOMIC); | 1259 | scontextp = kmemdup(initial_sid_to_string[sid], |
| 1260 | *scontext_len, GFP_ATOMIC); | ||
| 1263 | if (!scontextp) { | 1261 | if (!scontextp) { |
| 1264 | rc = -ENOMEM; | 1262 | rc = -ENOMEM; |
| 1265 | goto out; | 1263 | goto out; |
| 1266 | } | 1264 | } |
| 1267 | strcpy(scontextp, initial_sid_to_string[sid]); | ||
| 1268 | *scontext = scontextp; | 1265 | *scontext = scontextp; |
| 1269 | goto out; | 1266 | goto out; |
| 1270 | } | 1267 | } |
| @@ -1476,6 +1473,11 @@ int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid, | |||
| 1476 | sid, SECSID_NULL, gfp, 0); | 1473 | sid, SECSID_NULL, gfp, 0); |
| 1477 | } | 1474 | } |
| 1478 | 1475 | ||
| 1476 | int security_context_str_to_sid(const char *scontext, u32 *sid, gfp_t gfp) | ||
| 1477 | { | ||
| 1478 | return security_context_to_sid(scontext, strlen(scontext), sid, gfp); | ||
| 1479 | } | ||
| 1480 | |||
| 1479 | /** | 1481 | /** |
| 1480 | * security_context_to_sid_default - Obtain a SID for a given security context, | 1482 | * security_context_to_sid_default - Obtain a SID for a given security context, |
| 1481 | * falling back to specified default if needed. | 1483 | * falling back to specified default if needed. |
| @@ -2604,18 +2606,12 @@ int security_get_bools(int *len, char ***names, int **values) | |||
| 2604 | goto err; | 2606 | goto err; |
| 2605 | 2607 | ||
| 2606 | for (i = 0; i < *len; i++) { | 2608 | for (i = 0; i < *len; i++) { |
| 2607 | size_t name_len; | ||
| 2608 | |||
| 2609 | (*values)[i] = policydb.bool_val_to_struct[i]->state; | 2609 | (*values)[i] = policydb.bool_val_to_struct[i]->state; |
| 2610 | name_len = strlen(sym_name(&policydb, SYM_BOOLS, i)) + 1; | ||
| 2611 | 2610 | ||
| 2612 | rc = -ENOMEM; | 2611 | rc = -ENOMEM; |
| 2613 | (*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); | 2612 | (*names)[i] = kstrdup(sym_name(&policydb, SYM_BOOLS, i), GFP_ATOMIC); |
| 2614 | if (!(*names)[i]) | 2613 | if (!(*names)[i]) |
| 2615 | goto err; | 2614 | goto err; |
| 2616 | |||
| 2617 | strncpy((*names)[i], sym_name(&policydb, SYM_BOOLS, i), name_len); | ||
| 2618 | (*names)[i][name_len - 1] = 0; | ||
| 2619 | } | 2615 | } |
| 2620 | rc = 0; | 2616 | rc = 0; |
| 2621 | out: | 2617 | out: |
