diff options
-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: |