Stephen Smalley wrote:
On Wed, 2006-05-03 at 15:53 -0400, Paul Moore wrote:
diff -purN kernel-2.6.16/security/selinux/hooks.c
kernel-2.6.16-cipso_05032006/security/selinux/hooks.c
--- kernel-2.6.16/security/selinux/hooks.c 2006-05-02 10:41:02.000000000
-0400
+++ kernel-2.6.16-cipso_05032006/security/selinux/hooks.c 2006-05-02
14:19:13.000000000 -0400
@@ -3304,10 +3317,26 @@ static int selinux_socket_sock_rcv_skb(s
err = avc_has_perm(sock_sid, port_sid,
sock_class, recv_perm, &ad);
+ if (err)
+ goto out;
}
- if (!err)
- err = selinux_xfrm_sock_rcv_skb(sock_sid, skb);
+ /* PM - discuss these changes on the list */
+ err = selinux_xfrm_sock_rcv_skb(sock_sid, skb);
+ if (err == 0)
+ goto out;
+
+ err = security_netlbl_sid(skb, &netlbl_sid);
+ if (err)
+ goto out;
+
+ err = avc_has_perm(sock_sid,
+ netlbl_sid,
+ SECCLASS_SOCKET,
+ SOCKET__RECV_MSG,
+ &ad);
+ if (err)
+ netlbl_skbuff_err(skb, err);
We'll need to resolve how this should interact with the security marking
patches under development by James, see the RFC at:
http://marc.theaimsgroup.com/?l=linux-netdev&m=114516429530333&w=2
Patches should be forthcoming soon.
Those are intended to replace the existing SELinux netif/node/port
per-packet checks with a single per-packet check on each send/receive
based on the secmark assigned via iptables rules. Exactly how that
should interact with both the implicit packet labeling via IPSEC and
with your NetLabel code isn't entirely clear to me; ideally, they could
all leverage the secmark functionality and everything could devolve to a
single check on send/recv based on the secmark.
Ever since the SELinux Developers Summit this year I knew this was going
to be an issue, hence my comment in the code above. At this point I
don't have a clear enough picture of all three approaches to have a very
strong opinion. Although, I'll be honest here, I'll go with whatever
approach gets CIPSO support into the kernel.
One of my main design goals for NetLabel have been to minimize the
intrustion into the kernel network stack and the SELinux code. As a
result I think the NetLabel bits have turned out to be fairly generic in
the sense that I *believe* it could support many different types of
packet labeling based on either explicit tags (CIPSO, RIPSO, etc.),
implicit tags (IPsec SA labeling), or self assigned tags (the existing
netif/node/port checks, the secmark approach) in a way that is as LSM
generic as possibile (might not be a big issue now, but it may become
important in the future). However, the NetLabel hooks could also just
as easily be folded into another mechanism like secmark (I don't think
the existing XFRM code is generic enough to support NetLabel), although
I haven't looked at the secmark stuff in too much detail yet.
Regardless, I agree this is something that needs to be discussed as
there are a lot of different approaches that will need to be reconciled.
Do you have a suggestion of the right place to discuss this - the
netdev list, the SELinux list, here?
diff -purN kernel-2.6.16/security/selinux/ss/services.c
kernel-2.6.16-cipso_05032006/security/selinux/ss/services.c
--- kernel-2.6.16/security/selinux/ss/services.c 2006-05-02
10:41:02.000000000 -0400
+++ kernel-2.6.16-cipso_05032006/security/selinux/ss/services.c 2006-05-02
13:22:45.000000000 -0400
+int security_netlbl_sid(struct sk_buff *skb, u32 *sid)
+{
+ int ret_val = -EIDRM;
+ struct netlbl_lsm_secattr secattr;
+ struct context *ctx;
+ struct context ctx_new;
+
+ if (!ss_initialized)
+ return 0;
+
+ context_init(&ctx_new);
+ netlbl_secattr_init(&secattr);
+ secattr.lsm_type = NETLBL_LSM_SELINUX;
+ ret_val = netlbl_skbuff_read(skb, &secattr);
+ if (ret_val != 0)
+ goto netlbl_sid_failure;
+
+ if (secattr.set_selinux_sid)
+ *sid = secattr.lsm.selinux.sid;
Where do you check that the SID is defined/valid?
I don't. The NetLabel module treats the SID as an opaque value and just
returns the value that SELinux gives to it via the call to
netlbl_cache_add() further down in this function (the cache is
invalidated on policy loads/reloads). In the future the NetLabel code
made provide a SID when Selopt is used but that code still only exists
in my head.
Is there a SID verification function I should be calling? I always
thought that invalid SIDs were just mapped to an unlabled context, so
even if something went wrong and the SID was garbage/incorrect the worst
that would happen would be the packet would be "unlabeled", no?
+ } else if (secattr.set_mls_lvl) {
+ ctx = sidtab_search(&sidtab, SECINITSID_NETMSG);
+ if (ctx == NULL)
+ goto netlbl_sid_failure;
+
+ ret_val = context_cpy(&ctx_new, ctx);
+ if (ret_val != 0)
+ goto netlbl_sid_failure;
+ mls_context_destroy(&ctx_new);
+
+ if (mls_import_lvl(&ctx_new,
+ secattr.mls_lvl,
+ secattr.mls_lvl) != 0)
+ goto netlbl_sid_failure;
+ if (secattr.set_mls_cat) {
+ if (mls_import_cat(&ctx_new,
+ secattr.mls_cat,
+ secattr.mls_cat_len,
+ secattr.mls_cat,
+ secattr.mls_cat_len) != 0)
+ goto netlbl_sid_failure;
+ }
Where do you check that the MLS field values are defined and form a
legal combination under the policy, e.g. mls_context_isvalid?
Hmmm, good point. I made the mistake of thinking that the
sidtab_context_to_sid() function would verify the context like
security_context_to_sid(), but now that I am looking at it a bit closer
I realize I was wrong. Sorry about that.
I'll add the following before the call to sidtab_context_to_sid():
ret_val = mls_context_isvalid(policydb, &ctx_new);
if (ret_val != 0)
goto netlbl_sid_failure;
diff -purN kernel-2.6.16/security/selinux/xfrm.c
kernel-2.6.16-cipso_05032006/security/selinux/xfrm.c
--- kernel-2.6.16/security/selinux/xfrm.c 2006-05-02 10:40:28.000000000
-0400
+++ kernel-2.6.16-cipso_05032006/security/selinux/xfrm.c 2006-05-02
14:20:51.000000000 -0400
@@ -317,21 +317,12 @@ int selinux_xfrm_sock_rcv_skb(u32 isec_s
struct xfrm_state *x = sp->xvec[i];
if (x && selinux_authorizable_xfrm(x))
- goto accept;
+ return 0;
}
+ return -EPERM;
}
- /* check SELinux sock for unlabelled access */
- rc = avc_has_perm(isec_sid, SECINITSID_UNLABELED, SECCLASS_ASSOCIATION,
- ASSOCIATION__RECVFROM, NULL);
- if (rc)
- goto drop;
-
-accept:
- return 0;
-
-drop:
- return rc;
+ return -EIDRM;
}
Not clear what you are doing here with these different error codes. I
do agree that we want to unify the different per-packet checks.
Basically I was trying to be a bit more informative in case somebody
ever wants to know the different between a failed IPsec authorization,
-EPERM, and a packet that didn't even pass though IPsec, -EIDRM. At
least that is how I understand the code to work, please correct me if
I'm wrong. I figured it was cheap to provide more information so why
not do it?
Thanks for your comments, I appreciate the feedback.
--
paul moore
linux security @ hp
--
redhat-lspp mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/redhat-lspp