diff options
Diffstat (limited to 'security')
-rw-r--r-- | security/selinux/include/avc_ss.h | 9 | ||||
-rw-r--r-- | security/selinux/include/netlabel.h | 2 | ||||
-rw-r--r-- | security/selinux/include/objsec.h | 60 | ||||
-rw-r--r-- | security/selinux/include/security.h | 4 | ||||
-rw-r--r-- | security/selinux/netnode.c | 104 | ||||
-rw-r--r-- | security/selinux/netport.c | 40 | ||||
-rw-r--r-- | security/selinux/ss/conditional.h | 6 | ||||
-rw-r--r-- | security/selinux/ss/context.h | 4 | ||||
-rw-r--r-- | security/selinux/ss/hashtab.h | 6 | ||||
-rw-r--r-- | security/selinux/ss/mls.h | 6 | ||||
-rw-r--r-- | security/selinux/ss/mls_types.h | 4 | ||||
-rw-r--r-- | security/selinux/ss/policydb.h | 10 |
12 files changed, 121 insertions, 134 deletions
diff --git a/security/selinux/include/avc_ss.h b/security/selinux/include/avc_ss.h index ff869e8b6f4a..c0d314d9f8e1 100644 --- a/security/selinux/include/avc_ss.h +++ b/security/selinux/include/avc_ss.h @@ -10,22 +10,19 @@ int avc_ss_reset(u32 seqno); -struct av_perm_to_string -{ +struct av_perm_to_string { u16 tclass; u32 value; const char *name; }; -struct av_inherit -{ +struct av_inherit { u16 tclass; const char **common_pts; u32 common_base; }; -struct selinux_class_perm -{ +struct selinux_class_perm { const struct av_perm_to_string *av_perm_to_string; u32 av_pts_len; const char **class_to_string; diff --git a/security/selinux/include/netlabel.h b/security/selinux/include/netlabel.h index 9a9e7cd9a379..487a7d81fe20 100644 --- a/security/selinux/include/netlabel.h +++ b/security/selinux/include/netlabel.h @@ -64,7 +64,7 @@ static inline void selinux_netlbl_cache_invalidate(void) } static inline void selinux_netlbl_sk_security_reset( - struct sk_security_struct *ssec, + struct sk_security_struct *ssec, int family) { return; diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 300b61bad7b3..032c2357dad1 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -4,16 +4,16 @@ * This file contains the SELinux security data structures for kernel objects. * * Author(s): Stephen Smalley, <sds@epoch.ncsc.mil> - * Chris Vance, <cvance@nai.com> - * Wayne Salamon, <wsalamon@nai.com> - * James Morris <jmorris@redhat.com> + * Chris Vance, <cvance@nai.com> + * Wayne Salamon, <wsalamon@nai.com> + * James Morris <jmorris@redhat.com> * * Copyright (C) 2001,2002 Networks Associates Technology, Inc. * Copyright (C) 2003 Red Hat, Inc., James Morris <jmorris@redhat.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2, - * as published by the Free Software Foundation. + * as published by the Free Software Foundation. */ #ifndef _SELINUX_OBJSEC_H_ #define _SELINUX_OBJSEC_H_ @@ -28,58 +28,58 @@ #include "avc.h" struct task_security_struct { - u32 osid; /* SID prior to last execve */ - u32 sid; /* current SID */ - u32 exec_sid; /* exec SID */ - u32 create_sid; /* fscreate SID */ - u32 keycreate_sid; /* keycreate SID */ - u32 sockcreate_sid; /* fscreate SID */ + u32 osid; /* SID prior to last execve */ + u32 sid; /* current SID */ + u32 exec_sid; /* exec SID */ + u32 create_sid; /* fscreate SID */ + u32 keycreate_sid; /* keycreate SID */ + u32 sockcreate_sid; /* fscreate SID */ }; struct inode_security_struct { - struct inode *inode; /* back pointer to inode object */ - struct list_head list; /* list of inode_security_struct */ - u32 task_sid; /* SID of creating task */ - u32 sid; /* SID of this object */ - u16 sclass; /* security class of this object */ - unsigned char initialized; /* initialization flag */ + struct inode *inode; /* back pointer to inode object */ + struct list_head list; /* list of inode_security_struct */ + u32 task_sid; /* SID of creating task */ + u32 sid; /* SID of this object */ + u16 sclass; /* security class of this object */ + unsigned char initialized; /* initialization flag */ struct mutex lock; - unsigned char inherit; /* inherit SID from parent entry */ + unsigned char inherit; /* inherit SID from parent entry */ }; struct file_security_struct { - u32 sid; /* SID of open file description */ - u32 fown_sid; /* SID of file owner (for SIGIO) */ - u32 isid; /* SID of inode at the time of file open */ - u32 pseqno; /* Policy seqno at the time of file open */ + u32 sid; /* SID of open file description */ + u32 fown_sid; /* SID of file owner (for SIGIO) */ + u32 isid; /* SID of inode at the time of file open */ + u32 pseqno; /* Policy seqno at the time of file open */ }; struct superblock_security_struct { - struct super_block *sb; /* back pointer to sb object */ - struct list_head list; /* list of superblock_security_struct */ + struct super_block *sb; /* back pointer to sb object */ + struct list_head list; /* list of superblock_security_struct */ u32 sid; /* SID of file system superblock */ u32 def_sid; /* default SID for labeling */ u32 mntpoint_sid; /* SECURITY_FS_USE_MNTPOINT context for files */ - unsigned int behavior; /* labeling behavior */ - unsigned char initialized; /* initialization flag */ + unsigned int behavior; /* labeling behavior */ + unsigned char initialized; /* initialization flag */ unsigned char flags; /* which mount options were specified */ - unsigned char proc; /* proc fs */ + unsigned char proc; /* proc fs */ struct mutex lock; struct list_head isec_head; spinlock_t isec_lock; }; struct msg_security_struct { - u32 sid; /* SID of message */ + u32 sid; /* SID of message */ }; struct ipc_security_struct { u16 sclass; /* security class of this object */ - u32 sid; /* SID of IPC resource */ + u32 sid; /* SID of IPC resource */ }; struct bprm_security_struct { - u32 sid; /* SID for transformed process */ + u32 sid; /* SID for transformed process */ unsigned char set; /* @@ -123,7 +123,7 @@ struct sk_security_struct { }; struct key_security_struct { - u32 sid; /* SID of key */ + u32 sid; /* SID of key */ }; extern unsigned int selinux_checkreqprot; diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 1904c462a605..6445b6440648 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h @@ -62,7 +62,7 @@ enum { extern int selinux_policycap_netpeer; extern int selinux_policycap_openperm; -int security_load_policy(void * data, size_t len); +int security_load_policy(void *data, size_t len); int security_policycap_supported(unsigned int req_cap); @@ -110,7 +110,7 @@ int security_node_sid(u16 domain, void *addr, u32 addrlen, u32 *out_sid); int security_validate_transition(u32 oldsid, u32 newsid, u32 tasksid, - u16 tclass); + u16 tclass); int security_sid_mls_copy(u32 sid, u32 mls_sid, u32 *new_sid); diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c index 2edc4c5e0c61..b6ccd09379f1 100644 --- a/security/selinux/netnode.c +++ b/security/selinux/netnode.c @@ -40,11 +40,17 @@ #include <net/ipv6.h> #include <asm/bug.h> +#include "netnode.h" #include "objsec.h" #define SEL_NETNODE_HASH_SIZE 256 #define SEL_NETNODE_HASH_BKT_LIMIT 16 +struct sel_netnode_bkt { + unsigned int size; + struct list_head list; +}; + struct sel_netnode { struct netnode_security_struct nsec; @@ -60,7 +66,7 @@ struct sel_netnode { static LIST_HEAD(sel_netnode_list); static DEFINE_SPINLOCK(sel_netnode_lock); -static struct list_head sel_netnode_hash[SEL_NETNODE_HASH_SIZE]; +static struct sel_netnode_bkt sel_netnode_hash[SEL_NETNODE_HASH_SIZE]; /** * sel_netnode_free - Frees a node entry @@ -87,7 +93,7 @@ static void sel_netnode_free(struct rcu_head *p) * the bucket number for the given IP address. * */ -static u32 sel_netnode_hashfn_ipv4(__be32 addr) +static unsigned int sel_netnode_hashfn_ipv4(__be32 addr) { /* at some point we should determine if the mismatch in byte order * affects the hash function dramatically */ @@ -103,7 +109,7 @@ static u32 sel_netnode_hashfn_ipv4(__be32 addr) * the bucket number for the given IP address. * */ -static u32 sel_netnode_hashfn_ipv6(const struct in6_addr *addr) +static unsigned int sel_netnode_hashfn_ipv6(const struct in6_addr *addr) { /* just hash the least significant 32 bits to keep things fast (they * are the most likely to be different anyway), we can revisit this @@ -123,7 +129,7 @@ static u32 sel_netnode_hashfn_ipv6(const struct in6_addr *addr) */ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family) { - u32 idx; + unsigned int idx; struct sel_netnode *node; switch (family) { @@ -137,7 +143,7 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family) BUG(); } - list_for_each_entry_rcu(node, &sel_netnode_hash[idx], list) + list_for_each_entry_rcu(node, &sel_netnode_hash[idx].list, list) if (node->nsec.family == family) switch (family) { case PF_INET: @@ -159,15 +165,12 @@ static struct sel_netnode *sel_netnode_find(const void *addr, u16 family) * @node: the new node record * * Description: - * Add a new node record to the network address hash table. Returns zero on - * success, negative values on failure. + * Add a new node record to the network address hash table. * */ -static int sel_netnode_insert(struct sel_netnode *node) +static void sel_netnode_insert(struct sel_netnode *node) { - u32 idx; - u32 count = 0; - struct sel_netnode *iter; + unsigned int idx; switch (node->nsec.family) { case PF_INET: @@ -179,32 +182,21 @@ static int sel_netnode_insert(struct sel_netnode *node) default: BUG(); } - list_add_rcu(&node->list, &sel_netnode_hash[idx]); + + INIT_RCU_HEAD(&node->rcu); /* we need to impose a limit on the growth of the hash table so check * this bucket to make sure it is within the specified bounds */ - list_for_each_entry(iter, &sel_netnode_hash[idx], list) - if (++count > SEL_NETNODE_HASH_BKT_LIMIT) { - list_del_rcu(&iter->list); - call_rcu(&iter->rcu, sel_netnode_free); - break; - } - - return 0; -} - -/** - * sel_netnode_destroy - Remove a node record from the table - * @node: the existing node record - * - * Description: - * Remove an existing node record from the network address table. - * - */ -static void sel_netnode_destroy(struct sel_netnode *node) -{ - list_del_rcu(&node->list); - call_rcu(&node->rcu, sel_netnode_free); + list_add_rcu(&node->list, &sel_netnode_hash[idx].list); + if (sel_netnode_hash[idx].size == SEL_NETNODE_HASH_BKT_LIMIT) { + struct sel_netnode *tail; + tail = list_entry( + rcu_dereference(sel_netnode_hash[idx].list.prev), + struct sel_netnode, list); + list_del_rcu(&tail->list); + call_rcu(&tail->rcu, sel_netnode_free); + } else + sel_netnode_hash[idx].size++; } /** @@ -222,7 +214,7 @@ static void sel_netnode_destroy(struct sel_netnode *node) */ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) { - int ret; + int ret = -ENOMEM; struct sel_netnode *node; struct sel_netnode *new = NULL; @@ -230,25 +222,21 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) node = sel_netnode_find(addr, family); if (node != NULL) { *sid = node->nsec.sid; - ret = 0; - goto out; + spin_unlock_bh(&sel_netnode_lock); + return 0; } new = kzalloc(sizeof(*new), GFP_ATOMIC); - if (new == NULL) { - ret = -ENOMEM; + if (new == NULL) goto out; - } switch (family) { case PF_INET: ret = security_node_sid(PF_INET, - addr, sizeof(struct in_addr), - &new->nsec.sid); + addr, sizeof(struct in_addr), sid); new->nsec.addr.ipv4 = *(__be32 *)addr; break; case PF_INET6: ret = security_node_sid(PF_INET6, - addr, sizeof(struct in6_addr), - &new->nsec.sid); + addr, sizeof(struct in6_addr), sid); ipv6_addr_copy(&new->nsec.addr.ipv6, addr); break; default: @@ -256,11 +244,10 @@ static int sel_netnode_sid_slow(void *addr, u16 family, u32 *sid) } if (ret != 0) goto out; + new->nsec.family = family; - ret = sel_netnode_insert(new); - if (ret != 0) - goto out; - *sid = new->nsec.sid; + new->nsec.sid = *sid; + sel_netnode_insert(new); out: spin_unlock_bh(&sel_netnode_lock); @@ -312,13 +299,18 @@ int sel_netnode_sid(void *addr, u16 family, u32 *sid) */ static void sel_netnode_flush(void) { - u32 idx; - struct sel_netnode *node; + unsigned int idx; + struct sel_netnode *node, *node_tmp; spin_lock_bh(&sel_netnode_lock); - for (idx = 0; idx < SEL_NETNODE_HASH_SIZE; idx++) - list_for_each_entry(node, &sel_netnode_hash[idx], list) - sel_netnode_destroy(node); + for (idx = 0; idx < SEL_NETNODE_HASH_SIZE; idx++) { + list_for_each_entry_safe(node, node_tmp, + &sel_netnode_hash[idx].list, list) { + list_del_rcu(&node->list); + call_rcu(&node->rcu, sel_netnode_free); + } + sel_netnode_hash[idx].size = 0; + } spin_unlock_bh(&sel_netnode_lock); } @@ -340,8 +332,10 @@ static __init int sel_netnode_init(void) if (!selinux_enabled) return 0; - for (iter = 0; iter < SEL_NETNODE_HASH_SIZE; iter++) - INIT_LIST_HEAD(&sel_netnode_hash[iter]); + for (iter = 0; iter < SEL_NETNODE_HASH_SIZE; iter++) { + INIT_LIST_HEAD(&sel_netnode_hash[iter].list); + sel_netnode_hash[iter].size = 0; + } ret = avc_add_callback(sel_netnode_avc_callback, AVC_CALLBACK_RESET, SECSID_NULL, SECSID_NULL, SECCLASS_NULL, 0); diff --git a/security/selinux/netport.c b/security/selinux/netport.c index 68ede3c498ab..90b4cff7c350 100644 --- a/security/selinux/netport.c +++ b/security/selinux/netport.c @@ -114,8 +114,7 @@ static struct sel_netport *sel_netport_find(u8 protocol, u16 pnum) idx = sel_netport_hashfn(pnum); list_for_each_entry_rcu(port, &sel_netport_hash[idx].list, list) - if (port->psec.port == pnum && - port->psec.protocol == protocol) + if (port->psec.port == pnum && port->psec.protocol == protocol) return port; return NULL; @@ -126,11 +125,10 @@ static struct sel_netport *sel_netport_find(u8 protocol, u16 pnum) * @port: the new port record * * Description: - * Add a new port record to the network address hash table. Returns zero on - * success, negative values on failure. + * Add a new port record to the network address hash table. * */ -static int sel_netport_insert(struct sel_netport *port) +static void sel_netport_insert(struct sel_netport *port) { unsigned int idx; @@ -140,13 +138,13 @@ static int sel_netport_insert(struct sel_netport *port) list_add_rcu(&port->list, &sel_netport_hash[idx].list); if (sel_netport_hash[idx].size == SEL_NETPORT_HASH_BKT_LIMIT) { struct sel_netport *tail; - tail = list_entry(port->list.prev, struct sel_netport, list); - list_del_rcu(port->list.prev); + tail = list_entry( + rcu_dereference(sel_netport_hash[idx].list.prev), + struct sel_netport, list); + list_del_rcu(&tail->list); call_rcu(&tail->rcu, sel_netport_free); } else sel_netport_hash[idx].size++; - - return 0; } /** @@ -163,7 +161,7 @@ static int sel_netport_insert(struct sel_netport *port) */ static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid) { - int ret; + int ret = -ENOMEM; struct sel_netport *port; struct sel_netport *new = NULL; @@ -171,23 +169,20 @@ static int sel_netport_sid_slow(u8 protocol, u16 pnum, u32 *sid) port = sel_netport_find(protocol, pnum); if (port != NULL) { *sid = port->psec.sid; - ret = 0; - goto out; + spin_unlock_bh(&sel_netport_lock); + return 0; } new = kzalloc(sizeof(*new), GFP_ATOMIC); - if (new == NULL) { - ret = -ENOMEM; + if (new == NULL) goto out; - } - ret = security_port_sid(protocol, pnum, &new->psec.sid); + ret = security_port_sid(protocol, pnum, sid); if (ret != 0) goto out; + new->psec.port = pnum; new->psec.protocol = protocol; - ret = sel_netport_insert(new); - if (ret != 0) - goto out; - *sid = new->psec.sid; + new->psec.sid = *sid; + sel_netport_insert(new); out: spin_unlock_bh(&sel_netport_lock); @@ -239,11 +234,12 @@ int sel_netport_sid(u8 protocol, u16 pnum, u32 *sid) static void sel_netport_flush(void) { unsigned int idx; - struct sel_netport *port; + struct sel_netport *port, *port_tmp; spin_lock_bh(&sel_netport_lock); for (idx = 0; idx < SEL_NETPORT_HASH_SIZE; idx++) { - list_for_each_entry(port, &sel_netport_hash[idx].list, list) { + list_for_each_entry_safe(port, port_tmp, + &sel_netport_hash[idx].list, list) { list_del_rcu(&port->list); call_rcu(&port->rcu, sel_netport_free); } diff --git a/security/selinux/ss/conditional.h b/security/selinux/ss/conditional.h index f3a1fc6e5d66..65b9f8366e9c 100644 --- a/security/selinux/ss/conditional.h +++ b/security/selinux/ss/conditional.h @@ -59,10 +59,10 @@ struct cond_node { struct cond_node *next; }; -int cond_policydb_init(struct policydb* p); -void cond_policydb_destroy(struct policydb* p); +int cond_policydb_init(struct policydb *p); +void cond_policydb_destroy(struct policydb *p); -int cond_init_bool_indexes(struct policydb* p); +int cond_init_bool_indexes(struct policydb *p); int cond_destroy_bool(void *key, void *datum, void *p); int cond_index_bool(void *key, void *datum, void *datap); diff --git a/security/selinux/ss/context.h b/security/selinux/ss/context.h index 2eee0dab524d..b9a6f7fc62fc 100644 --- a/security/selinux/ss/context.h +++ b/security/selinux/ss/context.h @@ -84,9 +84,9 @@ static inline int mls_context_cmp(struct context *c1, struct context *c2) return 1; return ((c1->range.level[0].sens == c2->range.level[0].sens) && - ebitmap_cmp(&c1->range.level[0].cat,&c2->range.level[0].cat) && + ebitmap_cmp(&c1->range.level[0].cat, &c2->range.level[0].cat) && (c1->range.level[1].sens == c2->range.level[1].sens) && - ebitmap_cmp(&c1->range.level[1].cat,&c2->range.level[1].cat)); + ebitmap_cmp(&c1->range.level[1].cat, &c2->range.level[1].cat)); } static inline void mls_context_destroy(struct context *c) diff --git a/security/selinux/ss/hashtab.h b/security/selinux/ss/hashtab.h index 7e2ff3e3c6d2..953872cd84ab 100644 --- a/security/selinux/ss/hashtab.h +++ b/security/selinux/ss/hashtab.h @@ -40,8 +40,8 @@ struct hashtab_info { * the new hash table otherwise. */ struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void *key), - int (*keycmp)(struct hashtab *h, const void *key1, const void *key2), - u32 size); + int (*keycmp)(struct hashtab *h, const void *key1, const void *key2), + u32 size); /* * Inserts the specified (key, datum) pair into the specified hash table. @@ -49,7 +49,7 @@ struct hashtab *hashtab_create(u32 (*hash_value)(struct hashtab *h, const void * * Returns -ENOMEM on memory allocation error, * -EEXIST if there is already an entry with the same key, * -EINVAL for general errors or - * 0 otherwise. + 0 otherwise. */ int hashtab_insert(struct hashtab *h, void *k, void *d); diff --git a/security/selinux/ss/mls.h b/security/selinux/ss/mls.h index ab53663d9f5f..0fdf6257ef64 100644 --- a/security/selinux/ss/mls.h +++ b/security/selinux/ss/mls.h @@ -13,7 +13,7 @@ /* * Updated: Hewlett-Packard <paul.moore@hp.com> * - * Added support to import/export the MLS label from NetLabel + * Added support to import/export the MLS label from NetLabel * * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 */ @@ -31,7 +31,7 @@ int mls_range_isvalid(struct policydb *p, struct mls_range *r); int mls_level_isvalid(struct policydb *p, struct mls_level *l); int mls_context_to_sid(char oldc, - char **scontext, + char **scontext, struct context *context, struct sidtab *s, u32 def_sid); @@ -49,7 +49,7 @@ int mls_compute_sid(struct context *scontext, struct context *newcontext); int mls_setup_user_range(struct context *fromcon, struct user_datum *user, - struct context *usercon); + struct context *usercon); #ifdef CONFIG_NETLABEL void mls_export_netlbl_lvl(struct context *context, diff --git a/security/selinux/ss/mls_types.h b/security/selinux/ss/mls_types.h index 0c692d58d489..b6e943a21061 100644 --- a/security/selinux/ss/mls_types.h +++ b/security/selinux/ss/mls_types.h @@ -31,7 +31,7 @@ static inline int mls_level_eq(struct mls_level *l1, struct mls_level *l2) return 1; return ((l1->sens == l2->sens) && - ebitmap_cmp(&l1->cat, &l2->cat)); + ebitmap_cmp(&l1->cat, &l2->cat)); } static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) @@ -40,7 +40,7 @@ static inline int mls_level_dom(struct mls_level *l1, struct mls_level *l2) return 1; return ((l1->sens >= l2->sens) && - ebitmap_contains(&l1->cat, &l2->cat)); + ebitmap_contains(&l1->cat, &l2->cat)); } #define mls_level_incomp(l1, l2) \ diff --git a/security/selinux/ss/policydb.h b/security/selinux/ss/policydb.h index ba593a3da877..4253370fda6a 100644 --- a/security/selinux/ss/policydb.h +++ b/security/selinux/ss/policydb.h @@ -12,12 +12,12 @@ * * Updated: Frank Mayer <mayerf@tresys.com> and Karl MacMillan <kmacmillan@tresys.com> * - * Added conditional policy language extensions + * Added conditional policy language extensions * * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * Copyright (C) 2003 - 2004 Tresys Technology, LLC * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by + * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2. */ @@ -221,7 +221,7 @@ struct policydb { /* type enforcement conditional access vectors and transitions */ struct avtab te_cond_avtab; /* linked list indexing te_cond_avtab by conditional */ - struct cond_node* cond_list; + struct cond_node *cond_list; /* role allows */ struct role_allow *role_allow; @@ -230,10 +230,10 @@ struct policydb { TCP or UDP port numbers, network interfaces and nodes */ struct ocontext *ocontexts[OCON_NUM]; - /* security contexts for files in filesystems that cannot support + /* security contexts for files in filesystems that cannot support a persistent label mapping or use another fixed labeling behavior. */ - struct genfs *genfs; + struct genfs *genfs; /* range transitions */ struct range_trans *range_tr; |