Merge branch 'upstream' of git://git.infradead.org/users/pcmoore/selinux into next

This commit is contained in:
James Morris 2015-10-22 11:17:50 +11:00
commit a47c7a6c8a
5 changed files with 36 additions and 45 deletions

View File

@ -78,7 +78,7 @@ config SECURITY_SELINUX_CHECKREQPROT_VALUE
int "NSA SELinux checkreqprot default value" int "NSA SELinux checkreqprot default value"
depends on SECURITY_SELINUX depends on SECURITY_SELINUX
range 0 1 range 0 1
default 1 default 0
help help
This option sets the default value for the 'checkreqprot' flag This option sets the default value for the 'checkreqprot' flag
that determines whether SELinux checks the protection requested that determines whether SELinux checks the protection requested
@ -92,7 +92,7 @@ config SECURITY_SELINUX_CHECKREQPROT_VALUE
'checkreqprot=' boot parameter. It may also be changed at runtime 'checkreqprot=' boot parameter. It may also be changed at runtime
via /selinux/checkreqprot if authorized by policy. via /selinux/checkreqprot if authorized by policy.
If you are unsure how to answer this question, answer 1. If you are unsure how to answer this question, answer 0.
config SECURITY_SELINUX_POLICYDB_VERSION_MAX config SECURITY_SELINUX_POLICYDB_VERSION_MAX
bool "NSA SELinux maximum supported policy format version" bool "NSA SELinux maximum supported policy format version"

View File

@ -126,6 +126,7 @@ int selinux_enabled = 1;
#endif #endif
static struct kmem_cache *sel_inode_cache; static struct kmem_cache *sel_inode_cache;
static struct kmem_cache *file_security_cache;
/** /**
* selinux_secmark_enabled - Check to see if SECMARK is currently enabled * selinux_secmark_enabled - Check to see if SECMARK is currently enabled
@ -287,7 +288,7 @@ static int file_alloc_security(struct file *file)
struct file_security_struct *fsec; struct file_security_struct *fsec;
u32 sid = current_sid(); u32 sid = current_sid();
fsec = kzalloc(sizeof(struct file_security_struct), GFP_KERNEL); fsec = kmem_cache_zalloc(file_security_cache, GFP_KERNEL);
if (!fsec) if (!fsec)
return -ENOMEM; return -ENOMEM;
@ -302,7 +303,7 @@ static void file_free_security(struct file *file)
{ {
struct file_security_struct *fsec = file->f_security; struct file_security_struct *fsec = file->f_security;
file->f_security = NULL; file->f_security = NULL;
kfree(fsec); kmem_cache_free(file_security_cache, fsec);
} }
static int superblock_alloc_security(struct super_block *sb) static int superblock_alloc_security(struct super_block *sb)
@ -674,10 +675,9 @@ static int selinux_set_mnt_opts(struct super_block *sb,
if (flags[i] == SBLABEL_MNT) if (flags[i] == SBLABEL_MNT)
continue; continue;
rc = security_context_to_sid(mount_options[i], rc = security_context_str_to_sid(mount_options[i], &sid, GFP_KERNEL);
strlen(mount_options[i]), &sid, GFP_KERNEL);
if (rc) { if (rc) {
printk(KERN_WARNING "SELinux: security_context_to_sid" printk(KERN_WARNING "SELinux: security_context_str_to_sid"
"(%s) failed for (dev %s, type %s) errno=%d\n", "(%s) failed for (dev %s, type %s) errno=%d\n",
mount_options[i], sb->s_id, name, rc); mount_options[i], sb->s_id, name, rc);
goto out; goto out;
@ -2617,15 +2617,12 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
for (i = 0; i < opts.num_mnt_opts; i++) { for (i = 0; i < opts.num_mnt_opts; i++) {
u32 sid; u32 sid;
size_t len;
if (flags[i] == SBLABEL_MNT) if (flags[i] == SBLABEL_MNT)
continue; continue;
len = strlen(mount_options[i]); rc = security_context_str_to_sid(mount_options[i], &sid, GFP_KERNEL);
rc = security_context_to_sid(mount_options[i], len, &sid,
GFP_KERNEL);
if (rc) { if (rc) {
printk(KERN_WARNING "SELinux: security_context_to_sid" printk(KERN_WARNING "SELinux: security_context_str_to_sid"
"(%s) failed for (dev %s, type %s) errno=%d\n", "(%s) failed for (dev %s, type %s) errno=%d\n",
mount_options[i], sb->s_id, sb->s_type->name, rc); mount_options[i], sb->s_id, sb->s_type->name, rc);
goto out_free_opts; goto out_free_opts;
@ -2946,7 +2943,8 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr)
ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET)) ATTR_ATIME_SET | ATTR_MTIME_SET | ATTR_TIMES_SET))
return dentry_has_perm(cred, dentry, FILE__SETATTR); return dentry_has_perm(cred, dentry, FILE__SETATTR);
if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE)) if (selinux_policycap_openperm && (ia_valid & ATTR_SIZE)
&& !(ia_valid & ATTR_FILE))
av |= FILE__OPEN; av |= FILE__OPEN;
return dentry_has_perm(cred, dentry, av); return dentry_has_perm(cred, dentry, av);
@ -3166,7 +3164,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name,
if (!value || !size) if (!value || !size)
return -EACCES; return -EACCES;
rc = security_context_to_sid((void *)value, size, &newsid, GFP_KERNEL); rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL);
if (rc) if (rc)
return rc; return rc;
@ -3238,7 +3236,7 @@ static void selinux_file_free_security(struct file *file)
* Check whether a task has the ioctl permission and cmd * Check whether a task has the ioctl permission and cmd
* operation to an inode. * operation to an inode.
*/ */
int ioctl_has_perm(const struct cred *cred, struct file *file, static int ioctl_has_perm(const struct cred *cred, struct file *file,
u32 requested, u16 cmd) u32 requested, u16 cmd)
{ {
struct common_audit_data ad; struct common_audit_data ad;
@ -6089,6 +6087,9 @@ static __init int selinux_init(void)
sel_inode_cache = kmem_cache_create("selinux_inode_security", sel_inode_cache = kmem_cache_create("selinux_inode_security",
sizeof(struct inode_security_struct), sizeof(struct inode_security_struct),
0, SLAB_PANIC, NULL); 0, SLAB_PANIC, NULL);
file_security_cache = kmem_cache_create("selinux_file_security",
sizeof(struct file_security_struct),
0, SLAB_PANIC, NULL);
avc_init(); avc_init();
security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks)); security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks));

