aboutsummaryrefslogtreecommitdiffstats
path: root/security
diff options
context:
space:
mode:
Diffstat (limited to 'security')
-rw-r--r--security/dummy.c3
-rw-r--r--security/selinux/include/xfrm.h3
-rw-r--r--security/selinux/xfrm.c53
3 files changed, 45 insertions, 14 deletions
diff --git a/security/dummy.c b/security/dummy.c
index aeee70565509..43874c1e6e23 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -881,7 +881,8 @@ static int dummy_xfrm_state_pol_flow_match(struct xfrm_state *x,
881 return 1; 881 return 1;
882} 882}
883 883
884static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) 884static int dummy_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm,
885 struct xfrm_policy *xp)
885{ 886{
886 return 1; 887 return 1;
887} 888}
diff --git a/security/selinux/include/xfrm.h b/security/selinux/include/xfrm.h
index 81eb59890162..526b28019aca 100644
--- a/security/selinux/include/xfrm.h
+++ b/security/selinux/include/xfrm.h
@@ -19,7 +19,8 @@ int selinux_xfrm_state_delete(struct xfrm_state *x);
19int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir); 19int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir);
20int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, 20int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x,
21 struct xfrm_policy *xp, struct flowi *fl); 21 struct xfrm_policy *xp, struct flowi *fl);
22int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm); 22int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm,
23 struct xfrm_policy *xp);
23 24
24 25
25/* 26/*
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c
index 3e742b850af6..675b995a67c3 100644
--- a/security/selinux/xfrm.c
+++ b/security/selinux/xfrm.c
@@ -77,8 +77,8 @@ static inline int selinux_authorizable_xfrm(struct xfrm_state *x)
77 */ 77 */
78int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir) 78int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir)
79{ 79{
80 int rc = 0; 80 int rc;
81 u32 sel_sid = SECINITSID_UNLABELED; 81 u32 sel_sid;
82 struct xfrm_sec_ctx *ctx; 82 struct xfrm_sec_ctx *ctx;
83 83
84 /* Context sid is either set to label or ANY_ASSOC */ 84 /* Context sid is either set to label or ANY_ASSOC */
@@ -88,11 +88,21 @@ int selinux_xfrm_policy_lookup(struct xfrm_policy *xp, u32 fl_secid, u8 dir)
88 88
89 sel_sid = ctx->ctx_sid; 89 sel_sid = ctx->ctx_sid;
90 } 90 }
91 else
92 /*
93 * All flows should be treated as polmatch'ing an
94 * otherwise applicable "non-labeled" policy. This
95 * would prevent inadvertent "leaks".
96 */
97 return 0;
91 98
92 rc = avc_has_perm(fl_secid, sel_sid, SECCLASS_ASSOCIATION, 99 rc = avc_has_perm(fl_secid, sel_sid, SECCLASS_ASSOCIATION,
93 ASSOCIATION__POLMATCH, 100 ASSOCIATION__POLMATCH,
94 NULL); 101 NULL);
95 102
103 if (rc == -EACCES)
104 rc = -ESRCH;
105
96 return rc; 106 return rc;
97} 107}
98 108
@@ -108,15 +118,20 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
108 u32 pol_sid; 118 u32 pol_sid;
109 int err; 119 int err;
110 120
111 if (x->security) 121 if (xp->security) {
112 state_sid = x->security->ctx_sid; 122 if (!x->security)
113 else 123 /* unlabeled SA and labeled policy can't match */
114 state_sid = SECINITSID_UNLABELED; 124 return 0;
115 125 else
116 if (xp->security) 126 state_sid = x->security->ctx_sid;
117 pol_sid = xp->security->ctx_sid; 127 pol_sid = xp->security->ctx_sid;
118 else 128 } else
119 pol_sid = SECINITSID_UNLABELED; 129 if (x->security)
130 /* unlabeled policy and labeled SA can't match */
131 return 0;
132 else
133 /* unlabeled policy and unlabeled SA match all flows */
134 return 1;
120 135
121 err = avc_has_perm(state_sid, pol_sid, SECCLASS_ASSOCIATION, 136 err = avc_has_perm(state_sid, pol_sid, SECCLASS_ASSOCIATION,
122 ASSOCIATION__POLMATCH, 137 ASSOCIATION__POLMATCH,
@@ -125,7 +140,11 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
125 if (err) 140 if (err)
126 return 0; 141 return 0;
127 142
128 return selinux_xfrm_flow_state_match(fl, x); 143 err = avc_has_perm(fl->secid, state_sid, SECCLASS_ASSOCIATION,
144 ASSOCIATION__SENDTO,
145 NULL)? 0:1;
146
147 return err;
129} 148}
130 149
131/* 150/*
@@ -133,12 +152,22 @@ int selinux_xfrm_state_pol_flow_match(struct xfrm_state *x, struct xfrm_policy *
133 * can use a given security association. 152 * can use a given security association.
134 */ 153 */
135 154
136int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm) 155int selinux_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm,
156 struct xfrm_policy *xp)
137{ 157{
138 int rc = 0; 158 int rc = 0;
139 u32 sel_sid = SECINITSID_UNLABELED; 159 u32 sel_sid = SECINITSID_UNLABELED;
140 struct xfrm_sec_ctx *ctx; 160 struct xfrm_sec_ctx *ctx;
141 161
162 if (!xp->security)
163 if (!xfrm->security)
164 return 1;
165 else
166 return 0;
167 else
168 if (!xfrm->security)
169 return 0;
170
142 /* Context sid is either set to label or ANY_ASSOC */ 171 /* Context sid is either set to label or ANY_ASSOC */
143 if ((ctx = xfrm->security)) { 172 if ((ctx = xfrm->security)) {
144 if (!selinux_authorizable_ctx(ctx)) 173 if (!selinux_authorizable_ctx(ctx))