Commit 2ccf4661 authored by James Morris's avatar James Morris

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

parents 32c2e675 615e51fd
...@@ -2,4 +2,3 @@ hostprogs-y := genheaders ...@@ -2,4 +2,3 @@ hostprogs-y := genheaders
HOST_EXTRACFLAGS += -Isecurity/selinux/include HOST_EXTRACFLAGS += -Isecurity/selinux/include
always := $(hostprogs-y) always := $(hostprogs-y)
clean-files := $(hostprogs-y)
...@@ -2,4 +2,4 @@ hostprogs-y := mdp ...@@ -2,4 +2,4 @@ hostprogs-y := mdp
HOST_EXTRACFLAGS += -Isecurity/selinux/include HOST_EXTRACFLAGS += -Isecurity/selinux/include
always := $(hostprogs-y) always := $(hostprogs-y)
clean-files := $(hostprogs-y) policy.* file_contexts clean-files := policy.* file_contexts
...@@ -161,6 +161,17 @@ static int selinux_peerlbl_enabled(void) ...@@ -161,6 +161,17 @@ static int selinux_peerlbl_enabled(void)
return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled()); return (selinux_policycap_alwaysnetwork || netlbl_enabled() || selinux_xfrm_enabled());
} }
static int selinux_netcache_avc_callback(u32 event)
{
if (event == AVC_CALLBACK_RESET) {
sel_netif_flush();
sel_netnode_flush();
sel_netport_flush();
synchronize_net();
}
return 0;
}
/* /*
* initialise the security for the init task * initialise the security for the init task
*/ */
...@@ -6002,6 +6013,9 @@ static __init int selinux_init(void) ...@@ -6002,6 +6013,9 @@ static __init int selinux_init(void)
if (register_security(&selinux_ops)) if (register_security(&selinux_ops))
panic("SELinux: Unable to register with kernel.\n"); panic("SELinux: Unable to register with kernel.\n");
if (avc_add_callback(selinux_netcache_avc_callback, AVC_CALLBACK_RESET))
panic("SELinux: Unable to register AVC netcache callback\n");
if (selinux_enforcing) if (selinux_enforcing)
printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n"); printk(KERN_DEBUG "SELinux: Starting in enforcing mode\n");
else else
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#ifndef _SELINUX_NETIF_H_ #ifndef _SELINUX_NETIF_H_
#define _SELINUX_NETIF_H_ #define _SELINUX_NETIF_H_
void sel_netif_flush(void);
int sel_netif_sid(int ifindex, u32 *sid); int sel_netif_sid(int ifindex, u32 *sid);
#endif /* _SELINUX_NETIF_H_ */ #endif /* _SELINUX_NETIF_H_ */
......
...@@ -27,6 +27,8 @@ ...@@ -27,6 +27,8 @@
#ifndef _SELINUX_NETNODE_H #ifndef _SELINUX_NETNODE_H
#define _SELINUX_NETNODE_H #define _SELINUX_NETNODE_H
void sel_netnode_flush(void);
int sel_netnode_sid(void *addr, u16 family, u32 *sid); int sel_netnode_sid(void *addr, u16 family, u32 *sid);
#endif #endif
...@@ -26,6 +26,8 @@ ...@@ -26,6 +26,8 @@
#ifndef _SELINUX_NETPORT_H #ifndef _SELINUX_NETPORT_H
#define _SELINUX_NETPORT_H #define _SELINUX_NETPORT_H
void sel_netport_flush(void);
int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid); int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid);
#endif #endif
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#ifndef _SELINUX_SECURITY_H_ #ifndef _SELINUX_SECURITY_H_
#define _SELINUX_SECURITY_H_ #define _SELINUX_SECURITY_H_
#include <linux/compiler.h>
#include <linux/dcache.h> #include <linux/dcache.h>
#include <linux/magic.h> #include <linux/magic.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -220,7 +221,7 @@ struct selinux_kernel_status { ...@@ -220,7 +221,7 @@ struct selinux_kernel_status {
/* /*
* The version > 0 supports above members. * The version > 0 supports above members.
*/ */
} __attribute__((packed)); } __packed;
extern void selinux_status_update_setenforce(int enforcing); extern void selinux_status_update_setenforce(int enforcing);
extern void selinux_status_update_policyload(int seqno); extern void selinux_status_update_policyload(int seqno);
......
...@@ -240,7 +240,7 @@ static void sel_netif_kill(int ifindex) ...@@ -240,7 +240,7 @@ static void sel_netif_kill(int ifindex)
* Remove all entries from the network interface table. * Remove all entries from the network interface table.
* *
*/ */
static void sel_netif_flush(void) void sel_netif_flush(void)
{ {
int idx; int idx;
struct sel_netif *netif; struct sel_netif *netif;
...@@ -252,15 +252,6 @@ static void sel_netif_flush(void) ...@@ -252,15 +252,6 @@ static void sel_netif_flush(void)
spin_unlock_bh(&sel_netif_lock); spin_unlock_bh(&sel_netif_lock);
} }
static int sel_netif_avc_callback(u32 event)
{
if (event == AVC_CALLBACK_RESET) {
sel_netif_flush();
synchronize_net();
}
return 0;
}
static int sel_netif_netdev_notifier_handler(struct notifier_block *this, static int sel_netif_netdev_notifier_handler(struct notifier_block *this,
unsigned long event, void *ptr) unsigned long event, void *ptr)
{ {
...@@ -291,10 +282,6 @@ static __init int sel_netif_init(void) ...@@ -291,10 +282,6 @@ static __init int sel_netif_init(void)
register_netdevice_notifier(&sel_netif_netdev_notifier); register_netdevice_notifier(&sel_netif_netdev_notifier);
err = avc_add_callback(sel_netif_avc_callback, AVC_CALLBACK_RESET);
if (err)
panic("avc_add_callback() failed, error %d\n", err);
return err; return err;
} }
......
...@@ -283,7 +283,7 @@ int sel_netnode_sid(void *addr, u16 family, u32 *sid) ...@@ -283,7 +283,7 @@ int sel_netnode_sid(void *addr, u16 family, u32 *sid)
* Remove all entries from the network address table. * Remove all entries from the network address table.
* *
*/ */
static void sel_netnode_flush(void) void sel_netnode_flush(void)
{ {
unsigned int idx; unsigned int idx;
struct sel_netnode *node, *node_tmp; struct sel_netnode *node, *node_tmp;
...@@ -300,15 +300,6 @@ static void sel_netnode_flush(void) ...@@ -300,15 +300,6 @@ static void sel_netnode_flush(void)
spin_unlock_bh(&sel_netnode_lock); spin_unlock_bh(&sel_netnode_lock);
} }
static int sel_netnode_avc_callback(u32 event)
{
if (event == AVC_CALLBACK_RESET) {
sel_netnode_flush();
synchronize_net();
}
return 0;
}
static __init int sel_netnode_init(void) static __init int sel_netnode_init(void)
{ {
int iter; int iter;
...@@ -322,10 +313,6 @@ static __init int sel_netnode_init(void) ...@@ -322,10 +313,6 @@ static __init int sel_netnode_init(void)
sel_netnode_hash[iter].size = 0; sel_netnode_hash[iter].size = 0;
} }
ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET);
if (ret != 0)
panic("avc_add_callback() failed, error %d\n", ret);
return ret; return ret;
} }
......
...@@ -217,7 +217,7 @@ int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid) ...@@ -217,7 +217,7 @@ int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid)
* Remove all entries from the network address table. * Remove all entries from the network address table.
* *
*/ */
static void sel_netport_flush(void) void sel_netport_flush(void)
{ {
unsigned int idx; unsigned int idx;
struct sel_netport *port, *port_tmp; struct sel_netport *port, *port_tmp;
...@@ -234,15 +234,6 @@ static void sel_netport_flush(void) ...@@ -234,15 +234,6 @@ static void sel_netport_flush(void)
spin_unlock_bh(&sel_netport_lock); spin_unlock_bh(&sel_netport_lock);
} }
static int sel_netport_avc_callback(u32 event)
{
if (event == AVC_CALLBACK_RESET) {
sel_netport_flush();
synchronize_net();
}
return 0;
}
static __init int sel_netport_init(void) static __init int sel_netport_init(void)
{ {
int iter; int iter;
...@@ -256,10 +247,6 @@ static __init int sel_netport_init(void) ...@@ -256,10 +247,6 @@ static __init int sel_netport_init(void)
sel_netport_hash[iter].size = 0; sel_netport_hash[iter].size = 0;
} }
ret = avc_add_callback(sel_netport_avc_callback, AVC_CALLBACK_RESET);
if (ret != 0)
panic("avc_add_callback() failed, error %d\n", ret);
return ret; return ret;
} }
......
...@@ -402,19 +402,14 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp) ...@@ -402,19 +402,14 @@ static int cond_read_node(struct policydb *p, struct cond_node *node, void *fp)
int rc; int rc;
struct cond_expr *expr = NULL, *last = NULL; struct cond_expr *expr = NULL, *last = NULL;
rc = next_entry(buf, fp, sizeof(u32)); rc = next_entry(buf, fp, sizeof(u32) * 2);
if (rc) if (rc)
return rc; goto err;
node->cur_state = le32_to_cpu(buf[0]); node->cur_state = le32_to_cpu(buf[0]);
len = 0;
rc = next_entry(buf, fp, sizeof(u32));
if (rc)
return rc;
/* expr */ /* expr */
len = le32_to_cpu(buf[0]); len = le32_to_cpu(buf[1]);
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
rc = next_entry(buf, fp, sizeof(u32) * 2); rc = next_entry(buf, fp, sizeof(u32) * 2);
......
...@@ -1080,6 +1080,26 @@ static int context_read_and_validate(struct context *c, ...@@ -1080,6 +1080,26 @@ static int context_read_and_validate(struct context *c,
* binary representation file. * binary representation file.
*/ */
static int str_read(char **strp, gfp_t flags, void *fp, u32 len)
{
int rc;
char *str;
str = kmalloc(len + 1, flags);
if (!str)
return -ENOMEM;
/* it's expected the caller should free the str */
*strp = str;
rc = next_entry(str, fp, len);
if (rc)
return rc;
str[len] = '\0';
return 0;
}
static int perm_read(struct policydb *p, struct hashtab *h, void *fp) static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
{ {
char *key = NULL; char *key = NULL;
...@@ -1100,15 +1120,9 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1100,15 +1120,9 @@ static int perm_read(struct policydb *p, struct hashtab *h, void *fp)
len = le32_to_cpu(buf[0]); len = le32_to_cpu(buf[0]);
perdatum->value = le32_to_cpu(buf[1]); perdatum->value = le32_to_cpu(buf[1]);
rc = -ENOMEM; rc = str_read(&key, GFP_KERNEL, fp, len);
key = kmalloc(len + 1, GFP_KERNEL);
if (!key)
goto bad;
rc = next_entry(key, fp, len);
if (rc) if (rc)
goto bad; goto bad;
key[len] = '\0';
rc = hashtab_insert(h, key, perdatum); rc = hashtab_insert(h, key, perdatum);
if (rc) if (rc)
...@@ -1146,15 +1160,9 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1146,15 +1160,9 @@ static int common_read(struct policydb *p, struct hashtab *h, void *fp)
comdatum->permissions.nprim = le32_to_cpu(buf[2]); comdatum->permissions.nprim = le32_to_cpu(buf[2]);
nel = le32_to_cpu(buf[3]); nel = le32_to_cpu(buf[3]);
rc = -ENOMEM; rc = str_read(&key, GFP_KERNEL, fp, len);
key = kmalloc(len + 1, GFP_KERNEL);
if (!key)
goto bad;
rc = next_entry(key, fp, len);
if (rc) if (rc)
goto bad; goto bad;
key[len] = '\0';
for (i = 0; i < nel; i++) { for (i = 0; i < nel; i++) {
rc = perm_read(p, comdatum->permissions.table, fp); rc = perm_read(p, comdatum->permissions.table, fp);
...@@ -1321,25 +1329,14 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1321,25 +1329,14 @@ static int class_read(struct policydb *p, struct hashtab *h, void *fp)
ncons = le32_to_cpu(buf[5]); ncons = le32_to_cpu(buf[5]);
rc = -ENOMEM; rc = str_read(&key, GFP_KERNEL, fp, len);
key = kmalloc(len + 1, GFP_KERNEL);
if (!key)
goto bad;
rc = next_entry(key, fp, len);
if (rc) if (rc)
goto bad; goto bad;
key[len] = '\0';
if (len2) { if (len2) {
rc = -ENOMEM; rc = str_read(&cladatum->comkey, GFP_KERNEL, fp, len2);
cladatum->comkey = kmalloc(len2 + 1, GFP_KERNEL);
if (!cladatum->comkey)
goto bad;
rc = next_entry(cladatum->comkey, fp, len2);
if (rc) if (rc)
goto bad; goto bad;
cladatum->comkey[len2] = '\0';
rc = -EINVAL; rc = -EINVAL;
cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey); cladatum->comdatum = hashtab_search(p->p_commons.table, cladatum->comkey);
...@@ -1422,15 +1419,9 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1422,15 +1419,9 @@ static int role_read(struct policydb *p, struct hashtab *h, void *fp)
if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
role->bounds = le32_to_cpu(buf[2]); role->bounds = le32_to_cpu(buf[2]);
rc = -ENOMEM; rc = str_read(&key, GFP_KERNEL, fp, len);
key = kmalloc(len + 1, GFP_KERNEL);
if (!key)
goto bad;
rc = next_entry(key, fp, len);
if (rc) if (rc)
goto bad; goto bad;
key[len] = '\0';
rc = ebitmap_read(&role->dominates, fp); rc = ebitmap_read(&role->dominates, fp);
if (rc) if (rc)
...@@ -1495,14 +1486,9 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1495,14 +1486,9 @@ static int type_read(struct policydb *p, struct hashtab *h, void *fp)
typdatum->primary = le32_to_cpu(buf[2]); typdatum->primary = le32_to_cpu(buf[2]);
} }
rc = -ENOMEM; rc = str_read(&key, GFP_KERNEL, fp, len);
key = kmalloc(len + 1, GFP_KERNEL);
if (!key)
goto bad;
rc = next_entry(key, fp, len);
if (rc) if (rc)
goto bad; goto bad;
key[len] = '\0';
rc = hashtab_insert(h, key, typdatum); rc = hashtab_insert(h, key, typdatum);
if (rc) if (rc)
...@@ -1565,14 +1551,9 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1565,14 +1551,9 @@ static int user_read(struct policydb *p, struct hashtab *h, void *fp)
if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
usrdatum->bounds = le32_to_cpu(buf[2]); usrdatum->bounds = le32_to_cpu(buf[2]);
rc = -ENOMEM; rc = str_read(&key, GFP_KERNEL, fp, len);
key = kmalloc(len + 1, GFP_KERNEL);
if (!key)
goto bad;
rc = next_entry(key, fp, len);
if (rc) if (rc)
goto bad; goto bad;
key[len] = '\0';
rc = ebitmap_read(&usrdatum->roles, fp); rc = ebitmap_read(&usrdatum->roles, fp);
if (rc) if (rc)
...@@ -1616,14 +1597,9 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1616,14 +1597,9 @@ static int sens_read(struct policydb *p, struct hashtab *h, void *fp)
len = le32_to_cpu(buf[0]); len = le32_to_cpu(buf[0]);
levdatum->isalias = le32_to_cpu(buf[1]); levdatum->isalias = le32_to_cpu(buf[1]);
rc = -ENOMEM; rc = str_read(&key, GFP_ATOMIC, fp, len);
key = kmalloc(len + 1, GFP_ATOMIC);
if (!key)
goto bad;
rc = next_entry(key, fp, len);
if (rc) if (rc)
goto bad; goto bad;
key[len] = '\0';
rc = -ENOMEM; rc = -ENOMEM;
levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC); levdatum->level = kmalloc(sizeof(struct mls_level), GFP_ATOMIC);
...@@ -1664,14 +1640,9 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp) ...@@ -1664,14 +1640,9 @@ static int cat_read(struct policydb *p, struct hashtab *h, void *fp)
catdatum->value = le32_to_cpu(buf[1]); catdatum->value = le32_to_cpu(buf[1]);
catdatum->isalias = le32_to_cpu(buf[2]); catdatum->isalias = le32_to_cpu(buf[2]);
rc = -ENOMEM; rc = str_read(&key, GFP_ATOMIC, fp, len);
key = kmalloc(len + 1, GFP_ATOMIC);
if (!key)
goto bad;
rc = next_entry(key, fp, len);
if (rc) if (rc)
goto bad; goto bad;
key[len] = '\0';
rc = hashtab_insert(h, key, catdatum); rc = hashtab_insert(h, key, catdatum);
if (rc) if (rc)
...@@ -1968,18 +1939,12 @@ static int filename_trans_read(struct policydb *p, void *fp) ...@@ -1968,18 +1939,12 @@ static int filename_trans_read(struct policydb *p, void *fp)
goto out; goto out;
len = le32_to_cpu(buf[0]); len = le32_to_cpu(buf[0]);
rc = -ENOMEM;
name = kmalloc(len + 1, GFP_KERNEL);
if (!name)
goto out;
ft->name = name;
/* path component string */ /* path component string */
rc = next_entry(name, fp, len); rc = str_read(&name, GFP_KERNEL, fp, len);
if (rc) if (rc)
goto out; goto out;
name[len] = 0;
ft->name = name;
rc = next_entry(buf, fp, sizeof(u32) * 4); rc = next_entry(buf, fp, sizeof(u32) * 4);
if (rc) if (rc)
...@@ -2045,17 +2010,10 @@ static int genfs_read(struct policydb *p, void *fp) ...@@ -2045,17 +2010,10 @@ static int genfs_read(struct policydb *p, void *fp)
if (!newgenfs) if (!newgenfs)
goto out; goto out;
rc = -ENOMEM; rc = str_read(&newgenfs->fstype, GFP_KERNEL, fp, len);
newgenfs->fstype = kmalloc(len + 1, GFP_KERNEL);
if (!newgenfs->fstype)
goto out;
rc = next_entry(newgenfs->fstype, fp, len);
if (rc) if (rc)
goto out; goto out;
newgenfs->fstype[len] = 0;
for (genfs_p = NULL, genfs = p->genfs; genfs; for (genfs_p = NULL, genfs = p->genfs; genfs;
genfs_p = genfs, genfs = genfs->next) { genfs_p = genfs, genfs = genfs->next) {
rc = -EINVAL; rc = -EINVAL;
...@@ -2091,15 +2049,9 @@ static int genfs_read(struct policydb *p, void *fp) ...@@ -2091,15 +2049,9 @@ static int genfs_read(struct policydb *p, void *fp)
if (!newc) if (!newc)
goto out; goto out;
rc = -ENOMEM; rc = str_read(&newc->u.name, GFP_KERNEL, fp, len);
newc->u.name = kmalloc(len + 1, GFP_KERNEL);
if (!newc->u.name)
goto out;
rc = next_entry(newc->u.name, fp, len);
if (rc) if (rc)
goto out; goto out;
newc->u.name[len] = 0;
rc = next_entry(buf, fp, sizeof(u32)); rc = next_entry(buf, fp, sizeof(u32));
if (rc) if (rc)
...@@ -2189,16 +2141,10 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info, ...@@ -2189,16 +2141,10 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
goto out; goto out;
len = le32_to_cpu(buf[0]); len = le32_to_cpu(buf[0]);
rc = -ENOMEM; rc = str_read(&c->u.name, GFP_KERNEL, fp, len);
c->u.name = kmalloc(len + 1, GFP_KERNEL);
if (!c->u.name)
goto out;
rc = next_entry(c->u.name, fp, len);
if (rc) if (rc)
goto out; goto out;
c->u.name[len] = 0;
rc = context_read_and_validate(&c->context[0], p, fp); rc = context_read_and_validate(&c->context[0], p, fp);
if (rc) if (rc)
goto out; goto out;
...@@ -2240,16 +2186,11 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info, ...@@ -2240,16 +2186,11 @@ static int ocontext_read(struct policydb *p, struct policydb_compat_info *info,
if (c->v.behavior > SECURITY_FS_USE_MAX) if (c->v.behavior > SECURITY_FS_USE_MAX)
goto out; goto out;
rc = -ENOMEM;
len = le32_to_cpu(buf[1]); len = le32_to_cpu(buf[1]);
c->u.name = kmalloc(len + 1, GFP_KERNEL); rc = str_read(&c->u.name, GFP_KERNEL, fp, len);
if (!c->u.name)
goto out;
rc = next_entry(c->u.name, fp, len);
if (rc) if (rc)
goto out; goto out;
c->u.name[len] = 0;
rc = context_read_and_validate(&c->context[0], p, fp); rc = context_read_and_validate(&c->context[0], p, fp);
if (rc) if (rc)
goto out; goto out;
...@@ -2608,7 +2549,7 @@ static int mls_write_range_helper(struct mls_range *r, void *fp) ...@@ -2608,7 +2549,7 @@ static int mls_write_range_helper(struct mls_range *r, void *fp)
if (!eq) if (!eq)
buf[2] = cpu_to_le32(r->level[1].sens); buf[2] = cpu_to_le32(r->level[1].sens);
BUG_ON(items > (sizeof(buf)/sizeof(buf[0]))); BUG_ON(items > ARRAY_SIZE(buf));
rc = put_entry(buf, sizeof(u32), items, fp); rc = put_entry(buf, sizeof(u32), items, fp);
if (rc) if (rc)
...@@ -2990,7 +2931,7 @@ static int role_write(void *vkey, void *datum, void *ptr) ...@@ -2990,7 +2931,7 @@ static int role_write(void *vkey, void *datum, void *ptr)
if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
buf[items++] = cpu_to_le32(role->bounds); buf[items++] = cpu_to_le32(role->bounds);
BUG_ON(items > (sizeof(buf)/sizeof(buf[0]))); BUG_ON(items > ARRAY_SIZE(buf));
rc = put_entry(buf, sizeof(u32), items, fp); rc = put_entry(buf, sizeof(u32), items, fp);
if (rc) if (rc)
...@@ -3040,7 +2981,7 @@ static int type_write(void *vkey, void *datum, void *ptr) ...@@ -3040,7 +2981,7 @@ static int type_write(void *vkey, void *datum, void *ptr)
} else { } else {
buf[items++] = cpu_to_le32(typdatum->primary); buf[items++] = cpu_to_le32(typdatum->primary);
} }
BUG_ON(items > (sizeof(buf) / sizeof(buf[0]))); BUG_ON(items > ARRAY_SIZE(buf));
rc = put_entry(buf, sizeof(u32), items, fp); rc = put_entry(buf, sizeof(u32), items, fp);
if (rc) if (rc)
return rc; return rc;
...@@ -3069,7 +3010,7 @@ static int user_write(void *vkey, void *datum, void *ptr) ...@@ -3069,7 +3010,7 @@ static int user_write(void *vkey, void *datum, void *ptr)
buf[items++] = cpu_to_le32(usrdatum->value); buf[items++] = cpu_to_le32(usrdatum->value);
if (p->policyvers >= POLICYDB_VERSION_BOUNDARY) if (p->policyvers >= POLICYDB_VERSION_BOUNDARY)
buf[items++] = cpu_to_le32(usrdatum->bounds); buf[items++] = cpu_to_le32(usrdatum->bounds);
BUG_ON(items > (sizeof(buf) / sizeof(buf[0]))); BUG_ON(items > ARRAY_SIZE(buf));
rc = put_entry(buf, sizeof(u32), items, fp); rc = put_entry(buf, sizeof(u32), items, fp);
if (rc) if (rc)
return rc; return rc;
......
...@@ -2277,7 +2277,7 @@ int security_get_user_sids(u32 fromsid, ...@@ -2277,7 +2277,7 @@ int security_get_user_sids(u32 fromsid,
} }
/** /**
* security_genfs_sid - Obtain a SID for a file in a filesystem * __security_genfs_sid - Helper to obtain a SID for a file in a filesystem
* @fstype: filesystem type * @fstype: filesystem type
* @path: path from root of mount * @path: path from root of mount
* @sclass: file security class * @sclass: file security class
...@@ -2286,11 +2286,13 @@ int security_get_user_sids(u32 fromsid, ...@@ -2286,11 +2286,13 @@ int security_get_user_sids(u32 fromsid,
* Obtain a SID to use for a file in a filesystem that * Obtain a SID to use for a file in a filesystem that
* cannot support xattr or use a fixed labeling behavior like * cannot support xattr or use a fixed labeling behavior like
* transition SIDs or task SIDs. * transition SIDs or task SIDs.
*
* The caller must acquire the policy_rwlock before calling this function.
*/ */
int security_genfs_sid(const char *fstype, static inline int __security_genfs_sid(const char *fstype,
char *path, char *path,
u16 orig_sclass, u16 orig_sclass,
u32 *sid) u32 *sid)
{ {
int len; int len;
u16 sclass; u16 sclass;
...@@ -2301,8 +2303,6 @@ int security_genfs_sid(const char *fstype, ...@@ -2301,8 +2303,6 @@ int security_genfs_sid(const char *fstype,
while (path[0] == '/' && path[1] == '/') while (path[0] == '/' && path[1] == '/')
path++; path++;
read_lock(&policy_rwlock);
sclass = unmap_class(orig_sclass); sclass = unmap_class(orig_sclass);
*sid = SECINITSID_UNLABELED; *sid = SECINITSID_UNLABELED;
...@@ -2336,10 +2336,32 @@ int security_genfs_sid(const char *fstype, ...@@ -2336,10 +2336,32 @@ int security_genfs_sid(const char *fstype,
*sid = c->sid[0]; *sid = c->sid[0];
rc = 0; rc = 0;
out: out:
read_unlock(&policy_rwlock);
return rc; return rc;
} }
/**
* security_genfs_sid - Obtain a SID for a file in a filesystem
* @fstype: filesystem type
* @path: path from root of mount
* @sclass: file security class
* @sid: SID for path
*
* Acquire policy_rwlock before calling __security_genfs_sid() and release
* it afterward.
*/
int security_genfs_sid(const char *fstype,
char *path,
u16 orig_sclass,
u32 *sid)
{
int retval;
read_lock(&policy_rwlock);
retval = __security_genfs_sid(fstype, path, orig_sclass, sid);
read_unlock(&policy_rwlock);
return retval;
}
/** /**
* security_fs_use - Determine how to handle labeling for a filesystem. * security_fs_use - Determine how to handle labeling for a filesystem.
* @sb: superblock in question * @sb: superblock in question
...@@ -2370,7 +2392,8 @@ int security_fs_use(struct super_block *sb) ...@@ -2370,7 +2392,8 @@ int security_fs_use(struct super_block *sb)
} }
sbsec->sid = c->sid[0]; sbsec->sid = c->sid[0];
} else { } else {
rc = security_genfs_sid(fstype, "/", SECCLASS_DIR, &sbsec->sid); rc = __security_genfs_sid(fstype, "/", SECCLASS_DIR,
&sbsec->sid);
if (rc) { if (rc) {
sbsec->behavior = SECURITY_FS_USE_NONE; sbsec->behavior = SECURITY_FS_USE_NONE;
rc = 0; rc = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment