diff options
author | Dave Airlie <airlied@redhat.com> | 2015-04-20 11:32:26 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-04-20 13:05:20 +1000 |
commit | 2c33ce009ca2389dbf0535d0672214d09738e35e (patch) | |
tree | 6186a6458c3c160385d794a23eaf07c786a9e61b /security/selinux | |
parent | cec32a47010647e8b0603726ebb75b990a4057a4 (diff) | |
parent | 09d51602cf84a1264946711dd4ea0dddbac599a1 (diff) |
Merge Linus master into drm-next
The merge is clean, but the arm build fails afterwards,
due to API changes in the regulator tree.
I've included the patch into the merge to fix the build.
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'security/selinux')
-rw-r--r-- | security/selinux/avc.c | 6 | ||||
-rw-r--r-- | security/selinux/hooks.c | 47 | ||||
-rw-r--r-- | security/selinux/nlmsgtab.c | 13 | ||||
-rw-r--r-- | security/selinux/ss/avtab.c | 72 | ||||
-rw-r--r-- | security/selinux/ss/avtab.h | 8 | ||||
-rw-r--r-- | security/selinux/ss/mls.c | 10 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 6 |
7 files changed, 92 insertions, 70 deletions
diff --git a/security/selinux/avc.c b/security/selinux/avc.c index afcc0aed9393..3c17dda9571d 100644 --- a/security/selinux/avc.c +++ b/security/selinux/avc.c @@ -724,12 +724,10 @@ inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, rcu_read_lock(); node = avc_lookup(ssid, tsid, tclass); - if (unlikely(!node)) { + if (unlikely(!node)) node = avc_compute_av(ssid, tsid, tclass, avd); - } else { + else memcpy(avd, &node->ae.avd, sizeof(*avd)); - avd = &node->ae.avd; - } denied = requested & ~(avd->allowed); if (unlikely(denied)) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4d1a54190388..c318b304ee2f 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -51,7 +51,6 @@ #include <linux/tty.h> #include <net/icmp.h> #include <net/ip.h> /* for local_port_range[] */ -#include <net/sock.h> #include <net/tcp.h> /* struct or_callable used in sock_rcv_skb */ #include <net/inet_connection_sock.h> #include <net/net_namespace.h> @@ -1623,7 +1622,7 @@ static inline int dentry_has_perm(const struct cred *cred, the path to help the auditing code to more easily generate the pathname if needed. */ static inline int path_has_perm(const struct cred *cred, - struct path *path, + const struct path *path, u32 av) { struct inode *inode = path->dentry->d_inode; @@ -2954,15 +2953,9 @@ static int selinux_inode_setattr(struct dentry *dentry, struct iattr *iattr) return dentry_has_perm(cred, dentry, av); } -static int selinux_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) +static int selinux_inode_getattr(const struct path *path) { - const struct cred *cred = current_cred(); - struct path path; - - path.dentry = dentry; - path.mnt = mnt; - - return path_has_perm(cred, &path, FILE__GETATTR); + return path_has_perm(current_cred(), path, FILE__GETATTR); } static int selinux_inode_setotherxattr(struct dentry *dentry, const char *name) @@ -4652,11 +4645,6 @@ static void selinux_inet_conn_established(struct sock *sk, struct sk_buff *skb) selinux_skb_peerlbl_sid(skb, family, &sksec->peer_sid); } -static void selinux_skb_owned_by(struct sk_buff *skb, struct sock *sk) -{ - skb_set_owner_w(skb, sk); -} - static int selinux_secmark_relabel_packet(u32 sid) { const struct task_security_struct *__tsec; @@ -4858,21 +4846,17 @@ static unsigned int selinux_ip_forward(struct sk_buff *skb, static unsigned int selinux_ipv4_forward(const struct nf_hook_ops *ops, struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) + const struct nf_hook_state *state) { - return selinux_ip_forward(skb, in, PF_INET); + return selinux_ip_forward(skb, state->in, PF_INET); } #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) static unsigned int selinux_ipv6_forward(const struct nf_hook_ops *ops, struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) + const struct nf_hook_state *state) { - return selinux_ip_forward(skb, in, PF_INET6); + return selinux_ip_forward(skb, state->in, PF_INET6); } #endif /* IPV6 */ @@ -4920,9 +4904,7 @@ static unsigned int selinux_ip_output(struct sk_buff *skb, static unsigned int selinux_ipv4_output(const struct nf_hook_ops *ops, struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) + const struct nf_hook_state *state) { return selinux_ip_output(skb, PF_INET); } @@ -5097,21 +5079,17 @@ static unsigned int selinux_ip_postroute(struct sk_buff *skb, static unsigned int selinux_ipv4_postroute(const struct nf_hook_ops *ops, struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) + const struct nf_hook_state *state) { - return selinux_ip_postroute(skb, out, PF_INET); + return selinux_ip_postroute(skb, state->out, PF_INET); } #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) static unsigned int selinux_ipv6_postroute(const struct nf_hook_ops *ops, struct sk_buff *skb, - const struct net_device *in, - const struct net_device *out, - int (*okfn)(struct sk_buff *)) + const struct nf_hook_state *state) { - return selinux_ip_postroute(skb, out, PF_INET6); + return selinux_ip_postroute(skb, state->out, PF_INET6); } #endif /* IPV6 */ @@ -6041,7 +6019,6 @@ static struct security_operations selinux_ops = { .tun_dev_attach_queue = selinux_tun_dev_attach_queue, .tun_dev_attach = selinux_tun_dev_attach, .tun_dev_open = selinux_tun_dev_open, - .skb_owned_by = selinux_skb_owned_by, #ifdef CONFIG_SECURITY_NETWORK_XFRM .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, diff --git a/security/selinux/nlmsgtab.c b/security/selinux/nlmsgtab.c index 2df7b900e259..2bbb41822d8e 100644 --- a/security/selinux/nlmsgtab.c +++ b/security/selinux/nlmsgtab.c @@ -73,6 +73,9 @@ static struct nlmsg_perm nlmsg_route_perms[] = { RTM_NEWMDB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, { RTM_DELMDB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, { RTM_GETMDB, NETLINK_ROUTE_SOCKET__NLMSG_READ }, + { RTM_NEWNSID, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, + { RTM_DELNSID, NETLINK_ROUTE_SOCKET__NLMSG_READ }, + { RTM_GETNSID, NETLINK_ROUTE_SOCKET__NLMSG_READ }, }; static struct nlmsg_perm nlmsg_tcpdiag_perms[] = @@ -100,6 +103,13 @@ static struct nlmsg_perm nlmsg_xfrm_perms[] = { XFRM_MSG_FLUSHPOLICY, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, { XFRM_MSG_NEWAE, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, { XFRM_MSG_GETAE, NETLINK_XFRM_SOCKET__NLMSG_READ }, + { XFRM_MSG_REPORT, NETLINK_XFRM_SOCKET__NLMSG_READ }, + { XFRM_MSG_MIGRATE, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, + { XFRM_MSG_NEWSADINFO, NETLINK_XFRM_SOCKET__NLMSG_READ }, + { XFRM_MSG_GETSADINFO, NETLINK_XFRM_SOCKET__NLMSG_READ }, + { XFRM_MSG_NEWSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, + { XFRM_MSG_GETSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_READ }, + { XFRM_MSG_MAPPING, NETLINK_XFRM_SOCKET__NLMSG_READ }, }; static struct nlmsg_perm nlmsg_audit_perms[] = @@ -143,6 +153,8 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm) switch (sclass) { case SECCLASS_NETLINK_ROUTE_SOCKET: + /* RTM_MAX always point to RTM_SETxxxx, ie RTM_NEWxxx + 3 */ + BUILD_BUG_ON(RTM_MAX != (RTM_NEWNSID + 3)); err = nlmsg_perm(nlmsg_type, perm, nlmsg_route_perms, sizeof(nlmsg_route_perms)); break; @@ -153,6 +165,7 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm) break; case SECCLASS_NETLINK_XFRM_SOCKET: + BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_MAPPING); err = nlmsg_perm(nlmsg_type, perm, nlmsg_xfrm_perms, sizeof(nlmsg_xfrm_perms)); break; diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c index a3dd9faa19c0..b64f2772b030 100644 --- a/security/selinux/ss/avtab.c +++ b/security/selinux/ss/avtab.c @@ -25,10 +25,43 @@ static struct kmem_cache *avtab_node_cachep; -static inline int avtab_hash(struct avtab_key *keyp, u16 mask) +/* Based on MurmurHash3, written by Austin Appleby and placed in the + * public domain. + */ +static inline int avtab_hash(struct avtab_key *keyp, u32 mask) { - return ((keyp->target_class + (keyp->target_type << 2) + - (keyp->source_type << 9)) & mask); + static const u32 c1 = 0xcc9e2d51; + static const u32 c2 = 0x1b873593; + static const u32 r1 = 15; + static const u32 r2 = 13; + static const u32 m = 5; + static const u32 n = 0xe6546b64; + + u32 hash = 0; + +#define mix(input) { \ + u32 v = input; \ + v *= c1; \ + v = (v << r1) | (v >> (32 - r1)); \ + v *= c2; \ + hash ^= v; \ + hash = (hash << r2) | (hash >> (32 - r2)); \ + hash = hash * m + n; \ +} + + mix(keyp->target_class); + mix(keyp->target_type); + mix(keyp->source_type); + +#undef mix + + hash ^= hash >> 16; + hash *= 0x85ebca6b; + hash ^= hash >> 13; + hash *= 0xc2b2ae35; + hash ^= hash >> 16; + + return hash & mask; } static struct avtab_node* @@ -46,8 +79,12 @@ avtab_insert_node(struct avtab *h, int hvalue, newnode->next = prev->next; prev->next = newnode; } else { - newnode->next = h->htable[hvalue]; - h->htable[hvalue] = newnode; + newnode->next = flex_array_get_ptr(h->htable, hvalue); + if (flex_array_put_ptr(h->htable, hvalue, newnode, + GFP_KERNEL|__GFP_ZERO)) { + kmem_cache_free(avtab_node_cachep, newnode); + return NULL; + } } h->nel++; @@ -64,7 +101,7 @@ static int avtab_insert(struct avtab *h, struct avtab_key *key, struct avtab_dat return -EINVAL; hvalue = avtab_hash(key, h->mask); - for (prev = NULL, cur = h->htable[hvalue]; + for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue); cur; prev = cur, cur = cur->next) { if (key->source_type == cur->key.source_type && @@ -104,7 +141,7 @@ avtab_insert_nonunique(struct avtab *h, struct avtab_key *key, struct avtab_datu if (!h || !h->htable) return NULL; hvalue = avtab_hash(key, h->mask); - for (prev = NULL, cur = h->htable[hvalue]; + for (prev = NULL, cur = flex_array_get_ptr(h->htable, hvalue); cur; prev = cur, cur = cur->next) { if (key->source_type == cur->key.source_type && @@ -135,7 +172,8 @@ struct avtab_datum *avtab_search(struct avtab *h, struct avtab_key *key) return NULL; hvalue = avtab_hash(key, h->mask); - for (cur = h->htable[hvalue]; cur; cur = cur->next) { + for (cur = flex_array_get_ptr(h->htable, hvalue); cur; + cur = cur->next) { if (key->source_type == cur->key.source_type && key->target_type == cur->key.target_type && key->target_class == cur->key.target_class && @@ -170,7 +208,8 @@ avtab_search_node(struct avtab *h, struct avtab_key *key) return NULL; hvalue = avtab_hash(key, h->mask); - for (cur = h->htable[hvalue]; cur; cur = cur->next) { + for (cur = flex_array_get_ptr(h->htable, hvalue); cur; + cur = cur->next) { if (key->source_type == cur->key.source_type && key->target_type == cur->key.target_type && key->target_class == cur->key.target_class && @@ -228,15 +267,14 @@ void avtab_destroy(struct avtab *h) return; for (i = 0; i < h->nslot; i++) { - cur = h->htable[i]; + cur = flex_array_get_ptr(h->htable, i); while (cur) { temp = cur; cur = cur->next; kmem_cache_free(avtab_node_cachep, temp); } - h->htable[i] = NULL; } - kfree(h->htable); + flex_array_free(h->htable); h->htable = NULL; h->nslot = 0; h->mask = 0; @@ -251,7 +289,7 @@ int avtab_init(struct avtab *h) int avtab_alloc(struct avtab *h, u32 nrules) { - u16 mask = 0; + u32 mask = 0; u32 shift = 0; u32 work = nrules; u32 nslot = 0; @@ -270,7 +308,8 @@ int avtab_alloc(struct avtab *h, u32 nrules) nslot = MAX_AVTAB_HASH_BUCKETS; mask = nslot - 1; - h->htable = kcalloc(nslot, sizeof(*(h->htable)), GFP_KERNEL); + h->htable = flex_array_alloc(sizeof(struct avtab_node *), nslot, + GFP_KERNEL | __GFP_ZERO); if (!h->htable) return -ENOMEM; @@ -293,7 +332,7 @@ void avtab_hash_eval(struct avtab *h, char *tag) max_chain_len = 0; chain2_len_sum = 0; for (i = 0; i < h->nslot; i++) { - cur = h->htable[i]; + cur = flex_array_get_ptr(h->htable, i); if (cur) { slots_used++; chain_len = 0; @@ -534,7 +573,8 @@ int avtab_write(struct policydb *p, struct avtab *a, void *fp) return rc; for (i = 0; i < a->nslot; i++) { - for (cur = a->htable[i]; cur; cur = cur->next) { + for (cur = flex_array_get_ptr(a->htable, i); cur; + cur = cur->next) { rc = avtab_write_item(p, cur, fp); if (rc) return rc; diff --git a/security/selinux/ss/avtab.h b/security/selinux/ss/avtab.h index 63ce2f9e441d..adb451cd44f9 100644 --- a/security/selinux/ss/avtab.h +++ b/security/selinux/ss/avtab.h @@ -23,6 +23,8 @@ #ifndef _SS_AVTAB_H_ #define _SS_AVTAB_H_ +#include <linux/flex_array.h> + struct avtab_key { u16 source_type; /* source type */ u16 target_type; /* target type */ @@ -51,10 +53,10 @@ struct avtab_node { }; struct avtab { - struct avtab_node **htable; + struct flex_array *htable; u32 nel; /* number of elements */ u32 nslot; /* number of hash slots */ - u16 mask; /* mask to compute hash func */ + u32 mask; /* mask to compute hash func */ }; @@ -84,7 +86,7 @@ struct avtab_node *avtab_search_node_next(struct avtab_node *node, int specified void avtab_cache_init(void); void avtab_cache_destroy(void); -#define MAX_AVTAB_HASH_BITS 11 +#define MAX_AVTAB_HASH_BITS 16 #define MAX_AVTAB_HASH_BUCKETS (1 << MAX_AVTAB_HASH_BITS) #endif /* _SS_AVTAB_H_ */ diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index d307b37ddc2b..e1088842232c 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -654,19 +654,15 @@ int mls_import_netlbl_cat(struct context *context, rc = ebitmap_netlbl_import(&context->range.level[0].cat, secattr->attr.mls.cat); - if (rc != 0) - goto import_netlbl_cat_failure; - - rc = ebitmap_cpy(&context->range.level[1].cat, - &context->range.level[0].cat); - if (rc != 0) + if (rc) goto import_netlbl_cat_failure; + memcpy(&context->range.level[1].cat, &context->range.level[0].cat, + sizeof(context->range.level[0].cat)); return 0; import_netlbl_cat_failure: ebitmap_destroy(&context->range.level[0].cat); - ebitmap_destroy(&context->range.level[1].cat); return rc; } #endif /* CONFIG_NETLABEL */ diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index a1d3944751b9..9e2d82070915 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -3179,13 +3179,9 @@ int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr, ctx_new.type = ctx->type; mls_import_netlbl_lvl(&ctx_new, secattr); if (secattr->flags & NETLBL_SECATTR_MLS_CAT) { - rc = ebitmap_netlbl_import(&ctx_new.range.level[0].cat, - secattr->attr.mls.cat); + rc = mls_import_netlbl_cat(&ctx_new, secattr); if (rc) goto out; - memcpy(&ctx_new.range.level[1].cat, - &ctx_new.range.level[0].cat, - sizeof(ctx_new.range.level[0].cat)); } rc = -EIDRM; if (!mls_context_isvalid(&policydb, &ctx_new)) |