diff options
| -rw-r--r-- | include/linux/security.h | 40 | ||||
| -rw-r--r-- | net/key/af_key.c | 17 | ||||
| -rw-r--r-- | net/xfrm/xfrm_user.c | 19 | ||||
| -rw-r--r-- | security/dummy.c | 12 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 2 | ||||
| -rw-r--r-- | security/selinux/include/xfrm.h | 2 | ||||
| -rw-r--r-- | security/selinux/xfrm.c | 39 |
7 files changed, 108 insertions, 23 deletions
diff --git a/include/linux/security.h b/include/linux/security.h index 1bab48f6aeac..14c9bd050607 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
| @@ -805,31 +805,37 @@ struct swap_info_struct; | |||
| 805 | * used by the XFRM system. | 805 | * used by the XFRM system. |
| 806 | * @sec_ctx contains the security context information being provided by | 806 | * @sec_ctx contains the security context information being provided by |
| 807 | * the user-level policy update program (e.g., setkey). | 807 | * the user-level policy update program (e.g., setkey). |
| 808 | * Allocate a security structure to the xp->selector.security field. | 808 | * Allocate a security structure to the xp->security field. |
| 809 | * The security field is initialized to NULL when the xfrm_policy is | 809 | * The security field is initialized to NULL when the xfrm_policy is |
| 810 | * allocated. | 810 | * allocated. |
| 811 | * Return 0 if operation was successful (memory to allocate, legal context) | 811 | * Return 0 if operation was successful (memory to allocate, legal context) |
| 812 | * @xfrm_policy_clone_security: | 812 | * @xfrm_policy_clone_security: |
| 813 | * @old contains an existing xfrm_policy in the SPD. | 813 | * @old contains an existing xfrm_policy in the SPD. |
| 814 | * @new contains a new xfrm_policy being cloned from old. | 814 | * @new contains a new xfrm_policy being cloned from old. |
| 815 | * Allocate a security structure to the new->selector.security field | 815 | * Allocate a security structure to the new->security field |
| 816 | * that contains the information from the old->selector.security field. | 816 | * that contains the information from the old->security field. |
| 817 | * Return 0 if operation was successful (memory to allocate). | 817 | * Return 0 if operation was successful (memory to allocate). |
| 818 | * @xfrm_policy_free_security: | 818 | * @xfrm_policy_free_security: |
| 819 | * @xp contains the xfrm_policy | 819 | * @xp contains the xfrm_policy |
| 820 | * Deallocate xp->selector.security. | 820 | * Deallocate xp->security. |
| 821 | * @xfrm_policy_delete_security: | ||
| 822 | * @xp contains the xfrm_policy. | ||
| 823 | * Authorize deletion of xp->security. | ||
| 821 | * @xfrm_state_alloc_security: | 824 | * @xfrm_state_alloc_security: |
| 822 | * @x contains the xfrm_state being added to the Security Association | 825 | * @x contains the xfrm_state being added to the Security Association |
| 823 | * Database by the XFRM system. | 826 | * Database by the XFRM system. |
| 824 | * @sec_ctx contains the security context information being provided by | 827 | * @sec_ctx contains the security context information being provided by |
| 825 | * the user-level SA generation program (e.g., setkey or racoon). | 828 | * the user-level SA generation program (e.g., setkey or racoon). |
| 826 | * Allocate a security structure to the x->sel.security field. The | 829 | * Allocate a security structure to the x->security field. The |
| 827 | * security field is initialized to NULL when the xfrm_state is | 830 | * security field is initialized to NULL when the xfrm_state is |
| 828 | * allocated. | 831 | * allocated. |
| 829 | * Return 0 if operation was successful (memory to allocate, legal context). | 832 | * Return 0 if operation was successful (memory to allocate, legal context). |
| 830 | * @xfrm_state_free_security: | 833 | * @xfrm_state_free_security: |
| 831 | * @x contains the xfrm_state. | 834 | * @x contains the xfrm_state. |
| 832 | * Deallocate x>sel.security. | 835 | * Deallocate x->security. |
| 836 | * @xfrm_state_delete_security: | ||
| 837 | * @x contains the xfrm_state. | ||
| 838 | * Authorize deletion of x->security. | ||
| 833 | * @xfrm_policy_lookup: | 839 | * @xfrm_policy_lookup: |
| 834 | * @xp contains the xfrm_policy for which the access control is being | 840 | * @xp contains the xfrm_policy for which the access control is being |
| 835 | * checked. | 841 | * checked. |
| @@ -1298,8 +1304,10 @@ struct security_operations { | |||
| 1298 | int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx); | 1304 | int (*xfrm_policy_alloc_security) (struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx); |
| 1299 | int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new); | 1305 | int (*xfrm_policy_clone_security) (struct xfrm_policy *old, struct xfrm_policy *new); |
| 1300 | void (*xfrm_policy_free_security) (struct xfrm_policy *xp); | 1306 | void (*xfrm_policy_free_security) (struct xfrm_policy *xp); |
| 1307 | int (*xfrm_policy_delete_security) (struct xfrm_policy *xp); | ||
| 1301 | int (*xfrm_state_alloc_security) (struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx); | 1308 | int (*xfrm_state_alloc_security) (struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx); |
| 1302 | void (*xfrm_state_free_security) (struct xfrm_state *x); | 1309 | void (*xfrm_state_free_security) (struct xfrm_state *x); |
| 1310 | int (*xfrm_state_delete_security) (struct xfrm_state *x); | ||
| 1303 | int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 sk_sid, u8 dir); | 1311 | int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 sk_sid, u8 dir); |
| 1304 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ | 1312 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ |
| 1305 | 1313 | ||
| @@ -2934,11 +2942,21 @@ static inline void security_xfrm_policy_free(struct xfrm_policy *xp) | |||
| 2934 | security_ops->xfrm_policy_free_security(xp); | 2942 | security_ops->xfrm_policy_free_security(xp); |
| 2935 | } | 2943 | } |
| 2936 | 2944 | ||
| 2945 | static inline int security_xfrm_policy_delete(struct xfrm_policy *xp) | ||
| 2946 | { | ||
| 2947 | return security_ops->xfrm_policy_delete_security(xp); | ||
| 2948 | } | ||
| 2949 | |||
| 2937 | static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) | 2950 | static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) |
| 2938 | { | 2951 | { |
| 2939 | return security_ops->xfrm_state_alloc_security(x, sec_ctx); | 2952 | return security_ops->xfrm_state_alloc_security(x, sec_ctx); |
| 2940 | } | 2953 | } |
| 2941 | 2954 | ||
| 2955 | static inline int security_xfrm_state_delete(struct xfrm_state *x) | ||
| 2956 | { | ||
| 2957 | return security_ops->xfrm_state_delete_security(x); | ||
| 2958 | } | ||
| 2959 | |||
| 2942 | static inline void security_xfrm_state_free(struct xfrm_state *x) | 2960 | static inline void security_xfrm_state_free(struct xfrm_state *x) |
| 2943 | { | 2961 | { |
| 2944 | security_ops->xfrm_state_free_security(x); | 2962 | security_ops->xfrm_state_free_security(x); |
| @@ -2963,6 +2981,11 @@ static inline void security_xfrm_policy_free(struct xfrm_policy *xp) | |||
| 2963 | { | 2981 | { |
| 2964 | } | 2982 | } |
| 2965 | 2983 | ||
| 2984 | static inline int security_xfrm_policy_delete(struct xfrm_policy *xp) | ||
| 2985 | { | ||
| 2986 | return 0; | ||
| 2987 | } | ||
| 2988 | |||
| 2966 | static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) | 2989 | static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) |
| 2967 | { | 2990 | { |
| 2968 | return 0; | 2991 | return 0; |
| @@ -2972,6 +2995,11 @@ static inline void security_xfrm_state_free(struct xfrm_state *x) | |||
| 2972 | { | 2995 | { |
| 2973 | } | 2996 | } |
| 2974 | 2997 | ||
| 2998 | static inline int security_xfrm_state_delete(struct xfrm_policy *xp) | ||
| 2999 | { | ||
| 3000 | return 0; | ||
| 3001 | } | ||
| 3002 | |||
| 2975 | static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) | 3003 | static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) |
| 2976 | { | 3004 | { |
| 2977 | return 0; | 3005 | return 0; |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 859582275cab..d5e2121ea207 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
| @@ -1454,21 +1454,23 @@ static int pfkey_delete(struct sock *sk, struct sk_buff *skb, struct sadb_msg *h | |||
| 1454 | if (x == NULL) | 1454 | if (x == NULL) |
| 1455 | return -ESRCH; | 1455 | return -ESRCH; |
| 1456 | 1456 | ||
| 1457 | if ((err = security_xfrm_state_delete(x))) | ||
| 1458 | goto out; | ||
| 1459 | |||
| 1457 | if (xfrm_state_kern(x)) { | 1460 | if (xfrm_state_kern(x)) { |
| 1458 | xfrm_state_put(x); | 1461 | err = -EPERM; |
| 1459 | return -EPERM; | 1462 | goto out; |
| 1460 | } | 1463 | } |
| 1461 | 1464 | ||
| 1462 | err = xfrm_state_delete(x); | 1465 | err = xfrm_state_delete(x); |
| 1463 | if (err < 0) { | 1466 | if (err < 0) |
| 1464 | xfrm_state_put(x); | 1467 | goto out; |
| 1465 | return err; | ||
| 1466 | } | ||
| 1467 | 1468 | ||
| 1468 | c.seq = hdr->sadb_msg_seq; | 1469 | c.seq = hdr->sadb_msg_seq; |
| 1469 | c.pid = hdr->sadb_msg_pid; | 1470 | c.pid = hdr->sadb_msg_pid; |
| 1470 | c.event = XFRM_MSG_DELSA; | 1471 | c.event = XFRM_MSG_DELSA; |
| 1471 | km_state_notify(x, &c); | 1472 | km_state_notify(x, &c); |
| 1473 | out: | ||
| 1472 | xfrm_state_put(x); | 1474 | xfrm_state_put(x); |
| 1473 | 1475 | ||
| 1474 | return err; | 1476 | return err; |
| @@ -2274,11 +2276,14 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, struct sadb_msg | |||
| 2274 | 2276 | ||
| 2275 | err = 0; | 2277 | err = 0; |
| 2276 | 2278 | ||
| 2279 | if ((err = security_xfrm_policy_delete(xp))) | ||
| 2280 | goto out; | ||
| 2277 | c.seq = hdr->sadb_msg_seq; | 2281 | c.seq = hdr->sadb_msg_seq; |
| 2278 | c.pid = hdr->sadb_msg_pid; | 2282 | c.pid = hdr->sadb_msg_pid; |
| 2279 | c.event = XFRM_MSG_DELPOLICY; | 2283 | c.event = XFRM_MSG_DELPOLICY; |
| 2280 | km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c); | 2284 | km_policy_notify(xp, pol->sadb_x_policy_dir-1, &c); |
| 2281 | 2285 | ||
| 2286 | out: | ||
| 2282 | xfrm_pol_put(xp); | 2287 | xfrm_pol_put(xp); |
| 2283 | return err; | 2288 | return err; |
| 2284 | } | 2289 | } |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 81d1005830f4..a3733d2db3ba 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -427,23 +427,25 @@ static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) | |||
| 427 | if (x == NULL) | 427 | if (x == NULL) |
| 428 | return -ESRCH; | 428 | return -ESRCH; |
| 429 | 429 | ||
| 430 | if (err = security_xfrm_state_delete(x)) | ||
| 431 | goto out; | ||
| 432 | |||
| 430 | if (xfrm_state_kern(x)) { | 433 | if (xfrm_state_kern(x)) { |
| 431 | xfrm_state_put(x); | 434 | err = -EPERM; |
| 432 | return -EPERM; | 435 | goto out; |
| 433 | } | 436 | } |
| 434 | 437 | ||
| 435 | err = xfrm_state_delete(x); | 438 | err = xfrm_state_delete(x); |
| 436 | if (err < 0) { | 439 | if (err < 0) |
| 437 | xfrm_state_put(x); | 440 | goto out; |
| 438 | return err; | ||
| 439 | } | ||
| 440 | 441 | ||
| 441 | c.seq = nlh->nlmsg_seq; | 442 | c.seq = nlh->nlmsg_seq; |
| 442 | c.pid = nlh->nlmsg_pid; | 443 | c.pid = nlh->nlmsg_pid; |
| 443 | c.event = nlh->nlmsg_type; | 444 | c.event = nlh->nlmsg_type; |
| 444 | km_state_notify(x, &c); | 445 | km_state_notify(x, &c); |
| 445 | xfrm_state_put(x); | ||
| 446 | 446 | ||
| 447 | out: | ||
| 448 | xfrm_state_put(x); | ||
| 447 | return err; | 449 | return err; |
| 448 | } | 450 | } |
| 449 | 451 | ||
| @@ -1055,6 +1057,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
| 1055 | MSG_DONTWAIT); | 1057 | MSG_DONTWAIT); |
| 1056 | } | 1058 | } |
| 1057 | } else { | 1059 | } else { |
| 1060 | if (err = security_xfrm_policy_delete(xp)) | ||
| 1061 | goto out; | ||
| 1058 | c.data.byid = p->index; | 1062 | c.data.byid = p->index; |
| 1059 | c.event = nlh->nlmsg_type; | 1063 | c.event = nlh->nlmsg_type; |
| 1060 | c.seq = nlh->nlmsg_seq; | 1064 | c.seq = nlh->nlmsg_seq; |
| @@ -1064,6 +1068,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr | |||
| 1064 | 1068 | ||
| 1065 | xfrm_pol_put(xp); | 1069 | xfrm_pol_put(xp); |
| 1066 | 1070 | ||
| 1071 | out: | ||
| 1067 | return err; | 1072 | return err; |
| 1068 | } | 1073 | } |
| 1069 | 1074 | ||
diff --git a/security/dummy.c b/security/dummy.c index 8ccccccc12ac..64f6da0f422e 100644 --- a/security/dummy.c +++ b/security/dummy.c | |||
| @@ -810,6 +810,11 @@ static void dummy_xfrm_policy_free_security(struct xfrm_policy *xp) | |||
| 810 | { | 810 | { |
| 811 | } | 811 | } |
| 812 | 812 | ||
| 813 | static int dummy_xfrm_policy_delete_security(struct xfrm_policy *xp) | ||
| 814 | { | ||
| 815 | return 0; | ||
| 816 | } | ||
| 817 | |||
| 813 | static int dummy_xfrm_state_alloc_security(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) | 818 | static int dummy_xfrm_state_alloc_security(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) |
| 814 | { | 819 | { |
| 815 | return 0; | 820 | return 0; |
| @@ -819,6 +824,11 @@ static void dummy_xfrm_state_free_security(struct xfrm_state *x) | |||
| 819 | { | 824 | { |
| 820 | } | 825 | } |
| 821 | 826 | ||
| 827 | static int dummy_xfrm_state_delete_security(struct xfrm_state *x) | ||
| 828 | { | ||
| 829 | return 0; | ||
| 830 | } | ||
| 831 | |||
| 822 | static int dummy_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) | 832 | static int dummy_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) |
| 823 | { | 833 | { |
| 824 | return 0; | 834 | return 0; |
| @@ -1024,8 +1034,10 @@ void security_fixup_ops (struct security_operations *ops) | |||
| 1024 | set_to_dummy_if_null(ops, xfrm_policy_alloc_security); | 1034 | set_to_dummy_if_null(ops, xfrm_policy_alloc_security); |
| 1025 | set_to_dummy_if_null(ops, xfrm_policy_clone_security); | 1035 | set_to_dummy_if_null(ops, xfrm_policy_clone_security); |
| 1026 | set_to_dummy_if_null(ops, xfrm_policy_free_security); | 1036 | set_to_dummy_if_null(ops, xfrm_policy_free_security); |
| 1037 | set_to_dummy_if_null(ops, xfrm_policy_delete_security); | ||
| 1027 | set_to_dummy_if_null(ops, xfrm_state_alloc_security); | 1038 | set_to_dummy_if_null(ops, xfrm_state_alloc_security); |
| 1028 | set_to_dummy_if_null(ops, xfrm_state_free_security); | 1039 | set_to_dummy_if_null(ops, xfrm_state_free_security); |
| 1040 | set_to_dummy_if_null(ops, xfrm_state_delete_security); | ||
| 1029 | set_to_dummy_if_null(ops, xfrm_policy_lookup); | 1041 | set_to_dummy_if_null(ops, xfrm_policy_lookup); |
| 1030 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ | 1042 | #endif /* CONFIG_SECURITY_NETWORK_XFRM */ |
| 1031 | #ifdef CONFIG_KEYS | 1043 | #ifdef CONFIG_KEYS |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 90b4cdc0c948..cf7b62ca886a 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -4374,8 +4374,10 @@ static struct security_operations selinux_ops = { | |||
| 4374 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, | 4374 | .xfrm_policy_alloc_security = selinux_xfrm_policy_alloc, |
| 4375 | .xfrm_policy_clone_security = selinux_xfrm_policy_clone, | 4375 | .xfrm_policy_clone_security = selinux_xfrm_policy_clone, |
| 4376 | .xfrm_policy_free_security = selinux_xfrm_policy_free, | 4376 | .xfrm_policy_free_security = selinux_xfrm_policy_free, |
| 4377 | .xfrm_policy_delete_security = selinux_xfrm_policy_delete, | ||
| 4377 | .xfrm_state_alloc_security = selinux_xfrm_state_alloc, | 4378 | .xfrm_state_alloc_security = selinux_xfrm_state_alloc, |
| 4378 | .xfrm_state_free_security = selinux_xfrm_state_free, | 4379 | .xfrm_state_free_security = selinux_xfrm_state_free, |
| 4380 | .xfrm_state_delete_security = selinux_xfrm_state_delete, | ||
| 4379 | .xfrm_policy_lookup = selinux_xfrm_policy_lookup, | 4381 | .xfrm_policy_lookup = selinux_xfrm_policy_lookup, |
| 4380 | #endif | 4382 | #endif |
| 4381 | }; | 4383 | }; |
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h index c10f1fc41502..f0f4e480ff99 100644 --- a/security/selinux/include/xfrm.h +++ b/security/selinux/include/xfrm.h | |||
| @@ -9,8 +9,10 @@ | |||
| 9 | int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx); | 9 | int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx); |
| 10 | int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new); | 10 | int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new); |
| 11 | void selinux_xfrm_policy_free(struct xfrm_policy *xp); | 11 | void selinux_xfrm_policy_free(struct xfrm_policy *xp); |
| 12 | int selinux_xfrm_policy_delete(struct xfrm_policy *xp); | ||
| 12 | int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx); | 13 | int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx); |
| 13 | void selinux_xfrm_state_free(struct xfrm_state *x); | 14 | void selinux_xfrm_state_free(struct xfrm_state *x); |
| 15 | int selinux_xfrm_state_delete(struct xfrm_state *x); | ||
| 14 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir); | 16 | int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir); |
| 15 | 17 | ||
| 16 | /* | 18 | /* |
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index abe99d881376..0e24df41099f 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
| @@ -132,10 +132,7 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_us | |||
| 132 | goto out; | 132 | goto out; |
| 133 | 133 | ||
| 134 | /* | 134 | /* |
| 135 | * Does the subject have permission to set security or permission to | 135 | * Does the subject have permission to set security context? |
| 136 | * do the relabel? | ||
| 137 | * Must be permitted to relabel from default socket type (process type) | ||
| 138 | * to specified context | ||
| 139 | */ | 136 | */ |
| 140 | rc = avc_has_perm(tsec->sid, ctx->ctx_sid, | 137 | rc = avc_has_perm(tsec->sid, ctx->ctx_sid, |
| 141 | SECCLASS_ASSOCIATION, | 138 | SECCLASS_ASSOCIATION, |
| @@ -201,6 +198,23 @@ void selinux_xfrm_policy_free(struct xfrm_policy *xp) | |||
| 201 | } | 198 | } |
| 202 | 199 | ||
| 203 | /* | 200 | /* |
| 201 | * LSM hook implementation that authorizes deletion of labeled policies. | ||
| 202 | */ | ||
| 203 | int selinux_xfrm_policy_delete(struct xfrm_policy *xp) | ||
| 204 | { | ||
| 205 | struct task_security_struct *tsec = current->security; | ||
| 206 | struct xfrm_sec_ctx *ctx = xp->security; | ||
| 207 | int rc = 0; | ||
| 208 | |||
| 209 | if (ctx) | ||
| 210 | rc = avc_has_perm(tsec->sid, ctx->ctx_sid, | ||
| 211 | SECCLASS_ASSOCIATION, | ||
| 212 | ASSOCIATION__SETCONTEXT, NULL); | ||
| 213 | |||
| 214 | return rc; | ||
| 215 | } | ||
| 216 | |||
| 217 | /* | ||
| 204 | * LSM hook implementation that allocs and transfers sec_ctx spec to | 218 | * LSM hook implementation that allocs and transfers sec_ctx spec to |
| 205 | * xfrm_state. | 219 | * xfrm_state. |
| 206 | */ | 220 | */ |
| @@ -292,6 +306,23 @@ u32 selinux_socket_getpeer_dgram(struct sk_buff *skb) | |||
| 292 | return SECSID_NULL; | 306 | return SECSID_NULL; |
| 293 | } | 307 | } |
| 294 | 308 | ||
| 309 | /* | ||
| 310 | * LSM hook implementation that authorizes deletion of labeled SAs. | ||
| 311 | */ | ||
| 312 | int selinux_xfrm_state_delete(struct xfrm_state *x) | ||
| 313 | { | ||
| 314 | struct task_security_struct *tsec = current->security; | ||
| 315 | struct xfrm_sec_ctx *ctx = x->security; | ||
| 316 | int rc = 0; | ||
| 317 | |||
| 318 | if (ctx) | ||
| 319 | rc = avc_has_perm(tsec->sid, ctx->ctx_sid, | ||
| 320 | SECCLASS_ASSOCIATION, | ||
| 321 | ASSOCIATION__SETCONTEXT, NULL); | ||
| 322 | |||
| 323 | return rc; | ||
| 324 | } | ||
| 325 | |||
| 295 | /* | 326 | /* |
| 296 | * LSM hook that controls access to unlabelled packets. If | 327 | * LSM hook that controls access to unlabelled packets. If |
| 297 | * a xfrm_state is authorizable (defined by macro) then it was | 328 | * a xfrm_state is authorizable (defined by macro) then it was |
