aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/security.h40
-rw-r--r--net/key/af_key.c17
-rw-r--r--net/xfrm/xfrm_user.c19
-rw-r--r--security/dummy.c12
-rw-r--r--security/selinux/hooks.c2
-rw-r--r--security/selinux/include/xfrm.h2
-rw-r--r--security/selinux/xfrm.c39
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
2945static inline int security_xfrm_policy_delete(struct xfrm_policy *xp)
2946{
2947 return security_ops->xfrm_policy_delete_security(xp);
2948}
2949
2937static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) 2950static 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
2955static inline int security_xfrm_state_delete(struct xfrm_state *x)
2956{
2957 return security_ops->xfrm_state_delete_security(x);
2958}
2959
2942static inline void security_xfrm_state_free(struct xfrm_state *x) 2960static 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
2984static inline int security_xfrm_policy_delete(struct xfrm_policy *xp)
2985{
2986 return 0;
2987}
2988
2966static inline int security_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) 2989static 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
2998static inline int security_xfrm_state_delete(struct xfrm_policy *xp)
2999{
3000 return 0;
3001}
3002
2975static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) 3003static 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);
1473out:
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
2286out:
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
447out:
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
1071out:
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
813static int dummy_xfrm_policy_delete_security(struct xfrm_policy *xp)
814{
815 return 0;
816}
817
813static int dummy_xfrm_state_alloc_security(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx) 818static 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
827static int dummy_xfrm_state_delete_security(struct xfrm_state *x)
828{
829 return 0;
830}
831
822static int dummy_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir) 832static 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 @@
9int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx); 9int selinux_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm_user_sec_ctx *sec_ctx);
10int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new); 10int selinux_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new);
11void selinux_xfrm_policy_free(struct xfrm_policy *xp); 11void selinux_xfrm_policy_free(struct xfrm_policy *xp);
12int selinux_xfrm_policy_delete(struct xfrm_policy *xp);
12int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx); 13int selinux_xfrm_state_alloc(struct xfrm_state *x, struct xfrm_user_sec_ctx *sec_ctx);
13void selinux_xfrm_state_free(struct xfrm_state *x); 14void selinux_xfrm_state_free(struct xfrm_state *x);
15int selinux_xfrm_state_delete(struct xfrm_state *x);
14int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid, u8 dir); 16int 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 */
203int 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 */
312int 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