On Mon, 2004-12-20 at 23:15, Serge E. Hallyn wrote:
The attached patch implements the permissions check the way I think
Chris and Stephen were suggesting. It does not yet set the netlink
eff_caps in selinux_netlink_send(). Other than that, does this patch
seem reasonable? Is this preferable to the sender side check? Do
we want to add some audit read checks, and split CAP_AUDIT into two
or three capabilities?
The basic approach seems reasonable to me. The untested patch below
should change SELinux to fit with this approach; it calls the secondary
module to get the initial settings for the eff_cap field, then obtains
the SELinux allowed capability permissions and intersects them. For
generality and consistency, I would suggest computing the entire eff_cap
set in the dummy module as well, so that a receiver can check any
capability bit; you might be able to re-use the dummy_capget logic for
that purpose.
With regard to sender vs. receiver side checking, given that you are
only checking a capability and netlink already conveys the capability
set, there seems to be little reason to not keep the code on the
receiver side, and that keeps the audit code more encapsulated. SELinux
doesn't have that option, unfortunately, since netlink doesn't convey
SELinux SIDs.
With regard to a check on read-like operations, that does seem
desirable, as you don't want to let arbitrary processes list the audit
filters or get the audit daemon's pid.
Index: linux-2.6/security/selinux/hooks.c
===================================================================
RCS file: /nfshome/pal/CVS/linux-2.6/security/selinux/hooks.c,v
retrieving revision 1.141
diff -u -p -r1.141 hooks.c
--- linux-2.6/security/selinux/hooks.c 6 Dec 2004 19:57:39 -0000 1.141
+++ linux-2.6/security/selinux/hooks.c 21 Dec 2004 12:50:46 -0000
@@ -3540,12 +3540,19 @@ static inline int selinux_nlmsg_perm(str
static int selinux_netlink_send(struct sock *sk, struct sk_buff *skb)
{
- int err = 0;
+ struct task_security_struct *tsec;
+ struct av_decision avd;
+ int err;
- if (capable(CAP_NET_ADMIN))
- cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN);
- else
- NETLINK_CB(skb).eff_cap = 0;
+ err = secondary_ops->netlink_send(sk, skb);
+ if (err)
+ return err;
+
+ tsec = current->security;
+ err = avc_has_perm_noaudit(tsec->sid, tsec->sid, SECCLASS_CAPABILITY, ~0,
&avd);
+ if (err)
+ return err;
+ cap_mask(NETLINK_CB(skb).eff_cap, avd.allowed);
if (policydb_loaded_version >= POLICYDB_VERSION_NLCLASS)
err = selinux_nlmsg_perm(sk, skb);
--
Stephen Smalley <sds(a)epoch.ncsc.mil>
National Security Agency