X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=security%2Fselinux%2Fxfrm.c;h=abe99d8813765a977405de8246d42f9597c34341;hb=376bd9cb357ec945ac893feaeb63af7370a6e70b;hp=c4d87d4dca7b3cd3eea2baf0fc8bf2828cfe6d84;hpb=1cb9e8e01d2c73184e2074f37cd155b3c4fdaae6;p=powerpc.git diff --git a/security/selinux/xfrm.c b/security/selinux/xfrm.c index c4d87d4dca..abe99d8813 100644 --- a/security/selinux/xfrm.c +++ b/security/selinux/xfrm.c @@ -137,22 +137,16 @@ static int selinux_xfrm_sec_ctx_alloc(struct xfrm_sec_ctx **ctxp, struct xfrm_us * Must be permitted to relabel from default socket type (process type) * to specified context */ - rc = avc_has_perm(tsec->sid, tsec->sid, - SECCLASS_ASSOCIATION, - ASSOCIATION__RELABELFROM, NULL); - if (rc) - goto out; - rc = avc_has_perm(tsec->sid, ctx->ctx_sid, SECCLASS_ASSOCIATION, - ASSOCIATION__RELABELTO, NULL); + ASSOCIATION__SETCONTEXT, NULL); if (rc) goto out; return rc; out: - *ctxp = 0; + *ctxp = NULL; kfree(ctx); return rc; } @@ -230,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 @@ -252,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;