View File

@ -166,6 +166,8 @@ int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len);
int security_context_to_sid(const char *scontext, u32 scontext_len, int security_context_to_sid(const char *scontext, u32 scontext_len,
u32 *out_sid, gfp_t gfp); u32 *out_sid, gfp_t gfp);
int security_context_str_to_sid(const char *scontext, u32 *out_sid, gfp_t gfp);
int security_context_to_sid_default(const char *scontext, u32 scontext_len, int security_context_to_sid_default(const char *scontext, u32 scontext_len,
u32 *out_sid, u32 def_sid, gfp_t gfp_flags); u32 *out_sid, u32 def_sid, gfp_t gfp_flags);

View File

@ -731,13 +731,11 @@ static ssize_t sel_write_access(struct file *file, char *buf, size_t size)
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
goto out; goto out;
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
GFP_KERNEL);
if (length) if (length)
goto out; goto out;
length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
GFP_KERNEL);
if (length) if (length)
goto out; goto out;
@ -819,13 +817,11 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size)
objname = namebuf; objname = namebuf;
} }
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
GFP_KERNEL);
if (length) if (length)
goto out; goto out;
length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
GFP_KERNEL);
if (length) if (length)
goto out; goto out;
@ -882,13 +878,11 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size)
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
goto out; goto out;
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
GFP_KERNEL);
if (length) if (length)
goto out; goto out;
length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
GFP_KERNEL);
if (length) if (length)
goto out; goto out;
@ -940,7 +934,7 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size)
if (sscanf(buf, "%s %s", con, user) != 2) if (sscanf(buf, "%s %s", con, user) != 2)
goto out; goto out;
length = security_context_to_sid(con, strlen(con) + 1, &sid, GFP_KERNEL); length = security_context_str_to_sid(con, &sid, GFP_KERNEL);
if (length) if (length)
goto out; goto out;
@ -1000,13 +994,11 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size)
if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3)
goto out; goto out;
length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, length = security_context_str_to_sid(scon, &ssid, GFP_KERNEL);
GFP_KERNEL);
if (length) if (length)
goto out; goto out;
length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, length = security_context_str_to_sid(tcon, &tsid, GFP_KERNEL);
GFP_KERNEL);
if (length) if (length)
goto out; goto out;

