diff options
author | Nikolay Aleksandrov <nikolay@redhat.com> | 2014-03-07 06:44:19 -0500 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2014-03-10 03:30:02 -0400 |
commit | 52a4c6404f91f2d2c5592ee6365a8418c4565f53 (patch) | |
tree | c88320060de9b18fbe345a46dc9d91eecb92dde9 | |
parent | 87536a81e1f52409b45333ce8cac415a1218163c (diff) |
selinux: add gfp argument to security_xfrm_policy_alloc and fix callers
security_xfrm_policy_alloc can be called in atomic context so the
allocation should be done with GFP_ATOMIC. Add an argument to let the
callers choose the appropriate way. In order to do so a gfp argument
needs to be added to the method xfrm_policy_alloc_security in struct
security_operations and to the internal function
selinux_xfrm_alloc_user. After that switch to GFP_ATOMIC in the atomic
callers and leave GFP_KERNEL as before for the rest.
The path that needed the gfp argument addition is:
security_xfrm_policy_alloc -> security_ops.xfrm_policy_alloc_security ->
all users of xfrm_policy_alloc_security (e.g. selinux_xfrm_policy_alloc) ->
selinux_xfrm_alloc_user (here the allocation used to be GFP_KERNEL only)
Now adding a gfp argument to selinux_xfrm_alloc_user requires us to also
add it to security_context_to_sid which is used inside and prior to this
patch did only GFP_KERNEL allocation. So add gfp argument to
security_context_to_sid and adjust all of its callers as well.
CC: Paul Moore <paul@paul-moore.com>
CC: Dave Jones <davej@redhat.com>
CC: Steffen Klassert <steffen.klassert@secunet.com>
CC: Fan Du <fan.du@windriver.com>
CC: David S. Miller <davem@davemloft.net>
CC: LSM list <linux-security-module@vger.kernel.org>
CC: SELinux list <selinux@tycho.nsa.gov>
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
Acked-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
-rw-r--r-- | include/linux/security.h | 10 | ||||
-rw-r--r-- | net/key/af_key.c | 6 | ||||
-rw-r--r-- | net/xfrm/xfrm_user.c | 6 | ||||
-rw-r--r-- | security/capability.c | 3 | ||||
-rw-r--r-- | security/security.c | 6 | ||||
-rw-r--r-- | security/selinux/hooks.c | 13 | ||||
-rw-r--r-- | security/selinux/include/security.h | 2 | ||||
-rw-r--r-- | security/selinux/include/xfrm.h | 3 | ||||
-rw-r--r-- | security/selinux/selinuxfs.c | 28 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 6 | ||||
-rw-r--r-- | security/selinux/xfrm.c | 14 |
11 files changed, 59 insertions, 38 deletions
diff --git a/include/linux/security.h b/include/linux/security.h index 5623a7f965b7..2fc42d191f79 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -1040,6 +1040,7 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
1040 | * Allocate a security structure to the xp->security field; the security | 1040 | * Allocate a security structure to the xp->security field; the security |
1041 | * field is initialized to NULL when the xfrm_policy is allocated. | 1041 | * field is initialized to NULL when the xfrm_policy is allocated. |
1042 | * Return 0 if operation was successful (memory to allocate, legal context) | 1042 | * Return 0 if operation was successful (memory to allocate, legal context) |
1043 | * @gfp is to specify the context for the allocation | ||
1043 | * @xfrm_policy_clone_security: | 1044 | * @xfrm_policy_clone_security: |
1044 | * @old_ctx contains an existing xfrm_sec_ctx. | 1045 | * @old_ctx contains an existing xfrm_sec_ctx. |
1045 | * @new_ctxp contains a new xfrm_sec_ctx being cloned from old. | 1046 | * @new_ctxp contains a new xfrm_sec_ctx being cloned from old. |
@@ -1683,7 +1684,7 @@ struct security_operations { | |||
1683 | 1684 | ||
1684 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1685 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
1685 | int (*xfrm_policy_alloc_security) (struct xfrm_sec_ctx **ctxp, | 1686 | int (*xfrm_policy_alloc_security) (struct xfrm_sec_ctx **ctxp, |
1686 | struct xfrm_user_sec_ctx *sec_ctx); | 1687 | struct xfrm_user_sec_ctx *sec_ctx, gfp_t gfp); |
1687 | int (*xfrm_policy_clone_security) (struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctx); | 1688 | int (*xfrm_policy_clone_security) (struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctx); |
1688 | void (*xfrm_policy_free_security) (struct xfrm_sec_ctx *ctx); | 1689 | void (*xfrm_policy_free_security) (struct xfrm_sec_ctx *ctx); |
1689 | int (*xfrm_policy_delete_security) (struct xfrm_sec_ctx *ctx); | 1690 | int (*xfrm_policy_delete_security) (struct xfrm_sec_ctx *ctx); |
@@ -2859,7 +2860,8 @@ static inline void security_skb_owned_by(struct sk_buff *skb, struct sock *sk) | |||
2859 | 2860 | ||
2860 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 2861 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
2861 | 2862 | ||
2862 | int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx); | 2863 | int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, |
2864 | struct xfrm_user_sec_ctx *sec_ctx, gfp_t gfp); | ||
2863 | int security_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctxp); | 2865 | int security_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, struct xfrm_sec_ctx **new_ctxp); |
2864 | void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx); | 2866 | void security_xfrm_policy_free(struct xfrm_sec_ctx *ctx); |
2865 | int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx); | 2867 | int security_xfrm_policy_delete(struct xfrm_sec_ctx *ctx); |
@@ -2877,7 +2879,9 @@ void security_skb_classify_flow(struct sk_buff *skb, struct flowi *fl); | |||
2877 | 2879 | ||
2878 | #else /* CONFIG_SECURITY_NETWORK_XFRM */ | 2880 | #else /* CONFIG_SECURITY_NETWORK_XFRM */ |
2879 | 2881 | ||
2880 | static inline int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx) | 2882 | static inline int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, |
2883 | struct xfrm_user_sec_ctx *sec_ctx, | ||
2884 | gfp_t gfp) | ||
2881 | { | 2885 | { |
2882 | return 0; | 2886 | return 0; |
2883 | } | 2887 | } |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 1526023f99ed..79326978517a 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -2239,7 +2239,7 @@ static int pfkey_spdadd(struct sock *sk, struct sk_buff *skb, const struct sadb_ | |||
2239 | goto out; | 2239 | goto out; |
2240 | } | 2240 | } |
2241 | 2241 | ||
2242 | err = security_xfrm_policy_alloc(&xp->security, uctx); | 2242 | err = security_xfrm_policy_alloc(&xp->security, uctx, GFP_KERNEL); |
2243 | kfree(uctx); | 2243 | kfree(uctx); |
2244 | 2244 | ||
2245 | if (err) | 2245 | if (err) |
@@ -2341,7 +2341,7 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa | |||
2341 | if (!uctx) | 2341 | if (!uctx) |
2342 | return -ENOMEM; | 2342 | return -ENOMEM; |
2343 | 2343 | ||
2344 | err = security_xfrm_policy_alloc(&pol_ctx, uctx); | 2344 | err = security_xfrm_policy_alloc(&pol_ctx, uctx, GFP_KERNEL); |
2345 | kfree(uctx); | 2345 | kfree(uctx); |
2346 | if (err) | 2346 | if (err) |
2347 | return err; | 2347 | return err; |
@@ -3241,7 +3241,7 @@ static struct xfrm_policy *pfkey_compile_policy(struct sock *sk, int opt, | |||
3241 | if ((*dir = verify_sec_ctx_len(p))) | 3241 | if ((*dir = verify_sec_ctx_len(p))) |
3242 | goto out; | 3242 | goto out; |
3243 | uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx, GFP_ATOMIC); | 3243 | uctx = pfkey_sadb2xfrm_user_sec_ctx(sec_ctx, GFP_ATOMIC); |
3244 | *dir = security_xfrm_policy_alloc(&xp->security, uctx); | 3244 | *dir = security_xfrm_policy_alloc(&xp->security, uctx, GFP_ATOMIC); |
3245 | kfree(uctx); | 3245 | kfree(uctx); |
3246 | 3246 | ||
3247 | if (*dir) | 3247 | if (*dir) |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index c274179d60a2..2f7ddc3a59b4 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1221,7 +1221,7 @@ static int copy_from_user_sec_ctx(struct xfrm_policy *pol, struct nlattr **attrs | |||
1221 | return 0; | 1221 | return 0; |
1222 | 1222 | ||
1223 | uctx = nla_data(rt); | 1223 | uctx = nla_data(rt); |
1224 | return security_xfrm_policy_alloc(&pol->security, uctx); | 1224 | return security_xfrm_policy_alloc(&pol->security, uctx, GFP_KERNEL); |
1225 | } | 1225 | } |
1226 | 1226 | ||
1227 | static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, | 1227 | static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, |
@@ -1626,7 +1626,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1626 | if (rt) { | 1626 | if (rt) { |
1627 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); | 1627 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); |
1628 | 1628 | ||
1629 | err = security_xfrm_policy_alloc(&ctx, uctx); | 1629 | err = security_xfrm_policy_alloc(&ctx, uctx, GFP_KERNEL); |
1630 | if (err) | 1630 | if (err) |
1631 | return err; | 1631 | return err; |
1632 | } | 1632 | } |
@@ -1928,7 +1928,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1928 | if (rt) { | 1928 | if (rt) { |
1929 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); | 1929 | struct xfrm_user_sec_ctx *uctx = nla_data(rt); |
1930 | 1930 | ||
1931 | err = security_xfrm_policy_alloc(&ctx, uctx); | 1931 | err = security_xfrm_policy_alloc(&ctx, uctx, GFP_KERNEL); |
1932 | if (err) | 1932 | if (err) |
1933 | return err; | 1933 | return err; |
1934 | } | 1934 | } |
diff --git a/security/capability.c b/security/capability.c index 8b4f24ae4338..21e2b9cae685 100644 --- a/security/capability.c +++ b/security/capability.c | |||
@@ -757,7 +757,8 @@ static void cap_skb_owned_by(struct sk_buff *skb, struct sock *sk) | |||
757 | 757 | ||
758 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 758 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
759 | static int cap_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp, | 759 | static int cap_xfrm_policy_alloc_security(struct xfrm_sec_ctx **ctxp, |
760 | struct xfrm_user_sec_ctx *sec_ctx) | 760 | struct xfrm_user_sec_ctx *sec_ctx, |
761 | gfp_t gfp) | ||
761 | { | 762 | { |
762 | return 0; | 763 | return 0; |
763 | } | 764 | } |
diff --git a/security/security.c b/security/security.c index 15b6928592ef..919cad93ac82 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -1317,9 +1317,11 @@ void security_skb_owned_by(struct sk_buff *skb, struct sock *sk) | |||
1317 | 1317 | ||
1318 | #ifdef CONFIG_SECURITY_NETWORK_XFRM | 1318 | #ifdef CONFIG_SECURITY_NETWORK_XFRM |
1319 | 1319 | ||
1320 | int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_user_sec_ctx *sec_ctx) | 1320 | int security_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, |
1321 | struct xfrm_user_sec_ctx *sec_ctx, | ||
1322 | gfp_t gfp) | ||
1321 | { | 1323 | { |
1322 | return security_ops->xfrm_policy_alloc_security(ctxp, sec_ctx); | 1324 | return security_ops->xfrm_policy_alloc_security(ctxp, sec_ctx, gfp); |
1323 | } | 1325 | } |
1324 | EXPORT_SYMBOL(security_xfrm_policy_alloc); | 1326 | EXPORT_SYMBOL(security_xfrm_policy_alloc); |
1325 | 1327 | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 4b34847208cc..b332e2cc0954 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -668,7 +668,7 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
668 | if (flags[i] == SBLABEL_MNT) | 668 | if (flags[i] == SBLABEL_MNT) |
669 | continue; | 669 | continue; |
670 | rc = security_context_to_sid(mount_options[i], | 670 | rc = security_context_to_sid(mount_options[i], |
671 | strlen(mount_options[i]), &sid); | 671 | strlen(mount_options[i]), &sid, GFP_KERNEL); |
672 | if (rc) { | 672 | if (rc) { |
673 | printk(KERN_WARNING "SELinux: security_context_to_sid" | 673 | printk(KERN_WARNING "SELinux: security_context_to_sid" |
674 | "(%s) failed for (dev %s, type %s) errno=%d\n", | 674 | "(%s) failed for (dev %s, type %s) errno=%d\n", |
@@ -2489,7 +2489,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data) | |||
2489 | if (flags[i] == SBLABEL_MNT) | 2489 | if (flags[i] == SBLABEL_MNT) |
2490 | continue; | 2490 | continue; |
2491 | len = strlen(mount_options[i]); | 2491 | len = strlen(mount_options[i]); |
2492 | rc = security_context_to_sid(mount_options[i], len, &sid); | 2492 | rc = security_context_to_sid(mount_options[i], len, &sid, |
2493 | GFP_KERNEL); | ||
2493 | if (rc) { | 2494 | if (rc) { |
2494 | printk(KERN_WARNING "SELinux: security_context_to_sid" | 2495 | printk(KERN_WARNING "SELinux: security_context_to_sid" |
2495 | "(%s) failed for (dev %s, type %s) errno=%d\n", | 2496 | "(%s) failed for (dev %s, type %s) errno=%d\n", |
@@ -2893,7 +2894,7 @@ static int selinux_inode_setxattr(struct dentry *dentry, const char *name, | |||
2893 | if (rc) | 2894 | if (rc) |
2894 | return rc; | 2895 | return rc; |
2895 | 2896 | ||
2896 | rc = security_context_to_sid(value, size, &newsid); | 2897 | rc = security_context_to_sid(value, size, &newsid, GFP_KERNEL); |
2897 | if (rc == -EINVAL) { | 2898 | if (rc == -EINVAL) { |
2898 | if (!capable(CAP_MAC_ADMIN)) { | 2899 | if (!capable(CAP_MAC_ADMIN)) { |
2899 | struct audit_buffer *ab; | 2900 | struct audit_buffer *ab; |
@@ -3050,7 +3051,7 @@ static int selinux_inode_setsecurity(struct inode *inode, const char *name, | |||
3050 | if (!value || !size) | 3051 | if (!value || !size) |
3051 | return -EACCES; | 3052 | return -EACCES; |
3052 | 3053 | ||
3053 | rc = security_context_to_sid((void *)value, size, &newsid); | 3054 | rc = security_context_to_sid((void *)value, size, &newsid, GFP_KERNEL); |
3054 | if (rc) | 3055 | if (rc) |
3055 | return rc; | 3056 | return rc; |
3056 | 3057 | ||
@@ -5529,7 +5530,7 @@ static int selinux_setprocattr(struct task_struct *p, | |||
5529 | str[size-1] = 0; | 5530 | str[size-1] = 0; |
5530 | size--; | 5531 | size--; |
5531 | } | 5532 | } |
5532 | error = security_context_to_sid(value, size, &sid); | 5533 | error = security_context_to_sid(value, size, &sid, GFP_KERNEL); |
5533 | if (error == -EINVAL && !strcmp(name, "fscreate")) { | 5534 | if (error == -EINVAL && !strcmp(name, "fscreate")) { |
5534 | if (!capable(CAP_MAC_ADMIN)) { | 5535 | if (!capable(CAP_MAC_ADMIN)) { |
5535 | struct audit_buffer *ab; | 5536 | struct audit_buffer *ab; |
@@ -5638,7 +5639,7 @@ static int selinux_secid_to_secctx(u32 secid, char **secdata, u32 *seclen) | |||
5638 | 5639 | ||
5639 | static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) | 5640 | static int selinux_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid) |
5640 | { | 5641 | { |
5641 | return security_context_to_sid(secdata, seclen, secid); | 5642 | return security_context_to_sid(secdata, seclen, secid, GFP_KERNEL); |
5642 | } | 5643 | } |
5643 | 5644 | ||
5644 | static void selinux_release_secctx(char *secdata, u32 seclen) | 5645 | static void selinux_release_secctx(char *secdata, u32 seclen) |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index 8ed8daf7f1ee..ce7852cf526b 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -134,7 +134,7 @@ int security_sid_to_context(u32 sid, char **scontext, | |||
134 | int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len); | 134 | int security_sid_to_context_force(u32 sid, char **scontext, u32 *scontext_len); |
135 | 135 | ||
136 | int security_context_to_sid(const char *scontext, u32 scontext_len, | 136 | int security_context_to_sid(const char *scontext, u32 scontext_len, |
137 | u32 *out_sid); | 137 | u32 *out_sid, gfp_t gfp); |
138 | 138 | ||
139 | int security_context_to_sid_default(const char *scontext, u32 scontext_len, | 139 | int security_context_to_sid_default(const char *scontext, u32 scontext_len, |
140 | u32 *out_sid, u32 def_sid, gfp_t gfp_flags); | 140 | u32 *out_sid, u32 def_sid, gfp_t gfp_flags); |
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index 48c3cc94c168..9f0584710c85 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h | |||
@@ -10,7 +10,8 @@ | |||
10 | #include <net/flow.h> | 10 | #include <net/flow.h> |
11 | 11 | ||
12 | int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, | 12 | int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, |
13 | struct xfrm_user_sec_ctx *uctx); | 13 | struct xfrm_user_sec_ctx *uctx, |
14 | gfp_t gfp); | ||
14 | int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, | 15 | int selinux_xfrm_policy_clone(struct xfrm_sec_ctx *old_ctx, |
15 | struct xfrm_sec_ctx **new_ctxp); | 16 | struct xfrm_sec_ctx **new_ctxp); |
16 | void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx); | 17 | void selinux_xfrm_policy_free(struct xfrm_sec_ctx *ctx); |
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c index 5122affe06a8..d60c0ee66387 100644 --- a/security/selinux/selinuxfs.c +++ b/security/selinux/selinuxfs.c | |||
@@ -576,7 +576,7 @@ static ssize_t sel_write_context(struct file *file, char *buf, size_t size) | |||
576 | if (length) | 576 | if (length) |
577 | goto out; | 577 | goto out; |
578 | 578 | ||
579 | length = security_context_to_sid(buf, size, &sid); | 579 | length = security_context_to_sid(buf, size, &sid, GFP_KERNEL); |
580 | if (length) | 580 | if (length) |
581 | goto out; | 581 | goto out; |
582 | 582 | ||
@@ -731,11 +731,13 @@ 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_to_sid(scon, strlen(scon) + 1, &ssid, |
735 | GFP_KERNEL); | ||
735 | if (length) | 736 | if (length) |
736 | goto out; | 737 | goto out; |
737 | 738 | ||
738 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); | 739 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, |
740 | GFP_KERNEL); | ||
739 | if (length) | 741 | if (length) |
740 | goto out; | 742 | goto out; |
741 | 743 | ||
@@ -817,11 +819,13 @@ static ssize_t sel_write_create(struct file *file, char *buf, size_t size) | |||
817 | objname = namebuf; | 819 | objname = namebuf; |
818 | } | 820 | } |
819 | 821 | ||
820 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); | 822 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, |
823 | GFP_KERNEL); | ||
821 | if (length) | 824 | if (length) |
822 | goto out; | 825 | goto out; |
823 | 826 | ||
824 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); | 827 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, |
828 | GFP_KERNEL); | ||
825 | if (length) | 829 | if (length) |
826 | goto out; | 830 | goto out; |
827 | 831 | ||
@@ -878,11 +882,13 @@ static ssize_t sel_write_relabel(struct file *file, char *buf, size_t size) | |||
878 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) | 882 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) |
879 | goto out; | 883 | goto out; |
880 | 884 | ||
881 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); | 885 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, |
886 | GFP_KERNEL); | ||
882 | if (length) | 887 | if (length) |
883 | goto out; | 888 | goto out; |
884 | 889 | ||
885 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); | 890 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, |
891 | GFP_KERNEL); | ||
886 | if (length) | 892 | if (length) |
887 | goto out; | 893 | goto out; |
888 | 894 | ||
@@ -934,7 +940,7 @@ static ssize_t sel_write_user(struct file *file, char *buf, size_t size) | |||
934 | if (sscanf(buf, "%s %s", con, user) != 2) | 940 | if (sscanf(buf, "%s %s", con, user) != 2) |
935 | goto out; | 941 | goto out; |
936 | 942 | ||
937 | length = security_context_to_sid(con, strlen(con) + 1, &sid); | 943 | length = security_context_to_sid(con, strlen(con) + 1, &sid, GFP_KERNEL); |
938 | if (length) | 944 | if (length) |
939 | goto out; | 945 | goto out; |
940 | 946 | ||
@@ -994,11 +1000,13 @@ static ssize_t sel_write_member(struct file *file, char *buf, size_t size) | |||
994 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) | 1000 | if (sscanf(buf, "%s %s %hu", scon, tcon, &tclass) != 3) |
995 | goto out; | 1001 | goto out; |
996 | 1002 | ||
997 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid); | 1003 | length = security_context_to_sid(scon, strlen(scon) + 1, &ssid, |
1004 | GFP_KERNEL); | ||
998 | if (length) | 1005 | if (length) |
999 | goto out; | 1006 | goto out; |
1000 | 1007 | ||
1001 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid); | 1008 | length = security_context_to_sid(tcon, strlen(tcon) + 1, &tsid, |
1009 | GFP_KERNEL); | ||
1002 | if (length) | 1010 | if (length) |
1003 | goto out; | 1011 | goto out; |
1004 | 1012 | ||
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 5d0144ee8ed6..4bca49414a40 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -1289,16 +1289,18 @@ out: | |||
1289 | * @scontext: security context | 1289 | * @scontext: security context |
1290 | * @scontext_len: length in bytes | 1290 | * @scontext_len: length in bytes |
1291 | * @sid: security identifier, SID | 1291 | * @sid: security identifier, SID |
1292 | * @gfp: context for the allocation | ||
1292 | * | 1293 | * |
1293 | * Obtains a SID associated with the security context that | 1294 | * Obtains a SID associated with the security context that |
1294 | * has the string representation specified by @scontext. | 1295 | * has the string representation specified by @scontext. |
1295 | * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient | 1296 | * Returns -%EINVAL if the context is invalid, -%ENOMEM if insufficient |
1296 | * memory is available, or 0 on success. | 1297 | * memory is available, or 0 on success. |
1297 | */ | 1298 | */ |
1298 | int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid) | 1299 | int security_context_to_sid(const char *scontext, u32 scontext_len, u32 *sid, |
1300 | gfp_t gfp) | ||
1299 | { | 1301 | { |
1300 | return security_context_to_sid_core(scontext, scontext_len, | 1302 | return security_context_to_sid_core(scontext, scontext_len, |
1301 | sid, SECSID_NULL, GFP_KERNEL, 0); | 1303 | sid, SECSID_NULL, gfp, 0); |
1302 | } | 1304 | } |
1303 | 1305 | ||
1304 | /** | 1306 | /** |
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index 0462cb3ff0a7..98b042630a9e 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
@@ -78,7 +78,8 @@ static inline int selinux_authorizable_xfrm(struct xfrm_state *x) | |||
78 | * xfrm_user_sec_ctx context. | 78 | * xfrm_user_sec_ctx context. |
79 | */ | 79 | */ |
80 | static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, | 80 | static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, |
81 | struct xfrm_user_sec_ctx *uctx) | 81 | struct xfrm_user_sec_ctx *uctx, |
82 | gfp_t gfp) | ||
82 | { | 83 | { |
83 | int rc; | 84 | int rc; |
84 | const struct task_security_struct *tsec = current_security(); | 85 | const struct task_security_struct *tsec = current_security(); |
@@ -94,7 +95,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, | |||
94 | if (str_len >= PAGE_SIZE) | 95 | if (str_len >= PAGE_SIZE) |
95 | return -ENOMEM; | 96 | return -ENOMEM; |
96 | 97 | ||
97 | ctx = kmalloc(sizeof(*ctx) + str_len + 1, GFP_KERNEL); | 98 | ctx = kmalloc(sizeof(*ctx) + str_len + 1, gfp); |
98 | if (!ctx) | 99 | if (!ctx) |
99 | return -ENOMEM; | 100 | return -ENOMEM; |
100 | 101 | ||
@@ -103,7 +104,7 @@ static int selinux_xfrm_alloc_user(struct xfrm_sec_ctx **ctxp, | |||
103 | ctx->ctx_len = str_len; | 104 | ctx->ctx_len = str_len; |
104 | memcpy(ctx->ctx_str, &uctx[1], str_len); | 105 | memcpy(ctx->ctx_str, &uctx[1], str_len); |
105 | ctx->ctx_str[str_len] = '\0'; | 106 | ctx->ctx_str[str_len] = '\0'; |
106 | rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid); | 107 | rc = security_context_to_sid(ctx->ctx_str, str_len, &ctx->ctx_sid, gfp); |
107 | if (rc) | 108 | if (rc) |
108 | goto err; | 109 | goto err; |
109 | 110 | ||
@@ -282,9 +283,10 @@ int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid) | |||
282 | * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy. | 283 | * LSM hook implementation that allocs and transfers uctx spec to xfrm_policy. |
283 | */ | 284 | */ |
284 | int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, | 285 | int selinux_xfrm_policy_alloc(struct xfrm_sec_ctx **ctxp, |
285 | struct xfrm_user_sec_ctx *uctx) | 286 | struct xfrm_user_sec_ctx *uctx, |
287 | gfp_t gfp) | ||
286 | { | 288 | { |
287 | return selinux_xfrm_alloc_user(ctxp, uctx); | 289 | return selinux_xfrm_alloc_user(ctxp, uctx, gfp); |
288 | } | 290 | } |
289 | 291 | ||
290 | /* | 292 | /* |
@@ -332,7 +334,7 @@ int selinux_xfrm_policy_delete(struct xfrm_sec_ctx *ctx) | |||
332 | int selinux_xfrm_state_alloc(struct xfrm_state *x, | 334 | int selinux_xfrm_state_alloc(struct xfrm_state *x, |
333 | struct xfrm_user_sec_ctx *uctx) | 335 | struct xfrm_user_sec_ctx *uctx) |
334 | { | 336 | { |
335 | return selinux_xfrm_alloc_user(&x->security, uctx); | 337 | return selinux_xfrm_alloc_user(&x->security, uctx, GFP_KERNEL); |
336 | } | 338 | } |
337 | 339 | ||
338 | /* | 340 | /* |