diff options
Diffstat (limited to 'security/selinux/xfrm.c')
-rw-r--r-- | security/selinux/xfrm.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index b2af7ca496c1..dfab6c886698 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c | |||
@@ -225,6 +225,74 @@ void selinux_xfrm_state_free(struct xfrm_state *x) | |||
225 | } | 225 | } |
226 | 226 | ||
227 | /* | 227 | /* |
228 | * SELinux internal function to retrieve the context of a connected | ||
229 | * (sk->sk_state == TCP_ESTABLISHED) TCP socket based on its security | ||
230 | * association used to connect to the remote socket. | ||
231 | * | ||
232 | * Retrieve via getsockopt SO_PEERSEC. | ||
233 | */ | ||
234 | u32 selinux_socket_getpeer_stream(struct sock *sk) | ||
235 | { | ||
236 | struct dst_entry *dst, *dst_test; | ||
237 | u32 peer_sid = SECSID_NULL; | ||
238 | |||
239 | if (sk->sk_state != TCP_ESTABLISHED) | ||
240 | goto out; | ||
241 | |||
242 | dst = sk_dst_get(sk); | ||
243 | if (!dst) | ||
244 | goto out; | ||
245 | |||
246 | for (dst_test = dst; dst_test != 0; | ||
247 | dst_test = dst_test->child) { | ||
248 | struct xfrm_state *x = dst_test->xfrm; | ||
249 | |||
250 | if (x && selinux_authorizable_xfrm(x)) { | ||
251 | struct xfrm_sec_ctx *ctx = x->security; | ||
252 | peer_sid = ctx->ctx_sid; | ||
253 | break; | ||
254 | } | ||
255 | } | ||
256 | dst_release(dst); | ||
257 | |||
258 | out: | ||
259 | return peer_sid; | ||
260 | } | ||
261 | |||
262 | /* | ||
263 | * SELinux internal function to retrieve the context of a UDP packet | ||
264 | * based on its security association used to connect to the remote socket. | ||
265 | * | ||
266 | * Retrieve via setsockopt IP_PASSSEC and recvmsg with control message | ||
267 | * type SCM_SECURITY. | ||
268 | */ | ||
269 | u32 selinux_socket_getpeer_dgram(struct sk_buff *skb) | ||
270 | { | ||
271 | struct sec_path *sp; | ||
272 | |||
273 | if (skb == NULL) | ||
274 | return SECSID_NULL; | ||
275 | |||
276 | if (skb->sk->sk_protocol != IPPROTO_UDP) | ||
277 | return SECSID_NULL; | ||
278 | |||
279 | sp = skb->sp; | ||
280 | if (sp) { | ||
281 | int i; | ||
282 | |||
283 | for (i = sp->len-1; i >= 0; i--) { | ||
284 | struct xfrm_state *x = sp->x[i].xvec; | ||
285 | if (selinux_authorizable_xfrm(x)) { | ||
286 | struct xfrm_sec_ctx *ctx = x->security; | ||
287 | return ctx->ctx_sid; | ||
288 | } | ||
289 | } | ||
290 | } | ||
291 | |||
292 | return SECSID_NULL; | ||
293 | } | ||
294 | |||
295 | /* | ||
228 | * LSM hook that controls access to unlabelled packets. If | 296 | * LSM hook that controls access to unlabelled packets. If |
229 | * a xfrm_state is authorizable (defined by macro) then it was | 297 | * a xfrm_state is authorizable (defined by macro) then it was |
230 | * already authorized by the IPSec process. If not, then | 298 | * already authorized by the IPSec process. If not, then |