View File

@ -1218,13 +1218,10 @@ static int context_struct_to_string(struct context *context, char **scontext, u3
/* /*
* Copy the user name, role name and type name into the context. * Copy the user name, role name and type name into the context.
*/ */
sprintf(scontextp, "%s:%s:%s", scontextp += sprintf(scontextp, "%s:%s:%s",
sym_name(&policydb, SYM_USERS, context->user - 1), sym_name(&policydb, SYM_USERS, context->user - 1),
sym_name(&policydb, SYM_ROLES, context->role - 1), sym_name(&policydb, SYM_ROLES, context->role - 1),
sym_name(&policydb, SYM_TYPES, context->type - 1)); sym_name(&policydb, SYM_TYPES, context->type - 1));
scontextp += strlen(sym_name(&policydb, SYM_USERS, context->user - 1)) +
1 + strlen(sym_name(&policydb, SYM_ROLES, context->role - 1)) +
1 + strlen(sym_name(&policydb, SYM_TYPES, context->type - 1));
mls_sid_to_context(context, &scontextp); mls_sid_to_context(context, &scontextp);
@ -1259,12 +1256,12 @@ static int security_sid_to_context_core(u32 sid, char **scontext,
*scontext_len = strlen(initial_sid_to_string[sid]) + 1; *scontext_len = strlen(initial_sid_to_string[sid]) + 1;
if (!scontext) if (!scontext)
goto out; goto out;
scontextp = kmalloc(*scontext_len, GFP_ATOMIC); scontextp = kmemdup(initial_sid_to_string[sid],
*scontext_len, GFP_ATOMIC);
if (!scontextp) { if (!scontextp) {
rc = -ENOMEM; rc = -ENOMEM;
goto out; goto out;
} }
strcpy(scontextp, initial_sid_to_string[sid]);
*scontext = scontextp; *scontext = scontextp;
goto out; goto out;
} }
@ -1476,6 +1473,11 @@ int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid,
sid, SECSID_NULL, gfp, 0); sid, SECSID_NULL, gfp, 0);
} }
int security_context_str_to_sid(const char *scontext, u32 *sid, gfp_t gfp)
{
return security_context_to_sid(scontext, strlen(scontext), sid, gfp);
}
/** /**
* security_context_to_sid_default - Obtain a SID for a given security context, * security_context_to_sid_default - Obtain a SID for a given security context,
* falling back to specified default if needed. * falling back to specified default if needed.
@ -2604,18 +2606,12 @@ int security_get_bools(int *len, char ***names, int **values)
goto err; goto err;
for (i = 0; i < *len; i++) { for (i = 0; i < *len; i++) {
size_t name_len;
(*values)[i] = policydb.bool_val_to_struct[i]->state; (*values)[i] = policydb.bool_val_to_struct[i]->state;
name_len = strlen(sym_name(&policydb, SYM_BOOLS, i)) + 1;
rc = -ENOMEM; rc = -ENOMEM;
(*names)[i] = kmalloc(sizeof(char) * name_len, GFP_ATOMIC); (*names)[i] = kstrdup(sym_name(&policydb, SYM_BOOLS, i), GFP_ATOMIC);
if (!(*names)[i]) if (!(*names)[i])
goto err; goto err;
strncpy((*names)[i], sym_name(&policydb, SYM_BOOLS, i), name_len);
(*names)[i][name_len - 1] = 0;
} }
rc = 0; rc = 0;
out: out: