X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=security%2Fselinux%2Fxfrm.c;h=abe99d8813765a977405de8246d42f9597c34341;hb=376bd9cb357ec945ac893feaeb63af7370a6e70b;hp=b2af7ca496c1c925aa75c678565aa07b22559461;hpb=b8c475be7bf9b79e6417c08d7a921b2e8cb04258;p=powerpc.git diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index b2af7ca496..abe99d8813 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c @@ -224,6 +224,74 @@ void selinux_xfrm_state_free(struct xfrm_state *x) kfree(ctx); } +/* + * SELinux internal function to retrieve the context of a connected + * (sk->sk_state == TCP_ESTABLISHED) TCP socket based on its security + * association used to connect to the remote socket. + * + * Retrieve via getsockopt SO_PEERSEC. + */ +u32 selinux_socket_getpeer_stream(struct sock *sk) +{ + struct dst_entry *dst, *dst_test; + u32 peer_sid = SECSID_NULL; + + if (sk->sk_state != TCP_ESTABLISHED) + goto out; + + dst = sk_dst_get(sk); + if (!dst) + goto out; + + for (dst_test = dst; dst_test != 0; + dst_test = dst_test->child) { + struct xfrm_state *x = dst_test->xfrm; + + if (x && selinux_authorizable_xfrm(x)) { + struct xfrm_sec_ctx *ctx = x->security; + peer_sid = ctx->ctx_sid; + break; + } + } + dst_release(dst); + +out: + return peer_sid; +} + +/* + * SELinux internal function to retrieve the context of a UDP packet + * based on its security association used to connect to the remote socket. + * + * Retrieve via setsockopt IP_PASSSEC and recvmsg with control message + * type SCM_SECURITY. + */ +u32 selinux_socket_getpeer_dgram(struct sk_buff *skb) +{ + struct sec_path *sp; + + if (skb == NULL) + return SECSID_NULL; + + if (skb->sk->sk_protocol != IPPROTO_UDP) + return SECSID_NULL; + + sp = skb->sp; + if (sp) { + int i; + + for (i = sp->len-1; i >= 0; i--) { + struct xfrm_state *x = sp->xvec[i]; + if (selinux_authorizable_xfrm(x)) { + struct xfrm_sec_ctx *ctx = x->security; + return ctx->ctx_sid; + } + } + } + + return SECSID_NULL; +} + /* * LSM hook that controls access to unlabelled packets. If * a xfrm_state is authorizable (defined by macro) then it was @@ -246,7 +314,7 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_sid, struct sk_buff *skb) * Only need to verify the existence of an authorizable sp. */ for (i = 0; i < sp->len; i++) { - struct xfrm_state *x = sp->x[i].xvec; + struct xfrm_state *x = sp->xvec[i]; if (x && selinux_authorizable_xfrm(x)) goto accept;