* 2. Emulating a reasonable SO_PEERSEC across machines
* 3. Testing addition of sk_policy's with security context via setsockopt
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
goto out;
/*
- * Does the subject have permission to set security context?
+ * Does the subject have permission to set security or permission to
+ * do the relabel?
+ * Must be permitted to relabel from default socket type (process type)
+ * to specified context
*/
rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
SECCLASS_ASSOCIATION,
kfree(ctx);
}
-/*
- * LSM hook implementation that authorizes deletion of labeled policies.
- */
-int selinux_xfrm_policy_delete(struct xfrm_policy *xp)
-{
- struct task_security_struct *tsec = current->security;
- struct xfrm_sec_ctx *ctx = xp->security;
- int rc = 0;
-
- if (ctx)
- rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
- SECCLASS_ASSOCIATION,
- ASSOCIATION__SETCONTEXT, NULL);
-
- return rc;
-}
-
/*
* LSM hook implementation that allocs and transfers sec_ctx spec to
* xfrm_state.
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 implementation that authorizes deletion of labeled SAs.
- */
-int selinux_xfrm_state_delete(struct xfrm_state *x)
-{
- struct task_security_struct *tsec = current->security;
- struct xfrm_sec_ctx *ctx = x->security;
- int rc = 0;
-
- if (ctx)
- rc = avc_has_perm(tsec->sid, ctx->ctx_sid,
- SECCLASS_ASSOCIATION,
- ASSOCIATION__SETCONTEXT, NULL);
-
- return rc;
-}
-
/*
* LSM hook that controls access to unlabelled packets. If
* a xfrm_state is authorizable (defined by macro) then it was
* Only need to verify the existence of an authorizable sp.
*/
for (i = 0; i < sp->len; i++) {
- struct xfrm_state *x = sp->xvec[i];
+ struct xfrm_state *x = sp->x[i].xvec;
if (x && selinux_authorizable_xfrm(x))
goto accept;
struct xfrm_state *x = dst_test->xfrm;
if (x && selinux_authorizable_xfrm(x))
- goto out;
+ goto accept;
}
}
rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
ASSOCIATION__SENDTO, NULL);
-out:
- return rc;
+ if (rc)
+ goto drop;
+
+accept:
+ return NF_ACCEPT;
+
+drop:
+ return NF_DROP;
}