Re: [PATCH 1/1] Add post accept()/recvmsg() hooks.

2007-07-05 Thread Paul Moore
On Tuesday, July 3 2007 8:07:45 am Tetsuo Handa wrote:
> diff -ur a/include/linux/security.h b/include/linux/security.h
> --- a/include/linux/security.h2007-07-03 10:07:14.0 +0900
> +++ b/include/linux/security.h2007-07-03 13:21:20.581744544 +0900
> @@ -745,6 +745,16 @@
>   *   @sock contains the listening socket structure.
>   *   @newsock contains the newly created server socket for connection.
>   *   Return 0 if permission is granted.
> + * @socket_pre_accept:
> + *   Check peer's address after accepting a new connection but
> + *   before making that connection visible to userland.
> + *   This hook is intended for filtering connections from unwanted peers.
> + *   The connection will be aborted if this hook returns nonzero.
> + *   @sock contains the listening socket structure.
> + *   @newsock contains the newly created server socket for connection.
> + *   @address contains the address of remote endpoint.
> + *   @addrlen contains the length of address.
> + *   Return 0 if permission is granted.

 ... and below ...

> diff -ur a/net/socket.c b/net/socket.c
> --- a/net/socket.c2007-07-03 10:07:16.0 +0900
> +++ b/net/socket.c2007-07-03 13:23:53.055565000 +0900
> @@ -1426,6 +1437,11 @@
>   if (err < 0)
>   goto out_fd;
>
> + /* Filter connections from unwanted peers like TCP Wrapper. */
> + err = security_socket_pre_accept(sock, newsock);
> + if (err)
> + goto out_fd;
> +
>   if (upeer_sockaddr) {
>   if (newsock->ops->getname(newsock, (struct sockaddr *)address,
> &len, 2) < 0) {

I believe the existing security_inet_conn_request() LSM hook should allow you 
to do what you want.  Adding another hook _after_ the inbound connection has 
been accepted is probably a bad idea.

> diff -ur a/include/linux/security.h b/include/linux/security.h
> --- a/include/linux/security.h2007-07-03 10:07:14.0 +0900
> +++ b/include/linux/security.h2007-07-03 13:21:20.581744544 +0900
> @@ -763,6 +773,14 @@
>   *   @size contains the size of message structure.
>   *   @flags contains the operational flags.
>   *   Return 0 if permission is granted.
> + * @socket_post_recvmsg:
> + *   Check peer's address after receiving a message from a socket.
> + *   This hook is intended for filtering messages from unwanted peers.
> + *   @sock contains the socket structure.
> + *   @msg contains the message structure.
> + *   @size contains the size of message structure.
> + *   @flags contains the operational flags.
> + *   Return 0 if permission is granted.
>   * @socket_getsockname:
>   *   Check permission before the local address (name) of the socket object
>   *   @sock is retrieved.

 ... and below ...

> diff -ur a/net/socket.c b/net/socket.c
> --- a/net/socket.c2007-07-03 10:07:16.0 +0900
> +++ b/net/socket.c2007-07-03 13:23:53.055565000 +0900
> @@ -651,6 +651,17 @@
>   ret = __sock_recvmsg(&iocb, sock, msg, size, flags);
>   if (-EIOCBQUEUED == ret)
>   ret = wait_on_sync_kiocb(&iocb);
> + /*
> +  * Filter messages from unwanted peers.
> +  * To be exact, this hook can't filter messages,
> +  * this hook just returns an error code.
> +  * Do we have to keep userland buffer unchanged until this hook?
> +  */
> + if (ret >= 0) {
> + int err = security_socket_post_recvmsg(sock, msg, size, flags);
> + if (err)
> + ret = err;
> + }
>   return ret;
>  }

Is there some reason why you can't use security_socket_recvmsg()?  Also, don't 
forget that there are many other ways to read a network socket than just 
recvmsg().

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/1] Add post accept()/recvmsg() hooks.

2007-07-06 Thread Paul Moore
On Thursday, July 5 2007 10:01:59 pm Tetsuo Handa wrote:
> Paul Moore wrote:
> > I believe the existing security_inet_conn_request() LSM hook should allow
> > you to do what you want.  Adding another hook _after_ the inbound
> > connection has been accepted is probably a bad idea.
>
> Unfortunately, security_inet_conn_request() doesn't allow blocking
> operation. I want to sleep inside this hook because I want to use
> interactive operation by asking users whether to accept this connection or
> not.

Perhaps you could move the security_post_accept() hook further up and add a 
return value?  I do not see any current in-tree users of the hook and I 
imagine moving it up would actually make the existing hook a bit more useful 
in general.

> > Is there some reason why you can't use security_socket_recvmsg()?  Also,
> > don't forget that there are many other ways to read a network socket than
> > just recvmsg().
>
> security_socket_recvmsg() is called before retrieving a message.
> I want a hook that is called after retrieving a message
> because I want to use IP address and port number.
> But it seems that there are cases (recvmsg() and read()?) where
> __sock_recvmsg() is called with msg->name == NULL and msg->msg_namelen == 0
> that makes what I want to do impossible.
> To make IP address and port number always available,
> some more changes (that are not related with LSM) are needed.

In the existing security_socket_recvmsg() hook you could peek at the top of 
the socket's receive queue and determine all of the information you would 
want to know to make your access decision.  Granted, it still might be a bit 
racy if you have two threads reading from the same socket (maybe there is a 
lock there, I would have to check it further) but it can't be any worse then 
performing an access check _after_ the fact ...

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/1] Add post accept()/recvmsg() hooks.

2007-07-06 Thread Paul Moore
On Friday, July 6 2007 10:59:49 am Tetsuo Handa wrote:
> > In the existing security_socket_recvmsg() hook you could peek at the top
> > of the socket's receive queue and determine all of the information you
> > would want to know to make your access decision.  Granted, it still might
> > be a bit racy if you have two threads reading from the same socket (maybe
> > there is a lock there, I would have to check it further) but it can't be
> > any worse then performing an access check _after_ the fact ...
>
> I think dequeuing this message is needed, or programs that call recv() like
>
> while (1) {
>   FD_SET(fd, &rfds);
>   select(fd + 1, &rfds, NULL, NULL, NULL);
>   recv(fd, buffer, sizeof(buffer), 0);
> }
>
> will begin meaningless infinite loop.

Okay, so remove the first message from the queue when your LSM declares a 
denial.

> A proper way to avoid this loop will be "not to return ready answer for
> select()". But to do so, I will need modifications in lower layer where it
> is not allowed to sleep.

I'm not sure this would be the "proper" way to fix the problem, as you would 
still collect data in the socket's receive buffer, you just wouldn't let the 
application know about it.  Thinking about the implementation also makes me 
nervous as I can't think of a clean/sane way of doing it; maybe you can but 
I'm still not sure that is justification for the change.

Thinking about your problem (personal firewall) a bit more I can't help but 
wonder if your solution would be better implemented as a netfilter module?  
Or maybe in userspace using the netfilter userspace queue feature?

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/1] Add post accept()/recvmsg() hooks.

2007-07-06 Thread Paul Moore
On Friday, July 6 2007 1:25:22 pm Tetsuo Handa wrote:
> So, recv() returning -EPERM after dequing this message is acceptable?

Maybe :)

I would suggest sending a patchset to the list with both the LSM interface 
change patch (the one we have been discussing) as well as your actual 
LSM/personal-firewall patch.  You may also want to CC other relevant lists 
(based on this discussion netdev comes to mind) on your posting as they 
should probably review your suggested changes too.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC][PATCH] Simplified mandatory access control kernel implementation

2007-07-16 Thread Paul Moore
  */
+   return smack_net_ambient;
+   }
+   /*
+* Get the categories, if any
+*/
+   if ((sap->flags & NETLBL_SECATTR_MLS_CAT) != 0)
+   for (pcat = -1;;) {
+   pcat = netlbl_secattr_catmap_walk(sap->mls_cat, pcat+1);
+   if (pcat < 0)
+   break;
+   smack_catset_bit(pcat, &smack);
+   }
+   /*
+* If it is CIPSO using smack direct mapping
+* we are already done. WeeHee.
+*/
+   if (sap->mls_lvl == SMACK_CIPSO_DIRECT)
+   return smack;
+
+   /*
+* Look it up in the supplied table if it is not a direct mapping.
+*/
+   for (scp = smack_cipso; scp != NULL; scp = scp->smk_next)
+   if (scp->smk_level == sap->mls_lvl && scp->smk_catset == smack)
+   return scp->smk_smack;

The NetLabel caching mechanism can help make this a lot less painful, i.e. 
direct return of the correct "smack" instead of traversing an unordered 
linked list each time.

+static ssize_t smk_write_cipso(struct file *file, const char __user *buf,
+  size_t count, loff_t *ppos)
+{
+   struct smk_cipso_entry *scp;
+   smack_t mapsmack;
+   smack_t mapcatset;
+   int maplevel;
+   ssize_t rc = count;
+   char *data = NULL;
+   char *cp;
+   char *eolp;
+   char *linep;
+   int cat;
+   int i;
+
+   smk_cipso_doi();
+
+   if (!capable(CAP_MAC_OVERRIDE))
+   return -EPERM;
+   /*
+* No partial writes.
+*/
+   if (*ppos != 0)
+   return -EINVAL;
+   /*
+* Casey wonders about this number.
+*/
+   if ((count > 64 * 1024 * 1024) || (data = vmalloc(count + 1)) == NULL)
+   return -ENOMEM;

I wonder about that number too.  I realize it is always going to be hard to 
get rid of all those magic numbers, but at least put a nice comment there so 
we know the reasoning behind the value (saying it's a guess is okay for me) 
and ideally make it a constant/macro/#define somewhere.

This applies to a few other places in the code too.

+int smk_curacc(smack_t *obj_label, u32 mode)
+{
+   struct task_smack *tsp = current->security;
+   int rc;
+
+   rc = smk_access(&tsp->smk_task, obj_label, mode);
+   if (rc == 0)
+   return 0;
+   
+   if (capable(CAP_MAC_OVERRIDE))
+   return 0;
+
+   return rc;
+}

I noticed a distinct lack of auditing in SMACK, the function above is a 
perfect example.  I know Linux's auditing mechanism is "interesting", but you 
should probably make use of it for security related events.

+/*
+ * Should access checks be done on each read or write?
+ * UNICOS and SELinux say yes.
+ * Trusted Solaris, Trusted Irix, and just about everyone else says no.
+ */
+static int smack_file_permission(struct file *file, int mask)
+{
+#ifdef SMACKONREADWRITE
+   smack_t *fsp;
+   int rc;
+
+   if (mask == 0)
+   return 0;
+
+   fsp = (smack_t *)file->f_dentry->d_inode->i_security;
+
+   rc = smk_curacc(fsp, mask);
+   return rc;
+#else  /* SMACKONREADWRITE */
+   return 0;
+#endif /* SMACKONREADWRITE */
+}

Pick one, even if it's wrong :)

+static int smack_task_to_sock(struct sock *sk, struct task_smack *tsp)
+{
+   struct netlbl_lsm_secattr secattr;
+   int rc;
+
+   netlbl_secattr_init(&secattr);
+   smack_to_secattr(tsp->smk_out, tsp->smk_ipscheme, &secattr);
+   if (secattr.flags != 0)

Please use the constants defined for the flag values in the NetLabel LSM 
security attributes; it makes life easier if for some freak reason we have to 
change them.  For example, 0 == NETLBL_SECATTR_NONE.

This applies to a few other places in the code too.

I'm sure there will be more comments but these are the ones that jumped out at 
me.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC][PATCH] Simplified mandatory access control kernel implementation

2007-07-17 Thread Paul Moore
On Monday, July 16 2007 10:59:41 pm Casey Schaufler wrote:
> --- Paul Moore <[EMAIL PROTECTED]> wrote:
> > On Saturday, July 14 2007 5:47:38 pm Casey Schaufler wrote:
> > +#include "../../net/netlabel/netlabel_domainhash.h"
> > +#include 
> > +
> > + {snip}
> > +
> > +static void smk_cipso_doi(void)
> > +{
> > +   int rc;
> > +   struct cipso_v4_doi *doip;
> > +   struct netlbl_dom_map *ndmp;
> > +   struct netlbl_audit audit_info;
> > +
> > +   if (smk_cipso_doied != 0)
> > +   return;
> > +   smk_cipso_doied = 1;
> > +
> > +   doip = kmalloc(sizeof(struct cipso_v4_doi), GFP_KERNEL);
> > +   if (doip == NULL)
> > +   panic("smack:  Failed to initialize cipso DOI.\n");
> > +   doip->map.std = NULL;
> > +
> > +   ndmp = kmalloc(sizeof(struct netlbl_dom_map), GFP_KERNEL);
> > +   if (ndmp == NULL)
> > +   panic("smack:  Failed to initialize cipso ndmp.\n");
> > +
> > +   doip->doi = SMACK_CIPSO_DOI;
> > +   doip->type = CIPSO_V4_MAP_PASS;
> > +   doip->tags[0] = CIPSO_V4_TAG_RBITMAP;
> > +   for (rc = 1; rc < CIPSO_V4_TAG_MAXCNT; rc++)
> > +   doip->tags[rc] = CIPSO_V4_TAG_INVALID;
> > +
> > +   rc = cipso_v4_doi_add(doip);
> > +   printk("%s:%d add doi rc = %d\n", __FUNCTION__, __LINE__, rc);
> > +
> > +   /*
> > +   rc = cipso_v4_doi_domhsh_add(doip, SMACK_CIPSO_DOMAIN_NAME);
> > +   printk("%s:%d hash doi rc = %d\n", __FUNCTION__, __LINE__, rc);
> > +*/
> > +   ndmp->domain = SMACK_CIPSO_DOMAIN_NAME;
> > +   ndmp->type = NETLBL_NLTYPE_CIPSOV4;
> > +   ndmp->type_def.cipsov4 = doip;
> > +   rc = netlbl_domhsh_add(ndmp, &audit_info);
> > +   printk("%s:%d hash doi rc = %d\n", __FUNCTION__, __LINE__, rc);
> > +}
> >
> > If SMACK gets an OK for upstream we need to find a better solution than
> > the above.  The smk_cipso_doi() function pokes into too many NetLabel
> > internals.
> >
> > The two obvious options are to rely on userspace (netlabel_tools) to
> > configure NetLabel for SMACK, like SELinux, or to create a new NetLabel
> > API for allowing LSMs to manipulate the NetLabel domain mapping.
>
> A userspace scheme is a non-starter, it goes against the project
> goals of minimal dependence on helper applications. I would be happy
> to work with you to create an appropriate API.

All right, that's fair.  For the time being just throw a comment in the code 
and we'll work on something.

> > Also, any reason why you don't just use the NetLabel default domain
> > mapping?
>
> Uh, only that I couldn't figure out how to go about doing so. If it
> simplifies (there's that word again) things I'm all for it. I would
> be happy to have my ignorance dispelled.

Two things:

 1. change "ndmp->domain = SMACK_CIPSO_DOMAIN_NAME" to "ndmp->domain = NULL"
 2. change "netlbl_domhsh_add()" to "netlbl_domhsh_add_default()"

If you want to get really nitpicky the second step is optional, but I'd prefer 
you use it in case we ever need to do something radically different for the 
default NetLabel domain mapping (it's really easy as they take the same 
arguments in the same order, just change the function name).

> > +/*
> > + * CIPSO domain information.
> > + * Casey says that these may wind up being configurable
> > + * at some point.
> > + */
> > +#define SMACK_CIPSO_DOMAIN_NAME"SmackCIPSO"
> > +#define SMACK_CIPSO_DOI3
> > +#define SMACK_CIPSO_DIRECT 250 /* Arbitrary and bad */
> >
> > Yes, SMACK_CIPSO_DIRECT is bad.
> > There has to be a cleaner solution than this,
> > think harder ;)
>
> The cleanest solution is already in the code, where there's a 1:1
> mapping of Smack labels to Cipso level/catset maintained via
> /smack/cipso, and set administratively. A purist can always set
> this up to be complete.
>
> On the other hand, it has already been acknowledged that mapping one
> set of CIPSO tags to another is necessary in some cases, for example
> when one machine's bit 6 represents another's bits 2 and 3.

My main complaint is the "magic number" of 250.  Constants that are visible 
outside a subsystem make me very nervous, especially when they are "Arbitrary 
and bad".  I understand the desire to have a direct mapping, that isn't my 
concern, my worry is how you specify to the other end that it is a direct 
mapping.

> > +static smack_t smack_from_secattr(struct netlbl_lsm_secat

Re: [RFC][PATCH] Simplified mandatory access control kernel implementation

2007-07-17 Thread Paul Moore
On Tuesday, July 17 2007 2:51:14 pm Casey Schaufler wrote:
> --- Paul Moore <[EMAIL PROTECTED]> wrote:
> > > > Also, any reason why you don't just use the NetLabel default domain
> > > > mapping?
> > >
> > > Uh, only that I couldn't figure out how to go about doing so. If it
> > > simplifies (there's that word again) things I'm all for it. I would
> > > be happy to have my ignorance dispelled.
> >
> > Two things:
> >
> >  1. change "ndmp->domain = SMACK_CIPSO_DOMAIN_NAME" to "ndmp->domain =
> > NULL" 2. change "netlbl_domhsh_add()" to "netlbl_domhsh_add_default()"
> >
> > If you want to get really nitpicky the second step is optional, but I'd
> > prefer
> > you use it in case we ever need to do something radically different for
> > the default NetLabel domain mapping (it's really easy as they take the
> > same arguments in the same order, just change the function name).
>
> I gave these changes a try. netlbl_domhsh_add_default() returns
> -EEXIST and packets are not getting labeled. Is it possible that
> the default domain has to be cached?

Nope, but I forgot that you have to remove the existing default mapping first 
(the kernel creates a default unlabeled mapping at boot) ... you'll need to 
make a call to netlbl_domhsh_remove_default() first to get rid of the 
kernel's initial domain mapping.

Sorry about that.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC][PATCH] Simplified mandatory access control kernel implementation

2007-07-19 Thread Paul Moore
On Thursday, July 19 2007 10:15:53 am James Morris wrote:
> On Thu, 19 Jul 2007, Joshua Brindle wrote:
> > > I also see an effort that's SELinux specific. Should be fun.
> >
> > The SELinux part is going to be a profile on top of the generic part so
> > there shouldn't be any conflicts in the implementation.
>
> I wonder if it'd be worth setting up a mailing list specifically for this.
> We currently have too much off-list discussion happening, and nowhere
> really good to have it on-list.
>
> Thoughts?

I like public discussion whenever possible and so far I haven't seen anything 
crop up that warrants private email.  A public list might also help attract 
some warm bodies willing to write code ;)

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [TOMOYO 15/15] LSM expansion for TOMOYO Linux.

2007-08-27 Thread Paul Moore
On Friday, August 24 2007 8:58:28 am Kentaro Takeda wrote:
> LSM hooks for network accept and recv:
>* socket_post_accept is modified to return int.

This has been discussed several times on various lists and is not considered 
an acceptable solution to blocking incoming stream connection attempts.  
Please take a look at the existing LSM stream connection request hooks as 
well as how SELinux makes use of them.

>* post_recv_datagram is added in skb_recv_datagram.

Can you explain to me why this is not possible using the existing 
security_socket_sock_rcv_skb() LSM hook?

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [TOMOYO 15/15] LSM expansion for TOMOYO Linux.

2007-08-28 Thread Paul Moore
On Tuesday, August 28 2007 6:39:13 am Tetsuo Handa wrote:
> Hello.

Hello.

> Paul Moore wrote:
> > >* post_recv_datagram is added in skb_recv_datagram.
> >
> > Can you explain to me why this is not possible using the existing
> > security_socket_sock_rcv_skb() LSM hook?
>
> socket_sock_rcv_skb() is a hook for enqueue time.
> I want a hook for dequeue time, because what TOMOYO Linux is doing is
> not "whether a socket created by foo is permitted to pick up
> an incoming packet from specific address/port"
> but "whether bar is permitted to pick up
> an incoming packet from specific address/port".
> At the time of enqueue, I can't know who will pick up that packet.
>
> Same reason for socket_post_accept(). What TOMOYO Linux is doing is
> not "whether a socket created by foo is permitted to accept
> a connection request from specific address/port"
> but "whether bar is permitted to accept
> a connection request from specific address/port".
> At the time of enqueue, I can't know who will pick up that request.

I apologize for not recognizing your approach from our earlier discussion on 
the LSM mailing list in July.  Unfortunately, I have the same objections to 
these changes that I did back then and from what I can recall of the 
discussion the rest of the kernel networking community agreed that these 
changes are not the preferred way of solving this problem.  We offered 
suggestions on how to accomplish your goals in a way that would be acceptable 
upstream and I would encourage you to investigate those options further.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [TOMOYO 15/15] LSM expansion for TOMOYO Linux.

2007-09-04 Thread Paul Moore
On Monday 03 September 2007 9:15:27 am Tetsuo Handa wrote:
> Hello.

Hi.

> Paul Moore wrote:
> > I apologize for not recognizing your approach from our earlier discussion
> > on the LSM mailing list in July.  Unfortunately, I have the same
> > objections to these changes that I did back then and from what I can
> > recall of the discussion the rest of the kernel networking community
> > agreed that these changes are not the preferred way of solving this
> > problem.  We offered suggestions on how to accomplish your goals in a way
> > that would be acceptable upstream and I would encourage you to
> > investigate those options further.
>
> When I proposed a patch in July, I was patching at post-copy_to_user() step
> (i.e. after sock_recvmsg()).
> This approach messed up user-supplied buffer.
>
> This time, I'm patching at pre-copy_to_user() step
> (i.e. at skb_recv_datagram()).
> This approach doesn't mess up user-supplied buffer.
> I think this is a cleaner way than the previous patch.

It might be cleaner than your previous patch but it ignores some of the more 
important points that were brought up by the community in previous 
discussions.

> Although read() gets an error when select() said "read ready",
> I can't find other place to use for accomplishing my goals.
>
> By the way, similar thing can happen when select() against
> a file descriptor said "read ready" but read() gets an error
> if security policy or security-id of the file has changed
> between select() and read(), isn't it?
> And such behavior is acceptable, isn't it?
> If such behavior can happen and is acceptable and *preferable*,
> I think checking permission at dequeue time (i.e. skb_recv_datagram())
> is *preferable* way than checking permission at enqueue time
> (i.e. socket_sock_rcv_skb()).

As mentioned before that problem with enforcing access control at "dequeue" 
time is that the system has already accepted the packet from the remote 
host - how do you plan to deal with these unacceptable/bad packets sitting on 
a socket, waiting to be read by a process which does not have access to them?  
What about connection oriented sockets where the remote host will assume 
everything is okay and continue blasting the machine with more, illegal 
packets?  If you aren't going to allow the socket/application to read the 
packet, never allow the system to accept it in the first place.

The *preferable* solution, as previously stated before by several people, is 
to investigate other access control methods like the netfilter userspace 
queue mechanism.  At the very least, please explain how the approaches we 
proposed will not accomplish what you require.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [TOMOYO 15/15] LSM expansion for TOMOYO Linux.

2007-09-05 Thread Paul Moore
On Tuesday 04 September 2007 10:02:46 am Tetsuo Handa wrote:
> According to Patrick McHardy's posting at
> http://www.mail-archive.com/linux-security-module@vger.kernel.org/msg00999.
>html netfilter *socket filters* cannot know final recipient process.
> Can netfilter *userspace queue mechanism* know final recipient process?

Okay, I just went back and re-read the conversation from July as well as the 
description of your current patches and I think what is basically comes down 
to is that your design makes use of userspace intervention to allow/reject 
connections and/or packets based on the application's domain.  Unfortunately 
for TOMOYO, the current LSM network hooks are placed in such a way that you 
can not block and query a userspace agent for an access control decision.

Myself and some others have suggested using the netfilter userspace queue 
mechanism[1].  However, I understand this may cause you problems when you try 
to determine the incoming packet's destination/domain.  With these 
requirements I understand why you are pushing so hard to introduce these new 
LSM hooks, but for many reasons I would really prefer to try and find a way 
to utilize the existing hooks.  I've tried to think of a way to do this over 
the past day and have not been able to arrive at a clean solution.  
Personally, I still question the wisdom of receiving a packet/connection only 
to drop/reject it later when an application tries to read it but I might be 
the only one.

Based on some of the other discussion around this patch there appears to be 
other, larger issues which you still need to sort out (language parser in the 
kernel, /proc issues, etc.).  I would recommend addressing those concerns and 
including the netdev mailing list on your next patchset as they might have 
some thoughts on your network design.

[1]http://www.netfilter.org/projects/libnetfilter_queue/index.html

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [TOMOYO 15/15] LSM expansion for TOMOYO Linux.

2007-09-06 Thread Paul Moore
On Thursday, September 6 2007 9:04:01 am Tetsuo Handa wrote:
> (1) It uses userspace intervention to allow/reject
> connections and/or packets based on the application's domain.
> Since existent hooks can't be used for this purpose,
> I inserted a new hook post_recv_datagram() at skb_recv_datagram()
> and I modified socket_post_accept() to return error so that
> I can drop/disconnect based on the application's domain.
>
> I think skb_recv_datagram() is the only place that can remove
> a message picked up with MSG_PEEK flags from the receive queue.
> To remove a message picked up with MSG_PEEK flags, I noticed that
> I have to do skb_kill_datagram()-like operation so that
> "the head message that must not be delivered to the caller" won't
> prevent picking up of "the non-head message that should be delivered to the
> caller" when the caller repeats only recv(MSG_PEEK) requests.
> Since skb_recv_datagram() can be called from interrupt context,
> I have to use spin_lock_irqsave() instead for spin_lock_bh(), am I
> right?

There are almost certainly better people to answer locking questions, but here 
is my take on it ... If you are accessing data both in a bottom half and 
elsewhere you need to make sure you disable bottom halfs from running before 
you access the data outside the bottom half (spin_lock_bh()).  If you are 
accessing data both in an interrupt handler and elsewhere you need to make 
sure you disable interrupts when accessing data outside the irq handler 
(spin_lock_irqsave()).

> By the way, why can't socket_post_accept() fail?
> Someone may wish to do memory allocation at socket_post_accept().
> socket_accept() is too early for memory allocation because
> there is no chance to free allocated memory
> when sock->ops->accept() failed.
> I think socket_post_accept() should be able to fail.

>From my experience the community disapproves of approaches which go through 
the entire TCP handshake and then terminate the connection, which is what 
allowing security_socket_post_accept() to fail would do.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Version 3 (2.6.23-rc8) Smack: Simplified Mandatory Access Control Kernel

2007-09-30 Thread Paul Moore
On Sunday 30 September 2007 3:07:42 pm Theodore Tso wrote:
> There are different kinds of security.  Not all of them involve
> cryptography and IPSEC.  Some of them involve armed soldiers and air
> gap firewalls.  :-)
>
> Yes, normally the network is outside the Trusted Computing Base (TCB),
> but a cluster of Linux machines in a rack is roughly the same size of
> a huge Unix server tens year ago --- and it's not like Ethernet is any
> more secure than the PCI bus.  So why do we consider communications
> across a PCI bus secure even though they aren't encrypted?  Why,
> because normally we assume the PCI bus is inside the trust boundary,
> and so we don't worry about bad guys tapping communications between
> the CPU and the hard drive on the PCI bus.
>
> But these days, it is obviously possible to create clusters where
> certain network interfaces are only connected to machines contained
> completely inside the trust boundary, just like a PCI bus in a
> traditional server.  So don't be so quick to dismiss something like
> CIPSO out of hand, just because it doesn't use IPSEC.

Sorry I'm a bit late to the discussion (been busy doing "weekend" things), but 
I see that Casey, Josh, and Ted have already given a pretty good explanation 
of why CIPSO is not as "evil" as it appears at first glance.  I won't restate 
the points they have already made, but I think there are two other points 
worth mentioning:

The first is that CIPSO options are immutable, which means they work 
wonderfully with IPsec.  Label integrity can be provided through the use of 
AH and/or tunneled ESP, label confidentiality can be provided through 
tunneled ESP.  While the SELinux specific labeled IPsec implementation we 
currently have in the kernel is nice if you are talking to other SELinux 
machines, it has a very real handicap in that you can't use it to talk 
anything else.  CIPSO, or CIPSO in combination with standard, non-labeled 
IPsec, can be used to talk to pretty much any trusted OSs out there.  
Adherence to standards and interoperability with other OSs have always been a 
key factor of Linux's acceptance into new areas; support for CIPSO is just 
another part of this drive for greater interoperability.

The second point I wanted to make is that in the course of putting together 
the CIPSO implementation in the kernel I ended up talking with a few people 
who were involved in the original TSIG effort and the mess with the IETF.  
>From what I could gather, the main technical complaint (other than a variety 
of political complaints which aren't relevant to our discussion here) was 
that CIPSO options are difficult to parse (they are, look at the format - 
it's an option within an option format - yuck) and the intermediate node 
vendors did not like it all (too much work to do in a fastpath ASIC).  After 
all, look at the [R]IPSO RFC, dated only eight months earlier, and there is 
no cryptographic "special sauce" in that protocol.

CIPSO isn't for everyone, I'll be the first to admit that.  However, if you 
look at the mailing list archive for the Linux LSPP effort, the SELinux list, 
and to a lesser extent the netdev and LSM lists you will see that there are a 
set of users who care very much about this functionality.  Our support of 
CIPSO is helping Linux operate in areas it wouldn't be able to elsewhere and 
I consider that a "win".

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Version 3 (2.6.23-rc8) Smack: Simplified Mandatory Access Control Kernel

2007-09-30 Thread Paul Moore
On Sunday 30 September 2007 4:16:18 am Andrew Morton wrote:
> - hm, netlabels.  Who might be a suitable person to review that code?
>   Seems that Paul Moore is the man.  Maybe he'd be interested in taking a
>   look over it (please?)

Yep, I've been tracking Casey's work on this since the first patch and sending 
comments when appropriate.  I'm going to take a look at the latest rev of the 
patch and if anything looks awry I'll be sure to let Casey know.

The only real wart that still remains from the original patch is the code in 
smk_cipso_doi() which has a nice comment at the top saying that Paul and 
Casey need to work out an appropriate interface between NetLabel and SMACK.  
We punted on it before because SMACK's future was still a bit uncertain and 
SELinux has no need for an interface like this at present.  Now that SMACK 
looks to be queued up for 2.6.24 it's time to revisit this discussion.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Version 4 (2.6.23-rc8-mm2) Smack: Simplified Mandatory Access Control Kernel

2007-10-03 Thread Paul Moore
On Wednesday 03 October 2007 12:45:42 am Casey Schaufler wrote:
> From: Casey Schaufler <[EMAIL PROTECTED]>
>
> Smack is the Simplified Mandatory Access Control Kernel.
>
> Smack implements mandatory access control (MAC) using labels
> attached to tasks and data containers, including files, SVIPC,
> and other tasks. Smack is a kernel based scheme that requires
> an absolute minimum of application support and a very small
> amount of configuration data.
>
> {snip}
>
> This patch includes changes made by Paul Moore <[EMAIL PROTECTED]>
> in support of a more comfortable interface to initialize the
> CIPSO code from within the kernel. The changes in the net directory
> are Pauls, as is the update to netlabel.h

My sign-off got lost when Casey smooshed the patch I sent him into the SMACK 
mega-patch so I'll throw it back in the thread for accounting purposes.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>

As for SMACK's use of NetLabel - it looks fine to me, especially now that 
there is better preservation of the NetLabel/LSM boundary.  As has been 
discussed on the various lists during earlier revisions of the patch I 
believe there are still some optimizations that can be made regarding how 
SMACK uses NetLabel but that is something we can always work on at a later 
date.

Acked-by: Paul Moore <[EMAIL PROTECTED]>

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] Version 7 (2.6.23) Smack: Simplified Mandatory Access Control Kernel

2007-10-15 Thread Paul Moore
On Sunday 14 October 2007 11:30:53 pm Casey Schaufler wrote:
> --- "Ahmed S. Darwish" <[EMAIL PROTECTED]> wrote:
> > Hi Casey,
> >
> > On Sun, Oct 14, 2007 at 10:15:42AM -0700, Casey Schaufler wrote:
> > > +
> > > +CIPSO Configuration
> > > +
> > > +It is normally unnecessary to specify the CIPSO configuration. The
> > > default +values used by the system handle all internal cases. Smack
> > > will compose
> >
> > CIPSO
> >
> > > +label values to match the Smack labels being used without
> > > administrative +intervention.
> >
> > I have two issues with CIPSO and Smack:
> >
> > 1-
> >
> > Using default configuration (system startup script + smacfs fstab line),
> > system
> > can't access any service outside the Lan. "ICMP parameter problem
> > message" always
> > appear from the first Wan router (traceroute + tcpdump at [1]).
> >
> > Services inside the LAN can be accessed normally. System can connect to a
> > Lan Windows share. It also connects to the gateway HTTP server easily.
> >
> > After some tweaking, I discovered that using CIPSOv6 solves all above
> > problems:
> > $ echo -n "NLBL_CIPSOv6" > /smack/nltype
> >
> > Is this a normal behaviour ?
>
> Well ... sort of. CIPSOv6 isn't actually implemented in the
> labeled networking code. What you're seeing is unlabeled packets.
>
> As far as CIPSOv4 and your WAN router, It is possible that it is
> configured either to reject CIPSO packets or to allow only CIPSO
> packets in a particular DOI or to enforce a CIPSO policy of its
> own.

The how/why of the packet rejection probably isn't all that important, but the 
most likely scenario based on the ICMP error code is that the router simply 
does not know about the CIPSO IP option type and is dropping the packet as a 
result.  I'd be very surprised to see a standard router in general use which 
has policy to perform packet level access control using CIPSO options/labels.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v6 00/13] Labeled networking patches

2007-11-09 Thread Paul Moore
This is an update to the patcheset sent earlier this week and the first time
these patches have been sent to the LSM list.  The most notable change
between this patchset and the "v5" patches is the addition of the
fallback/static label patches that were discussed on the SELinux list a few
months ago.  In addition to just porting the old fallback/static patches I've
added the concept of a "default" interface as well as some intelligence in
the SELinux layer to allow the NetLabel provided fallback label to play
nicely with XFRM labels when both are present on a connection.  This should
help address issues found in the earlier versions of the fallback/static
label patches.  This patchset does not include Venkat's flow control patches,
but Venkat has promised that they will be ready very soon; when they are I
will merge them into this patchset.  On a similar note, the new "peer"
SELinux object class in this patchset isn't usable with currently released
SELinux policies so you'll still be using the separate, labeling protocol
specific, access checks.

I have to caution against using these patches for anything critical as they
are still a "work in progress" and have only received minimal testing.
However, I know there are a few of you who are very interested in this
functionality and have offered to help with the testing so I'm posting the
patches in this early state so we can get a jump shaking the bugs out.  For
those of you who are playing with these patches, there are a few things worth
noting:

 * You can do a pull down a complete git tree with these changes here:
   -> git://git.infradead.org/users/pcmoore/lblnet-2.6_testing

 * You should probably also apply this patch to fix an unrelated panic:
   -> 
http://git.kernel.org/?p=linux/kernel/git/jmorris/selinux-2.6.git;a=commitdiff;h=6d2b685564ba417f4c6d80c3661f0dfee13fff85

 * You'll need the latest SVN (rev 49 or higher) of the static_label branch
   of netlabel_tools to make use of the new fallback/static label features:
   -> http://netlabel.svn.sourceforge.net/viewvc/netlabel/netlabel_tools

To configure the new fallback/static labels you use the following netlabelctl
commands:

 * Add a label
"netlabelctl unlbl add default|interface: address:[/] \
  label:"
  DEV = interface
  ADDR = IP address
  MASK = size of address mask
  LABEL = full SELinux context

  Examples:
  # netlabelctl unlbl add default address:10.0.0.0/8 \
  label:system_u:object_r:unlabeled_t:s0
  # netlabelctl unlbl add interface:eth0 address:192.168.0.1 \
  label:system_u:object_r:unlabeled_t:s0
  # netlabelctl unlbl add interface:lo address:::1 \
  label:system_u:object_r:unlabeled_t:s0

 * Remove a label
"netlabelctl unlbl del default|interface: address:[/]"
  DEV = interface
  ADDR = IP address
  MASK = size of address mask

  Examples:
  # netlabelctl unlbl del default address:10.0.0.0/8
  # netlabelctl unlbl del interface:eth0 address:192.168.0.1
  # netlabelctl unlbl del interface:lo address:::1

 * Show labels
"netlabelctl -p unlbl list"

  Examples:
  # netlabelctl unlbl list
  # netlabelctl -p unlbl list

If you have any questions/problems/comments feel free to either drop me mail
privately or post something to the list.

Thanks.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v6 01/13] NetLabel: remove unneeded RCU read locks

2007-11-09 Thread Paul Moore
This patch removes some unneeded RCU read locks as we can treat the reads as
"safe" even without RCU.  It also converts the NetLabel configuration refcount
from a spinlock protected u32 into atomic_t to be more consistent with the rest
of the kernel.
---

 net/netlabel/netlabel_cipso_v4.c  |5 ++-
 net/netlabel/netlabel_kapi.c  |3 +-
 net/netlabel/netlabel_mgmt.c  |   63 ++---
 net/netlabel/netlabel_mgmt.h  |7 ++--
 net/netlabel/netlabel_unlabeled.c |   17 ++
 5 files changed, 15 insertions(+), 80 deletions(-)

diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index ba0ca8d..becf91a 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "netlabel_user.h"
 #include "netlabel_cipso_v4.h"
@@ -421,7 +422,7 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct 
genl_info *info)
break;
}
if (ret_val == 0)
-   netlbl_mgmt_protocount_inc();
+   atomic_inc(&netlabel_mgmt_protocount);
 
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
  &audit_info);
@@ -698,7 +699,7 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, 
struct genl_info *info)
  &audit_info,
  netlbl_cipsov4_doi_free);
if (ret_val == 0)
-   netlbl_mgmt_protocount_dec();
+   atomic_dec(&netlabel_mgmt_protocount);
 
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
  &audit_info);
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 4f50949..d3762ea 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "netlabel_domainhash.h"
 #include "netlabel_unlabeled.h"
@@ -262,7 +263,7 @@ int netlbl_enabled(void)
/* At some point we probably want to expose this mechanism to the user
 * as well so that admins can toggle NetLabel regardless of the
 * configuration */
-   return (netlbl_mgmt_protocount_value() > 0 ? 1 : 0);
+   return (atomic_read(&netlabel_mgmt_protocount) > 0);
 }
 
 /**
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index 5648337..e2258dc 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -37,14 +37,14 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "netlabel_domainhash.h"
 #include "netlabel_user.h"
 #include "netlabel_mgmt.h"
 
-/* NetLabel configured protocol count */
-static DEFINE_SPINLOCK(netlabel_mgmt_protocount_lock);
-static u32 netlabel_mgmt_protocount = 0;
+/* NetLabel configured protocol counter */
+atomic_t netlabel_mgmt_protocount = ATOMIC_INIT(0);
 
 /* Argument struct for netlbl_domhsh_walk() */
 struct netlbl_domhsh_walk_arg {
@@ -71,63 +71,6 @@ static const struct nla_policy 
netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
 };
 
 /*
- * NetLabel Misc Managment Functions
- */
-
-/**
- * netlbl_mgmt_protocount_inc - Increment the configured labeled protocol count
- *
- * Description:
- * Increment the number of labeled protocol configurations in the current
- * NetLabel configuration.  Keep track of this for use in determining if
- * NetLabel label enforcement should be active/enabled or not in the LSM.
- *
- */
-void netlbl_mgmt_protocount_inc(void)
-{
-   spin_lock(&netlabel_mgmt_protocount_lock);
-   netlabel_mgmt_protocount++;
-   spin_unlock(&netlabel_mgmt_protocount_lock);
-}
-
-/**
- * netlbl_mgmt_protocount_dec - Decrement the configured labeled protocol count
- *
- * Description:
- * Decrement the number of labeled protocol configurations in the current
- * NetLabel configuration.  Keep track of this for use in determining if
- * NetLabel label enforcement should be active/enabled or not in the LSM.
- *
- */
-void netlbl_mgmt_protocount_dec(void)
-{
-   spin_lock(&netlabel_mgmt_protocount_lock);
-   if (netlabel_mgmt_protocount > 0)
-   netlabel_mgmt_protocount--;
-   spin_unlock(&netlabel_mgmt_protocount_lock);
-}
-
-/**
- * netlbl_mgmt_protocount_value - Return the number of configured protocols
- *
- * Description:
- * Return the number of labeled protocols in the current NetLabel
- * configuration.  This value is useful in  determining if NetLabel label
- * enforcement should be active/enabled or not in the LSM.
- *
- */
-u32 netlbl_mgmt_protocount_value(void)
-{
-   u32 val;
-
-   rcu_read_lock();
-   val = netlabel_mgmt_protocount;
-   rcu_read_unlock();
-
-   return val;
-}
-
-/*
  * NetLabel Command Handlers
  */
 
diff --git a/net/netlabel/netlabel_mgmt.h b/net/netlabel/netlabel_mgmt.h
index ccb2b39..a43bff1 100644
--- a/net/netlabel/netlabel_mgmt.h
+++

[RFC PATCH v6 02/13] NetLabel: cleanup the LSM domain hash functions

2007-11-09 Thread Paul Moore
The NetLabel/LSM domain hash table search function used a argument to specify
if the default entry should be returned if an exact match couldn't be found in
the hash table.  This is a bit against the kernel's style so make two separate
functions to represent the separate behaviors.
---

 net/netlabel/netlabel_domainhash.c |   47 ++--
 1 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/net/netlabel/netlabel_domainhash.c 
b/net/netlabel/netlabel_domainhash.c
index b3675bd..1f8f7ac 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -109,17 +109,14 @@ static u32 netlbl_domhsh_hash(const char *key)
 /**
  * netlbl_domhsh_search - Search for a domain entry
  * @domain: the domain
- * @def: return default if no match is found
  *
  * Description:
  * Searches the domain hash table and returns a pointer to the hash table
- * entry if found, otherwise NULL is returned.  If @def is non-zero and a
- * match is not found in the domain hash table the default mapping is returned
- * if it exists.  The caller is responsibile for the rcu hash table locks
- * (i.e. the caller much call rcu_read_[un]lock()).
+ * entry if found, otherwise NULL is returned.  The caller is responsibile for
+ * the rcu hash table locks (i.e. the caller much call rcu_read_[un]lock()).
  *
  */
-static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain, u32 def)
+static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
 {
u32 bkt;
struct netlbl_dom_map *iter;
@@ -133,10 +130,31 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const 
char *domain, u32 def)
return iter;
}
 
-   if (def != 0) {
-   iter = rcu_dereference(netlbl_domhsh_def);
-   if (iter != NULL && iter->valid)
-   return iter;
+   return NULL;
+}
+
+/**
+ * netlbl_domhsh_search_def - Search for a domain entry
+ * @domain: the domain
+ * @def: return default if no match is found
+ *
+ * Description:
+ * Searches the domain hash table and returns a pointer to the hash table
+ * entry if an exact match is found, if an exact match is not present in the
+ * hash table then the default entry is returned if valid otherwise NULL is
+ * returned.  The caller is responsibile for the rcu hash table locks
+ * (i.e. the caller much call rcu_read_[un]lock()).
+ *
+ */
+static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
+{
+   struct netlbl_dom_map *entry;
+
+   entry = netlbl_domhsh_search(domain);
+   if (entry == NULL) {
+   entry = rcu_dereference(netlbl_domhsh_def);
+   if (entry != NULL && entry->valid)
+   return entry;
}
 
return NULL;
@@ -224,7 +242,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
if (entry->domain != NULL) {
bkt = netlbl_domhsh_hash(entry->domain);
spin_lock(&netlbl_domhsh_lock);
-   if (netlbl_domhsh_search(entry->domain, 0) == NULL)
+   if (netlbl_domhsh_search(entry->domain) == NULL)
list_add_tail_rcu(&entry->list,
&rcu_dereference(netlbl_domhsh)->tbl[bkt]);
else
@@ -307,7 +325,10 @@ int netlbl_domhsh_remove(const char *domain, struct 
netlbl_audit *audit_info)
struct audit_buffer *audit_buf;
 
rcu_read_lock();
-   entry = netlbl_domhsh_search(domain, (domain != NULL ? 0 : 1));
+   if (domain)
+   entry = netlbl_domhsh_search(domain);
+   else
+   entry = netlbl_domhsh_search_def(domain);
if (entry == NULL)
goto remove_return;
switch (entry->type) {
@@ -377,7 +398,7 @@ int netlbl_domhsh_remove_default(struct netlbl_audit 
*audit_info)
  */
 struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain)
 {
-   return netlbl_domhsh_search(domain, 1);
+   return netlbl_domhsh_search_def(domain);
 }
 
 /**

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v6 05/13] SELinux: add secctx_to_secid() LSM hook

2007-11-09 Thread Paul Moore
Add a secctx_to_secid() LSM hook to go along with the existing
secid_to_secctx() LSM hook.  This patch also includes a SELinux implementation
for this hook.
---

 include/linux/security.h |   13 +
 security/dummy.c |6 ++
 security/security.c  |6 ++
 security/selinux/hooks.c |6 ++
 4 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index ac05083..db19c92 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1183,6 +1183,10 @@ struct request_sock;
  * Convert secid to security context.
  * @secid contains the security ID.
  * @secdata contains the pointer that stores the converted security 
context.
+ * @secctx_to_secid:
+ *  Convert security context to secid.
+ *  @secid contains the pointer to the generated security ID.
+ *  @secdata contains the security context.
  *
  * @release_secctx:
  * Release the security context.
@@ -1371,6 +1375,7 @@ struct security_operations {
int (*getprocattr)(struct task_struct *p, char *name, char **value);
int (*setprocattr)(struct task_struct *p, char *name, void *value, 
size_t size);
int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen);
+   int (*secctx_to_secid)(char *secdata, u32 seclen, u32 *secid);
void (*release_secctx)(char *secdata, u32 seclen);
 
 #ifdef CONFIG_SECURITY_NETWORK
@@ -1603,6 +1608,7 @@ int security_setprocattr(struct task_struct *p, char 
*name, void *value, size_t
 int security_netlink_send(struct sock *sk, struct sk_buff *skb);
 int security_netlink_recv(struct sk_buff *skb, int cap);
 int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
+int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid);
 void security_release_secctx(char *secdata, u32 seclen);
 
 #else /* CONFIG_SECURITY */
@@ -2280,6 +2286,13 @@ static inline int security_secid_to_secctx(u32 secid, 
char **secdata, u32 *secle
return -EOPNOTSUPP;
 }
 
+static inline int security_secctx_to_secid(char *secdata,
+  u32 seclen,
+  u32 *secid)
+{
+   return -EOPNOTSUPP;
+}
+
 static inline void security_release_secctx(char *secdata, u32 seclen)
 {
 }
diff --git a/security/dummy.c b/security/dummy.c
index 6d895ad..767d5a7 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -928,6 +928,11 @@ static int dummy_secid_to_secctx(u32 secid, char 
**secdata, u32 *seclen)
return -EOPNOTSUPP;
 }
 
+static int dummy_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
+{
+   return -EOPNOTSUPP;
+}
+
 static void dummy_release_secctx(char *secdata, u32 seclen)
 {
 }
@@ -1086,6 +1091,7 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, getprocattr);
set_to_dummy_if_null(ops, setprocattr);
set_to_dummy_if_null(ops, secid_to_secctx);
+   set_to_dummy_if_null(ops, secctx_to_secid);
set_to_dummy_if_null(ops, release_secctx);
 #ifdef CONFIG_SECURITY_NETWORK
set_to_dummy_if_null(ops, unix_stream_connect);
diff --git a/security/security.c b/security/security.c
index 0e1f1f1..3bdcada 100644
--- a/security/security.c
+++ b/security/security.c
@@ -816,6 +816,12 @@ int security_secid_to_secctx(u32 secid, char **secdata, 
u32 *seclen)
 }
 EXPORT_SYMBOL(security_secid_to_secctx);
 
+int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
+{
+   return security_ops->secctx_to_secid(secdata, seclen, secid);
+}
+EXPORT_SYMBOL(security_secctx_to_secid);
+
 void security_release_secctx(char *secdata, u32 seclen)
 {
return security_ops->release_secctx(secdata, seclen);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9f3124b..8bb673b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4710,6 +4710,11 @@ static int selinux_secid_to_secctx(u32 secid, char 
**secdata, u32 *seclen)
return security_sid_to_context(secid, secdata, seclen);
 }
 
+static int selinux_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
+{
+   return security_context_to_sid(secdata, seclen, secid);
+}
+
 static void selinux_release_secctx(char *secdata, u32 seclen)
 {
kfree(secdata);
@@ -4898,6 +4903,7 @@ static struct security_operations selinux_ops = {
.setprocattr =  selinux_setprocattr,
 
.secid_to_secctx =  selinux_secid_to_secctx,
+   .secctx_to_secid =  selinux_secctx_to_secid,
.release_secctx =   selinux_release_secctx,
 
 .unix_stream_connect = selinux_socket_unix_stream_connect,

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v6 07/13] SELinux: Add a capabilities bitmap to SELinux policy version 22

2007-11-09 Thread Paul Moore
Add a new policy capabilities bitmap to SELinux policy version 22.  This bitmap
will enable the security server to query the policy to determine which features
it supports.
---

 security/selinux/Kconfig|2 -
 security/selinux/include/security.h |   15 ++
 security/selinux/selinuxfs.c|   89 +--
 security/selinux/ss/policydb.c  |   18 +++
 security/selinux/ss/policydb.h  |2 +
 security/selinux/ss/services.c  |   67 ++
 6 files changed, 185 insertions(+), 8 deletions(-)

diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
index b32a459..2b517d6 100644
--- a/security/selinux/Kconfig
+++ b/security/selinux/Kconfig
@@ -145,7 +145,7 @@ config SECURITY_SELINUX_POLICYDB_VERSION_MAX
 config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
int "NSA SELinux maximum supported policy format version value"
depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX
-   range 15 21
+   range 15 22
default 19
help
  This option sets the value for the maximum policy format version
diff --git a/security/selinux/include/security.h 
b/security/selinux/include/security.h
index 39337af..4d3c0d3 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -25,13 +25,14 @@
 #define POLICYDB_VERSION_MLS   19
 #define POLICYDB_VERSION_AVTAB 20
 #define POLICYDB_VERSION_RANGETRANS21
+#define POLICYDB_VERSION_POLCAP22
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX   
CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_RANGETRANS
+#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_POLCAP
 #endif
 
 struct netlbl_lsm_secattr;
@@ -39,8 +40,19 @@ struct netlbl_lsm_secattr;
 extern int selinux_enabled;
 extern int selinux_mls_enabled;
 
+/* Policy capabilities */
+enum {
+   POLICYDB_CAPABILITY_NETPEER,
+   __POLICYDB_CAPABILITY_MAX
+};
+#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
+
+extern int selinux_policycap_netpeer;
+
 int security_load_policy(void * data, size_t len);
 
+int security_policycap_supported(unsigned int req_cap);
+
 #define SEL_VEC_MAX 32
 struct av_decision {
u32 allowed;
@@ -92,6 +104,7 @@ int security_get_classes(char ***classes, int *nclasses);
 int security_get_permissions(char *class, char ***perms, int *nperms);
 int security_get_reject_unknown(void);
 int security_get_allow_unknown(void);
+int security_get_policycaps(int *len, int **values);
 
 #define SECURITY_FS_USE_XATTR  1 /* use xattr */
 #define SECURITY_FS_USE_TRANS  2 /* use transition SIDs, e.g. 
devpts/tmpfs */
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index f5f3e6d..cf583cc 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -2,6 +2,11 @@
  *
  * Added conditional policy language extensions
  *
+ *  Updated: Hewlett-Packard <[EMAIL PROTECTED]>
+ *
+ *  Added support for the policy capability bitmap
+ *
+ * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2003 - 2004 Tresys Technology, LLC
  * Copyright (C) 2004 Red Hat, Inc., James Morris <[EMAIL PROTECTED]>
  * This program is free software; you can redistribute it and/or modify
@@ -35,6 +40,11 @@
 #include "objsec.h"
 #include "conditional.h"
 
+/* Policy capability filenames */
+static char *policycap_names[] = {
+   "network_peer_controls"
+};
+
 unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
 
 #ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
@@ -71,6 +81,9 @@ static int *bool_pending_values = NULL;
 static struct dentry *class_dir = NULL;
 static unsigned long last_class_ino;
 
+/* global data for policy capabilities */
+static struct dentry *policycap_dir = NULL;
+
 extern void selnl_notify_setenforce(int val);
 
 /* Check whether a task is allowed to use a security operation. */
@@ -110,10 +123,11 @@ enum sel_inos {
 
 static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
 
-#define SEL_INITCON_INO_OFFSET 0x0100
-#define SEL_BOOL_INO_OFFSET0x0200
-#define SEL_CLASS_INO_OFFSET   0x0400
-#define SEL_INO_MASK   0x00ff
+#define SEL_INITCON_INO_OFFSET 0x0100
+#define SEL_BOOL_INO_OFFSET0x0200
+#define SEL_CLASS_INO_OFFSET   0x0400
+#define SEL_POLICYCAP_INO_OFFSET   0x0800
+#define SEL_INO_MASK   0x00ff
 
 #define TMPBUFLEN  12
 static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
@@ -262,6 +276,7 @@ static const struct file_operations sel_policyvers_ops = {
 /* declaration for sel_write_load */
 static int sel_make_bools(void);
 static int sel_make_classes(void);
+static int sel_make_po

[RFC PATCH v6 08/13] SELinux: Add new peer permissions to the Flask definitions

2007-11-09 Thread Paul Moore
Add additional Flask definitions to support the new "peer" object class.
---

 security/selinux/include/av_perm_to_string.h |3 +++
 security/selinux/include/av_permissions.h|3 +++
 security/selinux/include/class_to_string.h   |7 +++
 security/selinux/include/flask.h |1 +
 4 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/security/selinux/include/av_perm_to_string.h 
b/security/selinux/include/av_perm_to_string.h
index 049bf69..1d56a6a 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -159,3 +159,6 @@
S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NODE_BIND, "node_bind")
S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NAME_CONNECT, "name_connect")
S_(SECCLASS_MEMPROTECT, MEMPROTECT__MMAP_ZERO, "mmap_zero")
+   S_(SECCLASS_PEER, PEER__FLOW_IN, "flow_in")
+   S_(SECCLASS_PEER, PEER__FLOW_OUT, "flow_out")
+   S_(SECCLASS_PEER, PEER__RECV, "recv")
diff --git a/security/selinux/include/av_permissions.h 
b/security/selinux/include/av_permissions.h
index eda89a2..95d4674 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -824,3 +824,6 @@
 #define DCCP_SOCKET__NODE_BIND0x0040UL
 #define DCCP_SOCKET__NAME_CONNECT 0x0080UL
 #define MEMPROTECT__MMAP_ZERO 0x0001UL
+#define PEER__FLOW_IN 0x0001UL
+#define PEER__FLOW_OUT0x0002UL
+#define PEER__RECV0x0004UL
diff --git a/security/selinux/include/class_to_string.h 
b/security/selinux/include/class_to_string.h
index e77de0e..b1b0d1d 100644
--- a/security/selinux/include/class_to_string.h
+++ b/security/selinux/include/class_to_string.h
@@ -64,3 +64,10 @@
 S_(NULL)
 S_("dccp_socket")
 S_("memprotect")
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_("peer")
diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h
index a9c2b20..09e9dd2 100644
--- a/security/selinux/include/flask.h
+++ b/security/selinux/include/flask.h
@@ -50,6 +50,7 @@
 #define SECCLASS_KEY 58
 #define SECCLASS_DCCP_SOCKET 60
 #define SECCLASS_MEMPROTECT  61
+#define SECCLASS_PEER68
 
 /*
  * Security identifier indices for initial entities

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v6 10/13] SELinux: Enable dynamic enable/disable of the network access checks

2007-11-09 Thread Paul Moore
This patch introduces a mechanism for checking when labeled IPsec or SECMARK
are in use by keeping introducing a configuration reference counter for each
subsystem.  In the case of labeled IPsec, whenever a labeled SA or SPD entry
is created the labeled IPsec/XFRM reference count is increased and when the
entry is removed it is decreased.  In the case of SECMARK, when a SECMARK
target is created the reference count is increased and later decreased when the
target is removed.  These reference counters allow SELinux to quickly determine
if either of these subsystems are enabled.

NetLabel already has a similar mechanism which provides the netlbl_enabled()
function.

This patch also renames the selinux_relabel_packet_permission() function to
selinux_secmark_relabel_packet_permission() as the original name and
description were misleading in that they referenced a single packet label which
is not the case.
---

 include/linux/selinux.h |   45 ---
 net/netfilter/xt_SECMARK.c  |   13 ++-
 security/selinux/exports.c  |   20 -
 security/selinux/hooks.c|   24 -
 security/selinux/include/xfrm.h |   17 +++
 security/selinux/xfrm.c |   18 ++--
 6 files changed, 123 insertions(+), 14 deletions(-)

diff --git a/include/linux/selinux.h b/include/linux/selinux.h
index d1b7ca6..691170b 100644
--- a/include/linux/selinux.h
+++ b/include/linux/selinux.h
@@ -120,16 +120,35 @@ void selinux_get_task_sid(struct task_struct *tsk, u32 
*sid);
 int selinux_string_to_sid(char *str, u32 *sid);
 
 /**
- * selinux_relabel_packet_permission - check permission to relabel a packet
- * @sid: ID value to be applied to network packet (via SECMARK, most 
likely)
+ * selinux_secmark_relabel_packet_permission - secmark permission check
+ * @sid: SECMARK ID value to be applied to network packet
  *
- * Returns 0 if the current task is allowed to label packets with the
- * supplied security ID.  Note that it is implicit that the packet is 
always
- * being relabeled from the default unlabled value, and that the access
- * control decision is made in the AVC.
+ * Returns 0 if the current task is allowed to set the SECMARK label of
+ * packets with the supplied security ID.  Note that it is implicit that
+ * the packet is always being relabeled from the default unlabeled value,
+ * and that the access control decision is made in the AVC.
  */
-int selinux_relabel_packet_permission(u32 sid);
+int selinux_secmark_relabel_packet_permission(u32 sid);
 
+/**
+ * selinux_secmark_refcount_inc - increments the secmark use counter
+ *
+ * SELinux keeps track of the current SECMARK targets in use so it knows
+ * when to apply SECMARK label access checks to network packets.  This
+ * function incements this reference count to indicate that a new SECMARK
+ * target has been configured.
+ */
+void selinux_secmark_refcount_inc(void);
+
+/**
+ * selinux_secmark_refcount_dec - decrements the secmark use counter
+ *
+ * SELinux keeps track of the current SECMARK targets in use so it knows
+ * when to apply SECMARK label access checks to network packets.  This
+ * function decements this reference count to indicate that one of the
+ * existing SECMARK targets has been removed/flushed.
+ */
+void selinux_secmark_refcount_dec(void);
 #else
 
 static inline int selinux_audit_rule_init(u32 field, u32 op,
@@ -184,11 +203,21 @@ static inline int selinux_string_to_sid(const char *str, 
u32 *sid)
return 0;
 }
 
-static inline int selinux_relabel_packet_permission(u32 sid)
+static inline int selinux_secmark_relabel_packet_permission(u32 sid)
 {
return 0;
 }
 
+static inline void selinux_secmark_refcount_inc(void)
+{
+   return;
+}
+
+static inline void selinux_secmark_refcount_dec(void)
+{
+   return;
+}
+
 #endif /* CONFIG_SECURITY_SELINUX */
 
 #endif /* _LINUX_SELINUX_H */
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 235806e..db4a1fe 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -72,12 +72,13 @@ static bool checkentry_selinux(struct 
xt_secmark_target_info *info)
return false;
}
 
-   err = selinux_relabel_packet_permission(sel->selsid);
+   err = selinux_secmark_relabel_packet_permission(sel->selsid);
if (err) {
printk(KERN_INFO PFX "unable to obtain relabeling 
permission\n");
return false;
}
 
+   selinux_secmark_refcount_inc();
return true;
 }
 
@@ -109,11 +110,20 @@ static bool checkentry(const char *tablename, const void 
*entry,
return true;
 }
 
+void destroy(const struct xt_target *target, void *targinfo)
+{
+   switch (mode) {
+   case SECMARK_MODE_SEL:
+   selinux_secmark_refcount_dec();
+   }
+}
+
 static struct xt_target xt_secmark_targ

[RFC PATCH v6 12/13] NetLabel: introduce static network labels for unlabeled connections

2007-11-09 Thread Paul Moore
Most trusted OSs, with the exception of Linux, have the ability to specify
static security labels for unlabeled networks.  This patch adds this ability to
the NetLabel packet labeling framework.

If the NetLabel subsystem is called to determine the security attributes of an
incoming packet it first checks to see if any recognized NetLabel packet
labeling protocols are in-use on the packet.  If none can be found then the
unlabled connection table is queried and based on the packets incoming
interface and address it is matched with a security label as configured by the
administrator using the netlabel_tools package.  The matching security label is
returned to the caller just as if the packet was explicitly labeled using a
labeling protocol.
---

 include/net/netlabel.h|6 
 net/netlabel/netlabel_kapi.c  |   16 
 net/netlabel/netlabel_unlabeled.c | 1373 +
 net/netlabel/netlabel_unlabeled.h |  145 
 4 files changed, 1522 insertions(+), 18 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index a3bffb4..b3213c7 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -67,7 +67,11 @@
  * NetLabel NETLINK protocol
  */
 
-#define NETLBL_PROTO_VERSION1
+/* NetLabel NETLINK protocol version
+ *  1: initial version
+ *  2: added static labels for unlabeled connections
+ */
+#define NETLBL_PROTO_VERSION2
 
 /* NetLabel NETLINK types/families */
 #define NETLBL_NLTYPE_NONE  0
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 4914615..c69e3e1 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -312,7 +312,7 @@ socket_setattr_return:
  * @secattr: the security attributes
  *
  * Description:
- * Examines the given sock to see any NetLabel style labeling has been
+ * Examines the given sock to see if any NetLabel style labeling has been
  * applied to the sock, if so it parses the socket label and returns the
  * security attributes in @secattr.  Returns zero on success, negative values
  * on failure.
@@ -320,13 +320,7 @@ socket_setattr_return:
  */
 int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
 {
-   int ret_val;
-
-   ret_val = cipso_v4_sock_getattr(sk, secattr);
-   if (ret_val == 0)
-   return 0;
-
-   return netlbl_unlabel_getattr(secattr);
+   return cipso_v4_sock_getattr(sk, secattr);
 }
 
 /**
@@ -350,7 +344,7 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
cipso_v4_skbuff_getattr(skb, secattr) == 0)
return 0;
 
-   return netlbl_unlabel_getattr(secattr);
+   return netlbl_unlabel_getattr(skb, family, secattr);
 }
 
 /**
@@ -434,6 +428,10 @@ static int __init netlbl_init(void)
if (ret_val != 0)
goto init_failure;
 
+   ret_val = netlbl_unlabel_init(NETLBL_UNLHSH_BITSIZE);
+   if (ret_val != 0)
+   goto init_failure;
+
ret_val = netlbl_netlink_init();
if (ret_val != 0)
goto init_failure;
diff --git a/net/netlabel/netlabel_unlabeled.c 
b/net/netlabel/netlabel_unlabeled.c
index 5e11394..add0988 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -10,7 +10,7 @@
  */
 
 /*
- * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
+ * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - 2007
  *
  * This program is free software;  you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,22 +36,88 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
-
+#include 
+#include 
 #include 
 #include 
+#include 
 
 #include "netlabel_user.h"
 #include "netlabel_domainhash.h"
 #include "netlabel_unlabeled.h"
+#include "netlabel_mgmt.h"
+
+/* The unlabeled connection hash table which we use to map network interfaces
+ * and addresses of unlabeled packets to a user specified secid value for the
+ * LSM.  The hash table is used to lookup the network interface entry
+ * (struct netlbl_unlhsh_iface) and then the interface entry is used to
+ * lookup an IP address match from an ordered list.  If a network interface
+ * match can not be found in the hash table then the default entry
+ * (netlbl_unlhsh_def) is used.  The IP address entry list
+ * (struct netlbl_unlhsh_addr) is ordered such that the entries with a
+ * larger netmask come first.
+ */
+struct netlbl_unlhsh_tbl {
+   struct list_head *tbl;
+   u32 size;
+};
+struct netlbl_unlhsh_addr4 {
+   __be32 addr;
+   __be32 mask;
+   u32 secid;
+
+   u32 valid;
+   struct list_head list;
+   struct rcu_head rcu;
+};
+struct netlbl_unlhsh_addr6 {
+   struct in6_addr addr;
+   struct in6_addr mask;
+   u32 secid;
+
+   u32 valid;
+   struct list_head list;
+   

[RFC PATCH v6 13/13] NetLabel: add auditing to the static labeling mechanism

2007-11-09 Thread Paul Moore
This patch adds auditing support to the NetLabel static labeling mechanism.
---

 include/linux/audit.h |2 +
 net/netlabel/netlabel_unlabeled.c |  127 +++--
 2 files changed, 107 insertions(+), 22 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index c687816..bdd6f5d 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -115,6 +115,8 @@
 #define AUDIT_MAC_IPSEC_ADDSPD 1413/* Not used */
 #define AUDIT_MAC_IPSEC_DELSPD 1414/* Not used */
 #define AUDIT_MAC_IPSEC_EVENT  1415/* Audit an IPSec event */
+#define AUDIT_MAC_UNLBL_STCADD 1416/* NetLabel: add a static label */
+#define AUDIT_MAC_UNLBL_STCDEL 1417/* NetLabel: del a static label */
 
 #define AUDIT_FIRST_KERN_ANOM_MSG   1700
 #define AUDIT_LAST_KERN_ANOM_MSG1799
diff --git a/net/netlabel/netlabel_unlabeled.c 
b/net/netlabel/netlabel_unlabeled.c
index add0988..30ebb14 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -519,6 +519,7 @@ add_iface_failure:
  * @mask: address mask in network byte order
  * @addr_len: length of address/mask (4 for IPv4, 16 for IPv6)
  * @secid: LSM secid value for the entry
+ * @audit_info: NetLabel audit information
  *
  * Description:
  * Adds a new entry to the unlabeled connection hash table.  Returns zero on
@@ -530,12 +531,18 @@ static int netlbl_unlhsh_add(struct net *net,
 const void *addr,
 const void *mask,
 u32 addr_len,
-u32 secid)
+u32 secid,
+struct netlbl_audit *audit_info)
 {
int ret_val;
int ifindex;
struct net_device *dev;
struct netlbl_unlhsh_iface *iface;
+   struct in_addr *addr4, *mask4;
+   struct in6_addr *addr6, *mask6;
+   struct audit_buffer *audit_buf = NULL;
+   char *secctx = NULL;
+   u32 secctx_len;
 
if (addr_len != sizeof(struct in_addr) &&
addr_len != sizeof(struct in6_addr))
@@ -562,19 +569,25 @@ static int netlbl_unlhsh_add(struct net *net,
goto unlhsh_add_return;
}
}
+   audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCADD,
+ audit_info);
switch (addr_len) {
case sizeof(struct in_addr):
-   ret_val = netlbl_unlhsh_add_addr4(iface,
- (struct in_addr *)addr,
- (struct in_addr *)mask,
- secid);
+   addr4 = (struct in_addr *)addr;
+   mask4 = (struct in_addr *)mask;
+   ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid);
+   if (audit_buf != NULL)
+   audit_log_format(audit_buf, " daddr=" NIPQUAD_FMT,
+NIPQUAD(addr4->s_addr));
break;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
case sizeof(struct in6_addr):
-   ret_val = netlbl_unlhsh_add_addr6(iface,
- (struct in6_addr *)addr,
- (struct in6_addr *)mask,
- secid);
+   addr6 = (struct in6_addr *)addr;
+   mask6 = (struct in6_addr *)mask;
+   ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid);
+   if (audit_buf != NULL)
+   audit_log_format(audit_buf, " daddr= " NIP6_FMT,
+NIP6(*addr6));
break;
 #endif /* IPv6 */
default:
@@ -585,6 +598,16 @@ static int netlbl_unlhsh_add(struct net *net,
 
 unlhsh_add_return:
rcu_read_unlock();
+   if (audit_buf != NULL) {
+   if (security_secid_to_secctx(secid,
+&secctx,
+&secctx_len) == 0) {
+   audit_log_format(audit_buf, " sec_obj=%s", secctx);
+   security_release_secctx(secctx, secctx_len);
+   }
+   audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
+   audit_log_end(audit_buf);
+   }
return ret_val;
 }
 
@@ -593,6 +616,7 @@ unlhsh_add_return:
  * @iface: interface entry
  * @addr: IP address
  * @mask: IP address mask
+ * @audit_info: NetLabel audit information
  *
  * Description:
  * Remove an IP address entry from the unlabeled connection hash table.
@@ -602,10 +626,14 @@ unlhsh_add_return:
  */
 static int netlbl_unlhsh_remove_addr4(struct netlbl_unlhsh_iface *iface,
  const struct in_addr *addr,
- const struct in_addr *m

[RFC PATCH v6 04/13] NetLabel: Add secid token support to the NetLabel secattr struct

2007-11-09 Thread Paul Moore
This patch adds support to the NetLabel LSM secattr struct for a secid token
and a type field, paving the way for full LSM/SELinux context support and
"static" or "fallback" labels.  In addition, this patch adds a fair amount
of documentation to the core NetLabel structures used as part of the
NetLabel kernel API.
---

 include/net/netlabel.h|   91 ++---
 net/ipv4/cipso_ipv4.c |   59 +++-
 net/netlabel/netlabel_unlabeled.c |1 
 security/selinux/ss/mls.c |   10 ++--
 security/selinux/ss/services.c|5 ++
 5 files changed, 120 insertions(+), 46 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 2e5b2f6..18b73cf 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -105,17 +105,49 @@ struct netlbl_dom_map;
 /* Domain mapping operations */
 int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
 
-/* LSM security attributes */
+/*
+ * LSM security attributes
+ */
+
+/**
+ * struct netlbl_lsm_cache - NetLabel LSM security attribute cache
+ * @refcount: atomic reference counter
+ * @free: LSM supplied function to free the cache data
+ * @data: LSM supplied cache data
+ *
+ * Description:
+ * This structure is provided for LSMs which wish to make use of the NetLabel
+ * caching mechanism to store LSM specific data/attributes in the NetLabel
+ * cache.  If the LSM has to perform a lot of translation from the NetLabel
+ * security attributes into it's own internal representation then the cache
+ * mechanism can provide a way to eliminate some or all of that translation
+ * overhead on a cache hit.
+ *
+ */
 struct netlbl_lsm_cache {
atomic_t refcount;
void (*free) (const void *data);
void *data;
 };
-/* The catmap bitmap field MUST be a power of two in length and large
+
+/**
+ * struct netlbl_lsm_secattr_catmap - NetLabel LSM secattr category bitmap
+ * @startbit: the value of the lowest order bit in the bitmap
+ * @bitmap: the category bitmap
+ * @next: pointer to the next bitmap "node" or NULL
+ *
+ * Description:
+ * This structure is used to represent category bitmaps.  Due to the large
+ * number of categories supported by most labeling protocols it is not
+ * practical to transfer a full bitmap internally so NetLabel adopts a sparse
+ * bitmap structure modeled after SELinux's ebitmap structure.
+ * The catmap bitmap field MUST be a power of two in length and large
  * enough to hold at least 240 bits.  Special care (i.e. check the code!)
  * should be used when changing these values as the LSM implementation
  * probably has functions which rely on the sizes of these types to speed
- * processing. */
+ * processing.
+ *
+ */
 #define NETLBL_CATMAP_MAPTYPE   u64
 #define NETLBL_CATMAP_MAPCNT4
 #define NETLBL_CATMAP_MAPSIZE   (sizeof(NETLBL_CATMAP_MAPTYPE) * 8)
@@ -127,22 +159,48 @@ struct netlbl_lsm_secattr_catmap {
NETLBL_CATMAP_MAPTYPE bitmap[NETLBL_CATMAP_MAPCNT];
struct netlbl_lsm_secattr_catmap *next;
 };
+
+/**
+ * struct netlbl_lsm_secattr - NetLabel LSM security attributes
+ * @flags: indicate which attributes are contained in this structure
+ * @type: indicate the NLTYPE of the attributes
+ * @domain: the NetLabel LSM domain
+ * @cache: NetLabel LSM specific cache
+ * @attr.mls: MLS sensitivity label
+ * @attr.mls.cat: MLS category bitmap
+ * @attr.mls.lvl: MLS sensitivity level
+ * @attr.secid: LSM specific secid token
+ *
+ * Description:
+ * This structure is used to pass security attributes between NetLabel and the
+ * LSM modules.  The flags field is used to specify which fields within the
+ * struct are valid and valid values can be created by bitwise OR'ing the
+ * NETLBL_SECATTR_* defines.  The domain field is typically set by the LSM to
+ * specify domain specific configuration settings and is not usually used by
+ * NetLabel itself when returning security attributes to the LSM.
+ *
+ */
 #define NETLBL_SECATTR_NONE 0x
 #define NETLBL_SECATTR_DOMAIN   0x0001
 #define NETLBL_SECATTR_CACHE0x0002
 #define NETLBL_SECATTR_MLS_LVL  0x0004
 #define NETLBL_SECATTR_MLS_CAT  0x0008
+#define NETLBL_SECATTR_SECID0x0010
 #define NETLBL_SECATTR_CACHEABLE(NETLBL_SECATTR_MLS_LVL | \
-NETLBL_SECATTR_MLS_CAT)
+NETLBL_SECATTR_MLS_CAT | \
+NETLBL_SECATTR_SECID)
 struct netlbl_lsm_secattr {
u32 flags;
-
+   u32 type;
char *domain;
-
-   u32 mls_lvl;
-   struct netlbl_lsm_secattr_catmap *mls_cat;
-
struct netlbl_lsm_cache *cache;
+   union {
+   struct {
+   struct netlbl_lsm_secattr_catmap *cat;
+   u32 lvl;
+   } mls;
+   u32 secid;
+   } attr;
 };
 
 /*

[RFC PATCH v6 06/13] NetLabel: add IP address family information to the netlbl_skbuff_getattr() function

2007-11-09 Thread Paul Moore
In order to do any sort of IP header inspection of incoming packets we need to
know which address family, AF_INET/AF_INET6/etc., it belongs to and since the
sk_buff structure does not store this information we need to pass along the
address family separate from the packet itself.
---

 include/net/netlabel.h  |2 ++
 net/netlabel/netlabel_kapi.c|2 ++
 security/selinux/hooks.c|   24 ++--
 security/selinux/include/netlabel.h |8 +++-
 security/selinux/netlabel.c |   12 +---
 5 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 18b73cf..a3bffb4 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -363,6 +363,7 @@ int netlbl_sock_setattr(struct sock *sk,
 int netlbl_sock_getattr(struct sock *sk,
struct netlbl_lsm_secattr *secattr);
 int netlbl_skbuff_getattr(const struct sk_buff *skb,
+ u16 family,
  struct netlbl_lsm_secattr *secattr);
 void netlbl_skbuff_err(struct sk_buff *skb, int error);
 
@@ -415,6 +416,7 @@ static inline int netlbl_sock_getattr(struct sock *sk,
return -ENOSYS;
 }
 static inline int netlbl_skbuff_getattr(const struct sk_buff *skb,
+   u16 family,
struct netlbl_lsm_secattr *secattr)
 {
return -ENOSYS;
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index d3762ea..4914615 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -332,6 +332,7 @@ int netlbl_sock_getattr(struct sock *sk, struct 
netlbl_lsm_secattr *secattr)
 /**
  * netlbl_skbuff_getattr - Determine the security attributes of a packet
  * @skb: the packet
+ * @family: protocol family
  * @secattr: the security attributes
  *
  * Description:
@@ -342,6 +343,7 @@ int netlbl_sock_getattr(struct sock *sk, struct 
netlbl_lsm_secattr *secattr)
  *
  */
 int netlbl_skbuff_getattr(const struct sk_buff *skb,
+ u16 family,
  struct netlbl_lsm_secattr *secattr)
 {
if (CIPSO_V4_OPTEXIST(skb) &&
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8bb673b..2188b9c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3192,6 +3192,7 @@ static int selinux_parse_skb(struct sk_buff *skb, struct 
avc_audit_data *ad,
 /**
  * selinux_skb_extlbl_sid - Determine the external label of a packet
  * @skb: the packet
+ * @family: protocol family
  * @sid: the packet's SID
  *
  * Description:
@@ -3204,13 +3205,16 @@ static int selinux_parse_skb(struct sk_buff *skb, 
struct avc_audit_data *ad,
  * selinux_netlbl_skbuff_getsid().
  *
  */
-static void selinux_skb_extlbl_sid(struct sk_buff *skb, u32 *sid)
+static void selinux_skb_extlbl_sid(struct sk_buff *skb,
+  u16 family,
+  u32 *sid)
 {
u32 xfrm_sid;
u32 nlbl_sid;
 
selinux_skb_xfrm_sid(skb, &xfrm_sid);
if (selinux_netlbl_skbuff_getsid(skb,
+family,
 (xfrm_sid == SECSID_NULL ?
  SECINITSID_NETMSG : xfrm_sid),
 &nlbl_sid) != 0)
@@ -3703,7 +3707,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, 
struct sk_buff *skb)
if (err)
goto out;
 
-   err = selinux_netlbl_sock_rcv_skb(sksec, skb, &ad);
+   err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
if (err)
goto out;
 
@@ -3760,11 +3764,19 @@ static int selinux_socket_getpeersec_dgram(struct 
socket *sock, struct sk_buff *
 {
u32 peer_secid = SECSID_NULL;
int err = 0;
+   u16 family;
+
+   if (sock)
+   family = sock->sk->sk_family;
+   else if (skb->sk)
+   family = skb->sk->sk_family;
+   else
+   family = PF_UNSPEC;
 
-   if (sock && sock->sk->sk_family == PF_UNIX)
+   if (sock && family == PF_UNIX)
selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
else if (skb)
-   selinux_skb_extlbl_sid(skb, &peer_secid);
+   selinux_skb_extlbl_sid(skb, family, &peer_secid);
 
if (peer_secid == SECSID_NULL)
err = -EINVAL;
@@ -3825,7 +3837,7 @@ static int selinux_inet_conn_request(struct sock *sk, 
struct sk_buff *skb,
u32 newsid;
u32 peersid;
 
-   selinux_skb_extlbl_sid(skb, &peersid);
+   selinux_skb_extlbl_sid(skb, sk->sk_family, &peersid);
if (peersid == SECSID_NULL) {
req->secid = sksec->sid;
req->peer_secid = SECSID_NULL;
@@ -3863,7 +3875,7 @@ static void selinux_inet_conn_established(struct sock *sk,
 {
struct sk_security_struct *sksec = sk->sk_security;

[RFC PATCH v6 11/13] SELinux: allow NetLabel to directly cache SIDs

2007-11-09 Thread Paul Moore
Now that the SELinux NetLabel "base SID" is always the netmsg initial SID we
can do a big optimization - caching the SID and not just the MLS attributes.
This not only saves a lot of per-packet memory allocations and copies but it
has a nice side effect of removing a chunk of code.
---

 security/selinux/hooks.c|6 --
 security/selinux/include/netlabel.h |2 -
 security/selinux/include/security.h |2 -
 security/selinux/netlabel.c |   55 ++--
 security/selinux/ss/services.c  |  124 ++-
 5 files changed, 55 insertions(+), 134 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 6f4bea4..ac79ff4 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3231,11 +3231,7 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, 
u16 family, u32 *sid)
u32 nlbl_type;
 
selinux_skb_xfrm_sid(skb, &xfrm_sid);
-   selinux_netlbl_skbuff_getsid(skb,
-family,
-SECINITSID_NETMSG,
-&nlbl_type,
-&nlbl_sid);
+   selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
 
if (security_net_peersid_resolve(nlbl_sid, nlbl_type,
 xfrm_sid,
diff --git a/security/selinux/include/netlabel.h 
b/security/selinux/include/netlabel.h
index c8c05a6..00a2809 100644
--- a/security/selinux/include/netlabel.h
+++ b/security/selinux/include/netlabel.h
@@ -48,7 +48,6 @@ void selinux_netlbl_sk_security_clone(struct 
sk_security_struct *ssec,
 
 int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
 u16 family,
-u32 base_sid,
 u32 *type,
 u32 *sid);
 
@@ -89,7 +88,6 @@ static inline void selinux_netlbl_sk_security_clone(
 
 static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
   u16 family,
-  u32 base_sid,
   u32 *type,
   u32 *sid)
 {
diff --git a/security/selinux/include/security.h 
b/security/selinux/include/security.h
index fb807c1..4373a7e 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -125,7 +125,6 @@ int security_genfs_sid(const char *fstype, char *name, u16 
sclass,
 
 #ifdef CONFIG_NETLABEL
 int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
-  u32 base_sid,
   u32 *sid);
 
 int security_netlbl_sid_to_secattr(u32 sid,
@@ -133,7 +132,6 @@ int security_netlbl_sid_to_secattr(u32 sid,
 #else
 static inline int security_netlbl_secattr_to_sid(
struct netlbl_lsm_secattr *secattr,
-   u32 base_sid,
u32 *sid)
 {
return -EIDRM;
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index 6c194f9..ba4f3c8 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -36,6 +36,33 @@
 #include "security.h"
 
 /**
+ * selinux_netlbl_sidlookup_cached - Cache a SID lookup
+ * @skb: the packet
+ * @secattr: the NetLabel security attributes
+ * @sid: the SID
+ *
+ * Description:
+ * Query the SELinux security server to lookup the correct SID for the given
+ * security attributes.  If the query is successful, cache the result to speed
+ * up future lookups.  Returns zero on success, negative values on failure.
+ *
+ */
+static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
+  struct netlbl_lsm_secattr *secattr,
+  u32 *sid)
+{
+   int rc;
+
+   rc = security_netlbl_secattr_to_sid(secattr, sid);
+   if (rc == 0 &&
+   (secattr->flags & NETLBL_SECATTR_CACHEABLE) &&
+   (secattr->flags & NETLBL_SECATTR_CACHE))
+   netlbl_cache_add(skb, secattr);
+
+   return rc;
+}
+
+/**
  * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism
  * @sk: the socket to label
  * @sid: the SID to use
@@ -142,7 +169,6 @@ void selinux_netlbl_sk_security_clone(struct 
sk_security_struct *ssec,
  * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel
  * @skb: the packet
  * @family: protocol family
- * @base_sid: the SELinux SID to use as a context for MLS only attributes
  * @type: NetLabel labeling protocol type
  * @sid: the SID
  *
@@ -154,7 +180,6 @@ void selinux_netlbl_sk_security_clone(struct 
sk_security_struct *ssec,
  */
 int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
 u16 family,
-u3

[RFC PATCH v6 03/13] NetLabel: consolidate the LSM domain mapping/hashing locks

2007-11-09 Thread Paul Moore
Currently we use two separate spinlocks to protect both the hash/mapping table
and the default entry.  This could be considered a bit foolish because it adds
complexity without offering any real performance advantage.  This patch
removes the dedicated default spinlock and protects the default entry with the
hash/mapping table spinlock.
---

 net/netlabel/netlabel_domainhash.c |   30 +-
 1 files changed, 9 insertions(+), 21 deletions(-)

diff --git a/net/netlabel/netlabel_domainhash.c 
b/net/netlabel/netlabel_domainhash.c
index 1f8f7ac..9a8ea01 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -54,9 +54,6 @@ struct netlbl_domhsh_tbl {
  * hash table should be okay */
 static DEFINE_SPINLOCK(netlbl_domhsh_lock);
 static struct netlbl_domhsh_tbl *netlbl_domhsh = NULL;
-
-/* Default domain mapping */
-static DEFINE_SPINLOCK(netlbl_domhsh_def_lock);
 static struct netlbl_dom_map *netlbl_domhsh_def = NULL;
 
 /*
@@ -239,24 +236,22 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
INIT_RCU_HEAD(&entry->rcu);
 
rcu_read_lock();
+   spin_lock(&netlbl_domhsh_lock);
if (entry->domain != NULL) {
bkt = netlbl_domhsh_hash(entry->domain);
-   spin_lock(&netlbl_domhsh_lock);
if (netlbl_domhsh_search(entry->domain) == NULL)
list_add_tail_rcu(&entry->list,
&rcu_dereference(netlbl_domhsh)->tbl[bkt]);
else
ret_val = -EEXIST;
-   spin_unlock(&netlbl_domhsh_lock);
} else {
INIT_LIST_HEAD(&entry->list);
-   spin_lock(&netlbl_domhsh_def_lock);
if (rcu_dereference(netlbl_domhsh_def) == NULL)
rcu_assign_pointer(netlbl_domhsh_def, entry);
else
ret_val = -EEXIST;
-   spin_unlock(&netlbl_domhsh_def_lock);
}
+   spin_unlock(&netlbl_domhsh_lock);
audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
if (audit_buf != NULL) {
audit_log_format(audit_buf,
@@ -337,23 +332,16 @@ int netlbl_domhsh_remove(const char *domain, struct 
netlbl_audit *audit_info)
   entry->domain);
break;
}
-   if (entry != rcu_dereference(netlbl_domhsh_def)) {
-   spin_lock(&netlbl_domhsh_lock);
-   if (entry->valid) {
-   entry->valid = 0;
+   spin_lock(&netlbl_domhsh_lock);
+   if (entry->valid) {
+   entry->valid = 0;
+   if (entry != rcu_dereference(netlbl_domhsh_def))
list_del_rcu(&entry->list);
-   ret_val = 0;
-   }
-   spin_unlock(&netlbl_domhsh_lock);
-   } else {
-   spin_lock(&netlbl_domhsh_def_lock);
-   if (entry->valid) {
-   entry->valid = 0;
+   else
rcu_assign_pointer(netlbl_domhsh_def, NULL);
-   ret_val = 0;
-   }
-   spin_unlock(&netlbl_domhsh_def_lock);
+   ret_val = 0;
}
+   spin_unlock(&netlbl_domhsh_lock);
 
audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info);
if (audit_buf != NULL) {

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v6 09/13] SELinux: Better integration between peer labeling subsystems

2007-11-09 Thread Paul Moore
Rename the existing selinux_skb_extlbl_sid() function to
selinux_skb_peerlbl_sid() and modify it's behavior such that it now reconciles
multiple peer/external labels and if reconciliation is not possible it returns
an error to the caller.
---

 security/selinux/hooks.c|   94 ++-
 security/selinux/include/netlabel.h |3 +
 security/selinux/include/security.h |4 +
 security/selinux/netlabel.c |3 +
 security/selinux/ss/services.c  |   85 
 5 files changed, 154 insertions(+), 35 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2188b9c..4d13a80 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3190,36 +3190,39 @@ static int selinux_parse_skb(struct sk_buff *skb, 
struct avc_audit_data *ad,
 }
 
 /**
- * selinux_skb_extlbl_sid - Determine the external label of a packet
+ * selinux_skb_peerlbl_sid - Determine the peer label of a packet
  * @skb: the packet
  * @family: protocol family
- * @sid: the packet's SID
+ * @sid: the packet's peer label SID
  *
  * Description:
- * Check the various different forms of external packet labeling and determine
- * the external SID for the packet.  If only one form of external labeling is
- * present then it is used, if both labeled IPsec and NetLabel labels are
- * present then the SELinux type information is taken from the labeled IPsec
- * SA and the MLS sensitivity label information is taken from the NetLabel
- * security attributes.  This bit of "magic" is done in the call to
- * selinux_netlbl_skbuff_getsid().
+ * Check the various different forms of network peer labeling and determine
+ * the peer label/SID for the packet; most of the magic actually occurs in
+ * the security server function security_net_peersid_cmp().  The function
+ * returns zero if the value in @sid is valid (although it may be SECSID_NULL)
+ * or -EACCES if @sid is invalid due to inconsistencies with the different
+ * peer labels.
  *
  */
-static void selinux_skb_extlbl_sid(struct sk_buff *skb,
-  u16 family,
-  u32 *sid)
+static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
 {
u32 xfrm_sid;
u32 nlbl_sid;
+   u32 nlbl_type;
 
selinux_skb_xfrm_sid(skb, &xfrm_sid);
-   if (selinux_netlbl_skbuff_getsid(skb,
-family,
-(xfrm_sid == SECSID_NULL ?
- SECINITSID_NETMSG : xfrm_sid),
-&nlbl_sid) != 0)
-   nlbl_sid = SECSID_NULL;
-   *sid = (nlbl_sid == SECSID_NULL ? xfrm_sid : nlbl_sid);
+   selinux_netlbl_skbuff_getsid(skb,
+family,
+SECINITSID_NETMSG,
+&nlbl_type,
+&nlbl_sid);
+
+   if (security_net_peersid_resolve(nlbl_sid, nlbl_type,
+xfrm_sid,
+sid) != 0)
+   return -EACCES;
+
+   return 0;
 }
 
 /* socket security operations */
@@ -3674,17 +3677,32 @@ out:
return err;
 }
 
+static int selinux_sock_recv_peer_compat(struct sk_security_struct *sksec,
+struct sk_buff *skb,
+u16 family,
+struct avc_audit_data ad)
+{
+   int err;
+
+   err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
+   if (err)
+   return err;
+
+   return selinux_xfrm_sock_rcv_skb(sksec->sid, skb, &ad);
+}
+
 static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
 {
-   u16 family;
+   u16 family = sk->sk_family;
char *addrp;
-   int len, err = 0;
+   int len;
+   int err;
struct avc_audit_data ad;
struct sk_security_struct *sksec = sk->sk_security;
+   int peer_sid;
 
-   family = sk->sk_family;
if (family != PF_INET && family != PF_INET6)
-   goto out;
+   return 0;
 
/* Handle mapped IPv4 packets arriving via IPv6 sockets */
if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
@@ -3693,10 +3711,14 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, 
struct sk_buff *skb)
AVC_AUDIT_DATA_INIT(&ad, NET);
ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]";
ad.u.net.family = family;
-
err = selinux_parse_skb(skb, &ad, &addrp, &len, 1, NULL);
if (err)
-   goto out;
+   return err;
+
+   /* Between selinux_compat_net and selinux_policycap_netpeer this is
+* starting to get a bit messy - we need to setup a timetable for
+* deprecating some of this old/obsolete functiona

Re: [RFC PATCH v6 05/13] SELinux: add secctx_to_secid() LSM hook

2007-11-09 Thread Paul Moore
On Friday 09 November 2007 5:19:02 pm Casey Schaufler wrote:
> --- Paul Moore <[EMAIL PROTECTED]> wrote:
> > Add a secctx_to_secid() LSM hook to go along with the existing
> > secid_to_secctx() LSM hook.
>
> I'll bite. Where does this get used?

Patch 12/13, functions netlbl_unlabel_staticadd() and 
netlbl_unlabel_staticadddef().  It is used to convert a user supplied label 
into a token which is later passed to the LSM; in the SELinux case it is used 
directly in an avc_has_perm() call.

Go ahead and check, I'll wait ... just please don't bring up the whole 
getpeercon() issue (essentially the example you chose, although you picked 
the connectionless version) again.  Worrying about something that typically 
happens only once (if at all) per-connection is not something I want to worry 
about optimizing if it causes the per-packet case to become more tedious.

> There. I got the righteous indignation off my chest. I say to
> go ahead with adding this to the LSM ... {snip}

Sigh.  I agree, the whole tokenized label concept is conceptually very 
annoying and I'll also agree that it can be frustrating for certain 
implementations.  However, the world we live in (the Linux kernel) makes use 
of these tokenized labels (secid, SID, etc) because it's all the original LSM 
folks could get in some places.  The fact that this works fine with SELinux 
(actually works better than fine in some cases) is a happy coincidence and 
probably the reason things haven't changed much.

I _really_ don't want to get into the "one true security model" debate, but 
the fact remains that as long as SELinux is the only LSM implementation in 
the mainline kernel there is no reason to change this.  If/when SMACK (this 
is really the immediate source of the "righteous indignation" after all, 
right?) is merged then it will probably make sense to go revisit some of 
those earlier decisions regarding these tokenized labels.  For me personally, 
right now I'm just concerned about making sure the labeled networking bits 
work as well as we can make them work; with SELinux that means using a 
secid/SID to speed up the per-packet access checks.  For SMACK, this will 
probably mean passing the actual string label.  You and I have already talked 
about this so _you_know_ there is a SMACK friendly solution to the 
fallback/static label functionality; I just can't justify adding code that 
serves no purpose in the context (haha!) of the current kernel sources.

You know all this Casey, so I have no idea where all of these comments are 
coming from - bad day at work?  Somebody run over your dog?  Well, go home, 
have a beer and forget about it for right now.  Get SMACK merged, or any 
other LSM which highlights the same problem, and we can put that "righteous 
indignation" to good use; right now, it's just plan tiresome.

> In Linux 2.7 I propose that we fix these problems. Not today.

Un huh ... in the meantime I'm gonna work with what I have :)

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v6 08/13] SELinux: Add new peer permissions to the Flask definitions

2007-11-12 Thread Paul Moore
On Sunday 11 November 2007 5:31:44 pm James Morris wrote:
> On Fri, 9 Nov 2007, Paul Moore wrote:
> > Add additional Flask definitions to support the new "peer" object class.
>
> Should this be dependent on dynamic class/permission support?

I think it's okay to _define_ the Flask definitions regardless of what the 
policy supports as older policies should simply ignore these definitions.

> Or, will these checks only be invoked if labled networking is configured?

Bingo!  Look at patch 7/13, specifically the 'selinux_policycap_netpeer' 
variable and then at patch 9/13 where the new access checks are made 
conditional on this variable.  The whole mess needs more testing and 
verification, but "in theory" it shouldn't cause any breakage with older 
policies ... if someone does notice something broken please scream loudly.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v6 09/13] SELinux: Better integration between peer labeling subsystems

2007-11-12 Thread Paul Moore
On Sunday 11 November 2007 5:34:27 pm James Morris wrote:
> On Fri, 9 Nov 2007, Paul Moore wrote:
> > +   /* Between selinux_compat_net and selinux_policycap_netpeer this is
> > +* starting to get a bit messy - we need to setup a timetable for
> > +* deprecating some of this old/obsolete functionality so we can
> > +* reclaim some level of sanity in this function. */
>
> I don't think we can do anything which could potentially break userspace
> now.

Yeah, I've already had one very long day as a result of that, I'm not in any 
hurry to do that again :)

On a serious note, I thought we could remove specific features after a certain 
period of time, i.e. Documentation/feature-removal-schedule.txt?  My thought 
is that eventually we can at least remove compat_net, or is that too drastic?

> So, this one really needs to be right :-)

Yeah, this is the one thing that still worries me and one of the main reasons 
I keep pushing RFC patches so often.

Personally, I'm still a little frustrated at how ugly that function looks.  
I'm debating putting a check near the top to see if any of 
the "compatibility" flags are set, meaning an older policy, and if it is just 
handing off control to a compat function which handles all the ugliness.  
There might be some duplication of code but the sock_rcv_skb() function would 
be _much_ cleaner and faster in the "current policy" case.

Actually, I think I just talked myself into it ...

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v7 05/13] SELinux: add secctx_to_secid() LSM hook

2007-11-15 Thread Paul Moore
Add a secctx_to_secid() LSM hook to go along with the existing
secid_to_secctx() LSM hook.  This patch also includes a SELinux implementation
for this hook.
---

 include/linux/security.h |   13 +
 security/dummy.c |6 ++
 security/security.c  |6 ++
 security/selinux/hooks.c |6 ++
 4 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index ac05083..db19c92 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1183,6 +1183,10 @@ struct request_sock;
  * Convert secid to security context.
  * @secid contains the security ID.
  * @secdata contains the pointer that stores the converted security 
context.
+ * @secctx_to_secid:
+ *  Convert security context to secid.
+ *  @secid contains the pointer to the generated security ID.
+ *  @secdata contains the security context.
  *
  * @release_secctx:
  * Release the security context.
@@ -1371,6 +1375,7 @@ struct security_operations {
int (*getprocattr)(struct task_struct *p, char *name, char **value);
int (*setprocattr)(struct task_struct *p, char *name, void *value, 
size_t size);
int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen);
+   int (*secctx_to_secid)(char *secdata, u32 seclen, u32 *secid);
void (*release_secctx)(char *secdata, u32 seclen);
 
 #ifdef CONFIG_SECURITY_NETWORK
@@ -1603,6 +1608,7 @@ int security_setprocattr(struct task_struct *p, char 
*name, void *value, size_t
 int security_netlink_send(struct sock *sk, struct sk_buff *skb);
 int security_netlink_recv(struct sk_buff *skb, int cap);
 int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
+int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid);
 void security_release_secctx(char *secdata, u32 seclen);
 
 #else /* CONFIG_SECURITY */
@@ -2280,6 +2286,13 @@ static inline int security_secid_to_secctx(u32 secid, 
char **secdata, u32 *secle
return -EOPNOTSUPP;
 }
 
+static inline int security_secctx_to_secid(char *secdata,
+  u32 seclen,
+  u32 *secid)
+{
+   return -EOPNOTSUPP;
+}
+
 static inline void security_release_secctx(char *secdata, u32 seclen)
 {
 }
diff --git a/security/dummy.c b/security/dummy.c
index 6d895ad..767d5a7 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -928,6 +928,11 @@ static int dummy_secid_to_secctx(u32 secid, char 
**secdata, u32 *seclen)
return -EOPNOTSUPP;
 }
 
+static int dummy_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
+{
+   return -EOPNOTSUPP;
+}
+
 static void dummy_release_secctx(char *secdata, u32 seclen)
 {
 }
@@ -1086,6 +1091,7 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, getprocattr);
set_to_dummy_if_null(ops, setprocattr);
set_to_dummy_if_null(ops, secid_to_secctx);
+   set_to_dummy_if_null(ops, secctx_to_secid);
set_to_dummy_if_null(ops, release_secctx);
 #ifdef CONFIG_SECURITY_NETWORK
set_to_dummy_if_null(ops, unix_stream_connect);
diff --git a/security/security.c b/security/security.c
index 0e1f1f1..3bdcada 100644
--- a/security/security.c
+++ b/security/security.c
@@ -816,6 +816,12 @@ int security_secid_to_secctx(u32 secid, char **secdata, 
u32 *seclen)
 }
 EXPORT_SYMBOL(security_secid_to_secctx);
 
+int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
+{
+   return security_ops->secctx_to_secid(secdata, seclen, secid);
+}
+EXPORT_SYMBOL(security_secctx_to_secid);
+
 void security_release_secctx(char *secdata, u32 seclen)
 {
return security_ops->release_secctx(secdata, seclen);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9f3124b..8bb673b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4710,6 +4710,11 @@ static int selinux_secid_to_secctx(u32 secid, char 
**secdata, u32 *seclen)
return security_sid_to_context(secid, secdata, seclen);
 }
 
+static int selinux_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
+{
+   return security_context_to_sid(secdata, seclen, secid);
+}
+
 static void selinux_release_secctx(char *secdata, u32 seclen)
 {
kfree(secdata);
@@ -4898,6 +4903,7 @@ static struct security_operations selinux_ops = {
.setprocattr =  selinux_setprocattr,
 
.secid_to_secctx =  selinux_secid_to_secctx,
+   .secctx_to_secid =  selinux_secctx_to_secid,
.release_secctx =   selinux_release_secctx,
 
 .unix_stream_connect = selinux_socket_unix_stream_connect,

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v7 08/13] SELinux: Add new peer permissions to the Flask definitions

2007-11-15 Thread Paul Moore
Add additional Flask definitions to support the new "peer" object class.
---

 security/selinux/include/av_perm_to_string.h |3 +++
 security/selinux/include/av_permissions.h|3 +++
 security/selinux/include/class_to_string.h   |7 +++
 security/selinux/include/flask.h |1 +
 4 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/security/selinux/include/av_perm_to_string.h 
b/security/selinux/include/av_perm_to_string.h
index 049bf69..1d56a6a 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -159,3 +159,6 @@
S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NODE_BIND, "node_bind")
S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NAME_CONNECT, "name_connect")
S_(SECCLASS_MEMPROTECT, MEMPROTECT__MMAP_ZERO, "mmap_zero")
+   S_(SECCLASS_PEER, PEER__FLOW_IN, "flow_in")
+   S_(SECCLASS_PEER, PEER__FLOW_OUT, "flow_out")
+   S_(SECCLASS_PEER, PEER__RECV, "recv")
diff --git a/security/selinux/include/av_permissions.h 
b/security/selinux/include/av_permissions.h
index eda89a2..95d4674 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -824,3 +824,6 @@
 #define DCCP_SOCKET__NODE_BIND0x0040UL
 #define DCCP_SOCKET__NAME_CONNECT 0x0080UL
 #define MEMPROTECT__MMAP_ZERO 0x0001UL
+#define PEER__FLOW_IN 0x0001UL
+#define PEER__FLOW_OUT0x0002UL
+#define PEER__RECV0x0004UL
diff --git a/security/selinux/include/class_to_string.h 
b/security/selinux/include/class_to_string.h
index e77de0e..b1b0d1d 100644
--- a/security/selinux/include/class_to_string.h
+++ b/security/selinux/include/class_to_string.h
@@ -64,3 +64,10 @@
 S_(NULL)
 S_("dccp_socket")
 S_("memprotect")
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_("peer")
diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h
index a9c2b20..09e9dd2 100644
--- a/security/selinux/include/flask.h
+++ b/security/selinux/include/flask.h
@@ -50,6 +50,7 @@
 #define SECCLASS_KEY 58
 #define SECCLASS_DCCP_SOCKET 60
 #define SECCLASS_MEMPROTECT  61
+#define SECCLASS_PEER68
 
 /*
  * Security identifier indices for initial entities

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v7 03/13] NetLabel: consolidate the LSM domain mapping/hashing locks

2007-11-15 Thread Paul Moore
Currently we use two separate spinlocks to protect both the hash/mapping table
and the default entry.  This could be considered a bit foolish because it adds
complexity without offering any real performance advantage.  This patch
removes the dedicated default spinlock and protects the default entry with the
hash/mapping table spinlock.
---

 net/netlabel/netlabel_domainhash.c |   30 +-
 1 files changed, 9 insertions(+), 21 deletions(-)

diff --git a/net/netlabel/netlabel_domainhash.c 
b/net/netlabel/netlabel_domainhash.c
index 1f8f7ac..9a8ea01 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -54,9 +54,6 @@ struct netlbl_domhsh_tbl {
  * hash table should be okay */
 static DEFINE_SPINLOCK(netlbl_domhsh_lock);
 static struct netlbl_domhsh_tbl *netlbl_domhsh = NULL;
-
-/* Default domain mapping */
-static DEFINE_SPINLOCK(netlbl_domhsh_def_lock);
 static struct netlbl_dom_map *netlbl_domhsh_def = NULL;
 
 /*
@@ -239,24 +236,22 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
INIT_RCU_HEAD(&entry->rcu);
 
rcu_read_lock();
+   spin_lock(&netlbl_domhsh_lock);
if (entry->domain != NULL) {
bkt = netlbl_domhsh_hash(entry->domain);
-   spin_lock(&netlbl_domhsh_lock);
if (netlbl_domhsh_search(entry->domain) == NULL)
list_add_tail_rcu(&entry->list,
&rcu_dereference(netlbl_domhsh)->tbl[bkt]);
else
ret_val = -EEXIST;
-   spin_unlock(&netlbl_domhsh_lock);
} else {
INIT_LIST_HEAD(&entry->list);
-   spin_lock(&netlbl_domhsh_def_lock);
if (rcu_dereference(netlbl_domhsh_def) == NULL)
rcu_assign_pointer(netlbl_domhsh_def, entry);
else
ret_val = -EEXIST;
-   spin_unlock(&netlbl_domhsh_def_lock);
}
+   spin_unlock(&netlbl_domhsh_lock);
audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
if (audit_buf != NULL) {
audit_log_format(audit_buf,
@@ -337,23 +332,16 @@ int netlbl_domhsh_remove(const char *domain, struct 
netlbl_audit *audit_info)
   entry->domain);
break;
}
-   if (entry != rcu_dereference(netlbl_domhsh_def)) {
-   spin_lock(&netlbl_domhsh_lock);
-   if (entry->valid) {
-   entry->valid = 0;
+   spin_lock(&netlbl_domhsh_lock);
+   if (entry->valid) {
+   entry->valid = 0;
+   if (entry != rcu_dereference(netlbl_domhsh_def))
list_del_rcu(&entry->list);
-   ret_val = 0;
-   }
-   spin_unlock(&netlbl_domhsh_lock);
-   } else {
-   spin_lock(&netlbl_domhsh_def_lock);
-   if (entry->valid) {
-   entry->valid = 0;
+   else
rcu_assign_pointer(netlbl_domhsh_def, NULL);
-   ret_val = 0;
-   }
-   spin_unlock(&netlbl_domhsh_def_lock);
+   ret_val = 0;
}
+   spin_unlock(&netlbl_domhsh_lock);
 
audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info);
if (audit_buf != NULL) {

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v7 00/13] Labeled networking patches for 2.6.25

2007-11-15 Thread Paul Moore
This is a relatively minor update to the previous, "v6", patchset which the
main difference being an attempt at cleaning up all of the compatibility
code in the SELinux networking hooks.  The patches might look a bit ugly
but I believe the resulting code is much cleaner than in "v6" and should be
easier to understand/maintain in the long run.  I also took the opportunity
to update the SELinux compat_net code to make better use of the socket's
security struct which allows us to do away with the spinlock in
sock_rcv_skb() and cleanup some of that code.

I've updated the git tree last night with these bits backed against Linus'
latest which includes the ebitmap patch needed with "v6".  The git tree can
be found here:

 * git://git.infradead.org/users/pcmoore/lblnet-2.6_testing

There have also been a few small bugfixes to the static_label branch of
netlabel_tools.  For those of you who are playing with this code I recommend
you update to r50 to get the latest bits.

As usual, if you have any comments/bug-reports/questions let me know.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v7 01/13] NetLabel: remove unneeded RCU read locks

2007-11-15 Thread Paul Moore
This patch removes some unneeded RCU read locks as we can treat the reads as
"safe" even without RCU.  It also converts the NetLabel configuration refcount
from a spinlock protected u32 into atomic_t to be more consistent with the rest
of the kernel.
---

 net/netlabel/netlabel_cipso_v4.c  |5 ++-
 net/netlabel/netlabel_kapi.c  |3 +-
 net/netlabel/netlabel_mgmt.c  |   63 ++---
 net/netlabel/netlabel_mgmt.h  |7 ++--
 net/netlabel/netlabel_unlabeled.c |   17 ++
 5 files changed, 15 insertions(+), 80 deletions(-)

diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index ba0ca8d..becf91a 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "netlabel_user.h"
 #include "netlabel_cipso_v4.h"
@@ -421,7 +422,7 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct 
genl_info *info)
break;
}
if (ret_val == 0)
-   netlbl_mgmt_protocount_inc();
+   atomic_inc(&netlabel_mgmt_protocount);
 
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
  &audit_info);
@@ -698,7 +699,7 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, 
struct genl_info *info)
  &audit_info,
  netlbl_cipsov4_doi_free);
if (ret_val == 0)
-   netlbl_mgmt_protocount_dec();
+   atomic_dec(&netlabel_mgmt_protocount);
 
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
  &audit_info);
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 4f50949..d3762ea 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "netlabel_domainhash.h"
 #include "netlabel_unlabeled.h"
@@ -262,7 +263,7 @@ int netlbl_enabled(void)
/* At some point we probably want to expose this mechanism to the user
 * as well so that admins can toggle NetLabel regardless of the
 * configuration */
-   return (netlbl_mgmt_protocount_value() > 0 ? 1 : 0);
+   return (atomic_read(&netlabel_mgmt_protocount) > 0);
 }
 
 /**
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index 5648337..e2258dc 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -37,14 +37,14 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "netlabel_domainhash.h"
 #include "netlabel_user.h"
 #include "netlabel_mgmt.h"
 
-/* NetLabel configured protocol count */
-static DEFINE_SPINLOCK(netlabel_mgmt_protocount_lock);
-static u32 netlabel_mgmt_protocount = 0;
+/* NetLabel configured protocol counter */
+atomic_t netlabel_mgmt_protocount = ATOMIC_INIT(0);
 
 /* Argument struct for netlbl_domhsh_walk() */
 struct netlbl_domhsh_walk_arg {
@@ -71,63 +71,6 @@ static const struct nla_policy 
netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
 };
 
 /*
- * NetLabel Misc Managment Functions
- */
-
-/**
- * netlbl_mgmt_protocount_inc - Increment the configured labeled protocol count
- *
- * Description:
- * Increment the number of labeled protocol configurations in the current
- * NetLabel configuration.  Keep track of this for use in determining if
- * NetLabel label enforcement should be active/enabled or not in the LSM.
- *
- */
-void netlbl_mgmt_protocount_inc(void)
-{
-   spin_lock(&netlabel_mgmt_protocount_lock);
-   netlabel_mgmt_protocount++;
-   spin_unlock(&netlabel_mgmt_protocount_lock);
-}
-
-/**
- * netlbl_mgmt_protocount_dec - Decrement the configured labeled protocol count
- *
- * Description:
- * Decrement the number of labeled protocol configurations in the current
- * NetLabel configuration.  Keep track of this for use in determining if
- * NetLabel label enforcement should be active/enabled or not in the LSM.
- *
- */
-void netlbl_mgmt_protocount_dec(void)
-{
-   spin_lock(&netlabel_mgmt_protocount_lock);
-   if (netlabel_mgmt_protocount > 0)
-   netlabel_mgmt_protocount--;
-   spin_unlock(&netlabel_mgmt_protocount_lock);
-}
-
-/**
- * netlbl_mgmt_protocount_value - Return the number of configured protocols
- *
- * Description:
- * Return the number of labeled protocols in the current NetLabel
- * configuration.  This value is useful in  determining if NetLabel label
- * enforcement should be active/enabled or not in the LSM.
- *
- */
-u32 netlbl_mgmt_protocount_value(void)
-{
-   u32 val;
-
-   rcu_read_lock();
-   val = netlabel_mgmt_protocount;
-   rcu_read_unlock();
-
-   return val;
-}
-
-/*
  * NetLabel Command Handlers
  */
 
diff --git a/net/netlabel/netlabel_mgmt.h b/net/netlabel/netlabel_mgmt.h
index ccb2b39..a43bff1 100644
--- a/net/netlabel/netlabel_mgmt.h
+++

[RFC PATCH v7 02/13] NetLabel: cleanup the LSM domain hash functions

2007-11-15 Thread Paul Moore
The NetLabel/LSM domain hash table search function used a argument to specify
if the default entry should be returned if an exact match couldn't be found in
the hash table.  This is a bit against the kernel's style so make two separate
functions to represent the separate behaviors.
---

 net/netlabel/netlabel_domainhash.c |   47 ++--
 1 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/net/netlabel/netlabel_domainhash.c 
b/net/netlabel/netlabel_domainhash.c
index b3675bd..1f8f7ac 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -109,17 +109,14 @@ static u32 netlbl_domhsh_hash(const char *key)
 /**
  * netlbl_domhsh_search - Search for a domain entry
  * @domain: the domain
- * @def: return default if no match is found
  *
  * Description:
  * Searches the domain hash table and returns a pointer to the hash table
- * entry if found, otherwise NULL is returned.  If @def is non-zero and a
- * match is not found in the domain hash table the default mapping is returned
- * if it exists.  The caller is responsibile for the rcu hash table locks
- * (i.e. the caller much call rcu_read_[un]lock()).
+ * entry if found, otherwise NULL is returned.  The caller is responsibile for
+ * the rcu hash table locks (i.e. the caller much call rcu_read_[un]lock()).
  *
  */
-static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain, u32 def)
+static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
 {
u32 bkt;
struct netlbl_dom_map *iter;
@@ -133,10 +130,31 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const 
char *domain, u32 def)
return iter;
}
 
-   if (def != 0) {
-   iter = rcu_dereference(netlbl_domhsh_def);
-   if (iter != NULL && iter->valid)
-   return iter;
+   return NULL;
+}
+
+/**
+ * netlbl_domhsh_search_def - Search for a domain entry
+ * @domain: the domain
+ * @def: return default if no match is found
+ *
+ * Description:
+ * Searches the domain hash table and returns a pointer to the hash table
+ * entry if an exact match is found, if an exact match is not present in the
+ * hash table then the default entry is returned if valid otherwise NULL is
+ * returned.  The caller is responsibile for the rcu hash table locks
+ * (i.e. the caller much call rcu_read_[un]lock()).
+ *
+ */
+static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
+{
+   struct netlbl_dom_map *entry;
+
+   entry = netlbl_domhsh_search(domain);
+   if (entry == NULL) {
+   entry = rcu_dereference(netlbl_domhsh_def);
+   if (entry != NULL && entry->valid)
+   return entry;
}
 
return NULL;
@@ -224,7 +242,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
if (entry->domain != NULL) {
bkt = netlbl_domhsh_hash(entry->domain);
spin_lock(&netlbl_domhsh_lock);
-   if (netlbl_domhsh_search(entry->domain, 0) == NULL)
+   if (netlbl_domhsh_search(entry->domain) == NULL)
list_add_tail_rcu(&entry->list,
&rcu_dereference(netlbl_domhsh)->tbl[bkt]);
else
@@ -307,7 +325,10 @@ int netlbl_domhsh_remove(const char *domain, struct 
netlbl_audit *audit_info)
struct audit_buffer *audit_buf;
 
rcu_read_lock();
-   entry = netlbl_domhsh_search(domain, (domain != NULL ? 0 : 1));
+   if (domain)
+   entry = netlbl_domhsh_search(domain);
+   else
+   entry = netlbl_domhsh_search_def(domain);
if (entry == NULL)
goto remove_return;
switch (entry->type) {
@@ -377,7 +398,7 @@ int netlbl_domhsh_remove_default(struct netlbl_audit 
*audit_info)
  */
 struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain)
 {
-   return netlbl_domhsh_search(domain, 1);
+   return netlbl_domhsh_search_def(domain);
 }
 
 /**

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v7 04/13] NetLabel: Add secid token support to the NetLabel secattr struct

2007-11-15 Thread Paul Moore
This patch adds support to the NetLabel LSM secattr struct for a secid token
and a type field, paving the way for full LSM/SELinux context support and
"static" or "fallback" labels.  In addition, this patch adds a fair amount
of documentation to the core NetLabel structures used as part of the
NetLabel kernel API.
---

 include/net/netlabel.h|   91 ++---
 net/ipv4/cipso_ipv4.c |   59 +++-
 net/netlabel/netlabel_unlabeled.c |1 
 security/selinux/ss/mls.c |   10 ++--
 security/selinux/ss/services.c|5 ++
 5 files changed, 120 insertions(+), 46 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 2e5b2f6..18b73cf 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -105,17 +105,49 @@ struct netlbl_dom_map;
 /* Domain mapping operations */
 int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
 
-/* LSM security attributes */
+/*
+ * LSM security attributes
+ */
+
+/**
+ * struct netlbl_lsm_cache - NetLabel LSM security attribute cache
+ * @refcount: atomic reference counter
+ * @free: LSM supplied function to free the cache data
+ * @data: LSM supplied cache data
+ *
+ * Description:
+ * This structure is provided for LSMs which wish to make use of the NetLabel
+ * caching mechanism to store LSM specific data/attributes in the NetLabel
+ * cache.  If the LSM has to perform a lot of translation from the NetLabel
+ * security attributes into it's own internal representation then the cache
+ * mechanism can provide a way to eliminate some or all of that translation
+ * overhead on a cache hit.
+ *
+ */
 struct netlbl_lsm_cache {
atomic_t refcount;
void (*free) (const void *data);
void *data;
 };
-/* The catmap bitmap field MUST be a power of two in length and large
+
+/**
+ * struct netlbl_lsm_secattr_catmap - NetLabel LSM secattr category bitmap
+ * @startbit: the value of the lowest order bit in the bitmap
+ * @bitmap: the category bitmap
+ * @next: pointer to the next bitmap "node" or NULL
+ *
+ * Description:
+ * This structure is used to represent category bitmaps.  Due to the large
+ * number of categories supported by most labeling protocols it is not
+ * practical to transfer a full bitmap internally so NetLabel adopts a sparse
+ * bitmap structure modeled after SELinux's ebitmap structure.
+ * The catmap bitmap field MUST be a power of two in length and large
  * enough to hold at least 240 bits.  Special care (i.e. check the code!)
  * should be used when changing these values as the LSM implementation
  * probably has functions which rely on the sizes of these types to speed
- * processing. */
+ * processing.
+ *
+ */
 #define NETLBL_CATMAP_MAPTYPE   u64
 #define NETLBL_CATMAP_MAPCNT4
 #define NETLBL_CATMAP_MAPSIZE   (sizeof(NETLBL_CATMAP_MAPTYPE) * 8)
@@ -127,22 +159,48 @@ struct netlbl_lsm_secattr_catmap {
NETLBL_CATMAP_MAPTYPE bitmap[NETLBL_CATMAP_MAPCNT];
struct netlbl_lsm_secattr_catmap *next;
 };
+
+/**
+ * struct netlbl_lsm_secattr - NetLabel LSM security attributes
+ * @flags: indicate which attributes are contained in this structure
+ * @type: indicate the NLTYPE of the attributes
+ * @domain: the NetLabel LSM domain
+ * @cache: NetLabel LSM specific cache
+ * @attr.mls: MLS sensitivity label
+ * @attr.mls.cat: MLS category bitmap
+ * @attr.mls.lvl: MLS sensitivity level
+ * @attr.secid: LSM specific secid token
+ *
+ * Description:
+ * This structure is used to pass security attributes between NetLabel and the
+ * LSM modules.  The flags field is used to specify which fields within the
+ * struct are valid and valid values can be created by bitwise OR'ing the
+ * NETLBL_SECATTR_* defines.  The domain field is typically set by the LSM to
+ * specify domain specific configuration settings and is not usually used by
+ * NetLabel itself when returning security attributes to the LSM.
+ *
+ */
 #define NETLBL_SECATTR_NONE 0x
 #define NETLBL_SECATTR_DOMAIN   0x0001
 #define NETLBL_SECATTR_CACHE0x0002
 #define NETLBL_SECATTR_MLS_LVL  0x0004
 #define NETLBL_SECATTR_MLS_CAT  0x0008
+#define NETLBL_SECATTR_SECID0x0010
 #define NETLBL_SECATTR_CACHEABLE(NETLBL_SECATTR_MLS_LVL | \
-NETLBL_SECATTR_MLS_CAT)
+NETLBL_SECATTR_MLS_CAT | \
+NETLBL_SECATTR_SECID)
 struct netlbl_lsm_secattr {
u32 flags;
-
+   u32 type;
char *domain;
-
-   u32 mls_lvl;
-   struct netlbl_lsm_secattr_catmap *mls_cat;
-
struct netlbl_lsm_cache *cache;
+   union {
+   struct {
+   struct netlbl_lsm_secattr_catmap *cat;
+   u32 lvl;
+   } mls;
+   u32 secid;
+   } attr;
 };
 
 /*

[RFC PATCH v7 10/13] SELinux: Enable dynamic enable/disable of the network access checks

2007-11-15 Thread Paul Moore
This patch introduces a mechanism for checking when labeled IPsec or SECMARK
are in use by keeping introducing a configuration reference counter for each
subsystem.  In the case of labeled IPsec, whenever a labeled SA or SPD entry
is created the labeled IPsec/XFRM reference count is increased and when the
entry is removed it is decreased.  In the case of SECMARK, when a SECMARK
target is created the reference count is increased and later decreased when the
target is removed.  These reference counters allow SELinux to quickly determine
if either of these subsystems are enabled.

NetLabel already has a similar mechanism which provides the netlbl_enabled()
function.

This patch also renames the selinux_relabel_packet_permission() function to
selinux_secmark_relabel_packet_permission() as the original name and
description were misleading in that they referenced a single packet label which
is not the case.
---

 include/linux/selinux.h |   45 ---
 net/netfilter/xt_SECMARK.c  |   13 ++-
 security/selinux/exports.c  |   20 -
 security/selinux/hooks.c|   45 ---
 security/selinux/include/xfrm.h |   17 +++
 security/selinux/xfrm.c |   18 ++--
 6 files changed, 137 insertions(+), 21 deletions(-)

diff --git a/include/linux/selinux.h b/include/linux/selinux.h
index d1b7ca6..691170b 100644
--- a/include/linux/selinux.h
+++ b/include/linux/selinux.h
@@ -120,16 +120,35 @@ void selinux_get_task_sid(struct task_struct *tsk, u32 
*sid);
 int selinux_string_to_sid(char *str, u32 *sid);
 
 /**
- * selinux_relabel_packet_permission - check permission to relabel a packet
- * @sid: ID value to be applied to network packet (via SECMARK, most 
likely)
+ * selinux_secmark_relabel_packet_permission - secmark permission check
+ * @sid: SECMARK ID value to be applied to network packet
  *
- * Returns 0 if the current task is allowed to label packets with the
- * supplied security ID.  Note that it is implicit that the packet is 
always
- * being relabeled from the default unlabled value, and that the access
- * control decision is made in the AVC.
+ * Returns 0 if the current task is allowed to set the SECMARK label of
+ * packets with the supplied security ID.  Note that it is implicit that
+ * the packet is always being relabeled from the default unlabeled value,
+ * and that the access control decision is made in the AVC.
  */
-int selinux_relabel_packet_permission(u32 sid);
+int selinux_secmark_relabel_packet_permission(u32 sid);
 
+/**
+ * selinux_secmark_refcount_inc - increments the secmark use counter
+ *
+ * SELinux keeps track of the current SECMARK targets in use so it knows
+ * when to apply SECMARK label access checks to network packets.  This
+ * function incements this reference count to indicate that a new SECMARK
+ * target has been configured.
+ */
+void selinux_secmark_refcount_inc(void);
+
+/**
+ * selinux_secmark_refcount_dec - decrements the secmark use counter
+ *
+ * SELinux keeps track of the current SECMARK targets in use so it knows
+ * when to apply SECMARK label access checks to network packets.  This
+ * function decements this reference count to indicate that one of the
+ * existing SECMARK targets has been removed/flushed.
+ */
+void selinux_secmark_refcount_dec(void);
 #else
 
 static inline int selinux_audit_rule_init(u32 field, u32 op,
@@ -184,11 +203,21 @@ static inline int selinux_string_to_sid(const char *str, 
u32 *sid)
return 0;
 }
 
-static inline int selinux_relabel_packet_permission(u32 sid)
+static inline int selinux_secmark_relabel_packet_permission(u32 sid)
 {
return 0;
 }
 
+static inline void selinux_secmark_refcount_inc(void)
+{
+   return;
+}
+
+static inline void selinux_secmark_refcount_dec(void)
+{
+   return;
+}
+
 #endif /* CONFIG_SECURITY_SELINUX */
 
 #endif /* _LINUX_SELINUX_H */
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 235806e..db4a1fe 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -72,12 +72,13 @@ static bool checkentry_selinux(struct 
xt_secmark_target_info *info)
return false;
}
 
-   err = selinux_relabel_packet_permission(sel->selsid);
+   err = selinux_secmark_relabel_packet_permission(sel->selsid);
if (err) {
printk(KERN_INFO PFX "unable to obtain relabeling 
permission\n");
return false;
}
 
+   selinux_secmark_refcount_inc();
return true;
 }
 
@@ -109,11 +110,20 @@ static bool checkentry(const char *tablename, const void 
*entry,
return true;
 }
 
+void destroy(const struct xt_target *target, void *targinfo)
+{
+   switch (mode) {
+   case SECMARK_MODE_SEL:
+   selinux_secmark_refcount_dec();
+   }
+}
+
 static struct xt_targ

[RFC PATCH v7 11/13] SELinux: allow NetLabel to directly cache SIDs

2007-11-15 Thread Paul Moore
Now that the SELinux NetLabel "base SID" is always the netmsg initial SID we
can do a big optimization - caching the SID and not just the MLS attributes.
This not only saves a lot of per-packet memory allocations and copies but it
has a nice side effect of removing a chunk of code.
---

 security/selinux/hooks.c|6 --
 security/selinux/include/netlabel.h |2 -
 security/selinux/include/security.h |2 -
 security/selinux/netlabel.c |   55 ++--
 security/selinux/ss/services.c  |  124 ++-
 5 files changed, 55 insertions(+), 134 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 22789b5..a8928eb 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3231,11 +3231,7 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, 
u16 family, u32 *sid)
u32 nlbl_type;
 
selinux_skb_xfrm_sid(skb, &xfrm_sid);
-   selinux_netlbl_skbuff_getsid(skb,
-family,
-SECINITSID_NETMSG,
-&nlbl_type,
-&nlbl_sid);
+   selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
 
if (security_net_peersid_resolve(nlbl_sid, nlbl_type,
 xfrm_sid,
diff --git a/security/selinux/include/netlabel.h 
b/security/selinux/include/netlabel.h
index c8c05a6..00a2809 100644
--- a/security/selinux/include/netlabel.h
+++ b/security/selinux/include/netlabel.h
@@ -48,7 +48,6 @@ void selinux_netlbl_sk_security_clone(struct 
sk_security_struct *ssec,
 
 int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
 u16 family,
-u32 base_sid,
 u32 *type,
 u32 *sid);
 
@@ -89,7 +88,6 @@ static inline void selinux_netlbl_sk_security_clone(
 
 static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
   u16 family,
-  u32 base_sid,
   u32 *type,
   u32 *sid)
 {
diff --git a/security/selinux/include/security.h 
b/security/selinux/include/security.h
index fb807c1..4373a7e 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -125,7 +125,6 @@ int security_genfs_sid(const char *fstype, char *name, u16 
sclass,
 
 #ifdef CONFIG_NETLABEL
 int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
-  u32 base_sid,
   u32 *sid);
 
 int security_netlbl_sid_to_secattr(u32 sid,
@@ -133,7 +132,6 @@ int security_netlbl_sid_to_secattr(u32 sid,
 #else
 static inline int security_netlbl_secattr_to_sid(
struct netlbl_lsm_secattr *secattr,
-   u32 base_sid,
u32 *sid)
 {
return -EIDRM;
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index af78cb9..e07adf9 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -36,6 +36,33 @@
 #include "security.h"
 
 /**
+ * selinux_netlbl_sidlookup_cached - Cache a SID lookup
+ * @skb: the packet
+ * @secattr: the NetLabel security attributes
+ * @sid: the SID
+ *
+ * Description:
+ * Query the SELinux security server to lookup the correct SID for the given
+ * security attributes.  If the query is successful, cache the result to speed
+ * up future lookups.  Returns zero on success, negative values on failure.
+ *
+ */
+static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
+  struct netlbl_lsm_secattr *secattr,
+  u32 *sid)
+{
+   int rc;
+
+   rc = security_netlbl_secattr_to_sid(secattr, sid);
+   if (rc == 0 &&
+   (secattr->flags & NETLBL_SECATTR_CACHEABLE) &&
+   (secattr->flags & NETLBL_SECATTR_CACHE))
+   netlbl_cache_add(skb, secattr);
+
+   return rc;
+}
+
+/**
  * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism
  * @sk: the socket to label
  * @sid: the SID to use
@@ -141,7 +168,6 @@ void selinux_netlbl_sk_security_clone(struct 
sk_security_struct *ssec,
  * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel
  * @skb: the packet
  * @family: protocol family
- * @base_sid: the SELinux SID to use as a context for MLS only attributes
  * @type: NetLabel labeling protocol type
  * @sid: the SID
  *
@@ -153,7 +179,6 @@ void selinux_netlbl_sk_security_clone(struct 
sk_security_struct *ssec,
  */
 int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
 u16 family,
-u3

[RFC PATCH v7 13/13] NetLabel: add auditing to the static labeling mechanism

2007-11-15 Thread Paul Moore
This patch adds auditing support to the NetLabel static labeling mechanism.
---

 include/linux/audit.h |2 +
 net/netlabel/netlabel_unlabeled.c |  127 +++--
 2 files changed, 107 insertions(+), 22 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index c687816..bdd6f5d 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -115,6 +115,8 @@
 #define AUDIT_MAC_IPSEC_ADDSPD 1413/* Not used */
 #define AUDIT_MAC_IPSEC_DELSPD 1414/* Not used */
 #define AUDIT_MAC_IPSEC_EVENT  1415/* Audit an IPSec event */
+#define AUDIT_MAC_UNLBL_STCADD 1416/* NetLabel: add a static label */
+#define AUDIT_MAC_UNLBL_STCDEL 1417/* NetLabel: del a static label */
 
 #define AUDIT_FIRST_KERN_ANOM_MSG   1700
 #define AUDIT_LAST_KERN_ANOM_MSG1799
diff --git a/net/netlabel/netlabel_unlabeled.c 
b/net/netlabel/netlabel_unlabeled.c
index add0988..30ebb14 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -519,6 +519,7 @@ add_iface_failure:
  * @mask: address mask in network byte order
  * @addr_len: length of address/mask (4 for IPv4, 16 for IPv6)
  * @secid: LSM secid value for the entry
+ * @audit_info: NetLabel audit information
  *
  * Description:
  * Adds a new entry to the unlabeled connection hash table.  Returns zero on
@@ -530,12 +531,18 @@ static int netlbl_unlhsh_add(struct net *net,
 const void *addr,
 const void *mask,
 u32 addr_len,
-u32 secid)
+u32 secid,
+struct netlbl_audit *audit_info)
 {
int ret_val;
int ifindex;
struct net_device *dev;
struct netlbl_unlhsh_iface *iface;
+   struct in_addr *addr4, *mask4;
+   struct in6_addr *addr6, *mask6;
+   struct audit_buffer *audit_buf = NULL;
+   char *secctx = NULL;
+   u32 secctx_len;
 
if (addr_len != sizeof(struct in_addr) &&
addr_len != sizeof(struct in6_addr))
@@ -562,19 +569,25 @@ static int netlbl_unlhsh_add(struct net *net,
goto unlhsh_add_return;
}
}
+   audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCADD,
+ audit_info);
switch (addr_len) {
case sizeof(struct in_addr):
-   ret_val = netlbl_unlhsh_add_addr4(iface,
- (struct in_addr *)addr,
- (struct in_addr *)mask,
- secid);
+   addr4 = (struct in_addr *)addr;
+   mask4 = (struct in_addr *)mask;
+   ret_val = netlbl_unlhsh_add_addr4(iface, addr4, mask4, secid);
+   if (audit_buf != NULL)
+   audit_log_format(audit_buf, " daddr=" NIPQUAD_FMT,
+NIPQUAD(addr4->s_addr));
break;
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
case sizeof(struct in6_addr):
-   ret_val = netlbl_unlhsh_add_addr6(iface,
- (struct in6_addr *)addr,
- (struct in6_addr *)mask,
- secid);
+   addr6 = (struct in6_addr *)addr;
+   mask6 = (struct in6_addr *)mask;
+   ret_val = netlbl_unlhsh_add_addr6(iface, addr6, mask6, secid);
+   if (audit_buf != NULL)
+   audit_log_format(audit_buf, " daddr= " NIP6_FMT,
+NIP6(*addr6));
break;
 #endif /* IPv6 */
default:
@@ -585,6 +598,16 @@ static int netlbl_unlhsh_add(struct net *net,
 
 unlhsh_add_return:
rcu_read_unlock();
+   if (audit_buf != NULL) {
+   if (security_secid_to_secctx(secid,
+&secctx,
+&secctx_len) == 0) {
+   audit_log_format(audit_buf, " sec_obj=%s", secctx);
+   security_release_secctx(secctx, secctx_len);
+   }
+   audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
+   audit_log_end(audit_buf);
+   }
return ret_val;
 }
 
@@ -593,6 +616,7 @@ unlhsh_add_return:
  * @iface: interface entry
  * @addr: IP address
  * @mask: IP address mask
+ * @audit_info: NetLabel audit information
  *
  * Description:
  * Remove an IP address entry from the unlabeled connection hash table.
@@ -602,10 +626,14 @@ unlhsh_add_return:
  */
 static int netlbl_unlhsh_remove_addr4(struct netlbl_unlhsh_iface *iface,
  const struct in_addr *addr,
- const struct in_addr *m

[RFC PATCH v7 09/13] SELinux: Better integration between peer labeling subsystems

2007-11-15 Thread Paul Moore
Rework the handling of network peer labels so that the different peer labeling
subsystems work better together.  This includes moving both subsystems to a
single "peer" object class which involves not only changes to the permission
checks but an improved method of consolidating multiple packet peer labels.
As part of this work the inbound packet permission check code has been heavily
modified to handle both the old and new behavior in as sane a fashion as
possible.
---

 security/selinux/hooks.c|  214 ---
 security/selinux/include/netlabel.h |3 
 security/selinux/include/objsec.h   |2 
 security/selinux/include/security.h |4 +
 security/selinux/netlabel.c |   10 --
 security/selinux/ss/services.c  |   85 ++
 6 files changed, 218 insertions(+), 100 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2188b9c..8aeb1c0 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3190,36 +3190,39 @@ static int selinux_parse_skb(struct sk_buff *skb, 
struct avc_audit_data *ad,
 }
 
 /**
- * selinux_skb_extlbl_sid - Determine the external label of a packet
+ * selinux_skb_peerlbl_sid - Determine the peer label of a packet
  * @skb: the packet
  * @family: protocol family
- * @sid: the packet's SID
+ * @sid: the packet's peer label SID
  *
  * Description:
- * Check the various different forms of external packet labeling and determine
- * the external SID for the packet.  If only one form of external labeling is
- * present then it is used, if both labeled IPsec and NetLabel labels are
- * present then the SELinux type information is taken from the labeled IPsec
- * SA and the MLS sensitivity label information is taken from the NetLabel
- * security attributes.  This bit of "magic" is done in the call to
- * selinux_netlbl_skbuff_getsid().
+ * Check the various different forms of network peer labeling and determine
+ * the peer label/SID for the packet; most of the magic actually occurs in
+ * the security server function security_net_peersid_cmp().  The function
+ * returns zero if the value in @sid is valid (although it may be SECSID_NULL)
+ * or -EACCES if @sid is invalid due to inconsistencies with the different
+ * peer labels.
  *
  */
-static void selinux_skb_extlbl_sid(struct sk_buff *skb,
-  u16 family,
-  u32 *sid)
+static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
 {
u32 xfrm_sid;
u32 nlbl_sid;
+   u32 nlbl_type;
 
selinux_skb_xfrm_sid(skb, &xfrm_sid);
-   if (selinux_netlbl_skbuff_getsid(skb,
-family,
-(xfrm_sid == SECSID_NULL ?
- SECINITSID_NETMSG : xfrm_sid),
-&nlbl_sid) != 0)
-   nlbl_sid = SECSID_NULL;
-   *sid = (nlbl_sid == SECSID_NULL ? xfrm_sid : nlbl_sid);
+   selinux_netlbl_skbuff_getsid(skb,
+family,
+SECINITSID_NETMSG,
+&nlbl_type,
+&nlbl_sid);
+
+   if (security_net_peersid_resolve(nlbl_sid, nlbl_type,
+xfrm_sid,
+sid) != 0)
+   return -EACCES;
+
+   return 0;
 }
 
 /* socket security operations */
@@ -3285,6 +3288,7 @@ static int selinux_socket_post_create(struct socket 
*sock, int family,
if (sock->sk) {
sksec = sock->sk->sk_security;
sksec->sid = isec->sid;
+   sksec->sclass = isec->sclass;
err = selinux_netlbl_socket_post_create(sock);
}
 
@@ -3588,132 +3592,154 @@ static int selinux_socket_unix_may_send(struct socket 
*sock,
return 0;
 }
 
-static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
-   struct avc_audit_data *ad, u16 family, char *addrp, int len)
+static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk,
+   struct sk_buff *skb,
+   struct avc_audit_data *ad,
+   u16 family,
+   char *addrp,
+   int len)
 {
-   int err = 0;
-   u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0;
-   struct socket *sock;
-   u16 sock_class = 0;
-   u32 sock_sid = 0;
-
-   read_lock_bh(&sk->sk_callback_lock);
-   sock = sk->sk_socket;
-   if (sock) {
-   struct inode *inode;
-   inode = SOCK_INODE(sock);
-   if (inode) {
-   struct inode_security_struct *isec;
-   isec = inode->i

[RFC PATCH v7 07/13] SELinux: Add a capabilities bitmap to SELinux policy version 22

2007-11-15 Thread Paul Moore
Add a new policy capabilities bitmap to SELinux policy version 22.  This bitmap
will enable the security server to query the policy to determine which features
it supports.
---

 security/selinux/Kconfig|2 -
 security/selinux/include/security.h |   15 ++
 security/selinux/selinuxfs.c|   89 +--
 security/selinux/ss/policydb.c  |   18 +++
 security/selinux/ss/policydb.h  |2 +
 security/selinux/ss/services.c  |   67 ++
 6 files changed, 185 insertions(+), 8 deletions(-)

diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
index b32a459..2b517d6 100644
--- a/security/selinux/Kconfig
+++ b/security/selinux/Kconfig
@@ -145,7 +145,7 @@ config SECURITY_SELINUX_POLICYDB_VERSION_MAX
 config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
int "NSA SELinux maximum supported policy format version value"
depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX
-   range 15 21
+   range 15 22
default 19
help
  This option sets the value for the maximum policy format version
diff --git a/security/selinux/include/security.h 
b/security/selinux/include/security.h
index 39337af..4d3c0d3 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -25,13 +25,14 @@
 #define POLICYDB_VERSION_MLS   19
 #define POLICYDB_VERSION_AVTAB 20
 #define POLICYDB_VERSION_RANGETRANS21
+#define POLICYDB_VERSION_POLCAP22
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX   
CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_RANGETRANS
+#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_POLCAP
 #endif
 
 struct netlbl_lsm_secattr;
@@ -39,8 +40,19 @@ struct netlbl_lsm_secattr;
 extern int selinux_enabled;
 extern int selinux_mls_enabled;
 
+/* Policy capabilities */
+enum {
+   POLICYDB_CAPABILITY_NETPEER,
+   __POLICYDB_CAPABILITY_MAX
+};
+#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
+
+extern int selinux_policycap_netpeer;
+
 int security_load_policy(void * data, size_t len);
 
+int security_policycap_supported(unsigned int req_cap);
+
 #define SEL_VEC_MAX 32
 struct av_decision {
u32 allowed;
@@ -92,6 +104,7 @@ int security_get_classes(char ***classes, int *nclasses);
 int security_get_permissions(char *class, char ***perms, int *nperms);
 int security_get_reject_unknown(void);
 int security_get_allow_unknown(void);
+int security_get_policycaps(int *len, int **values);
 
 #define SECURITY_FS_USE_XATTR  1 /* use xattr */
 #define SECURITY_FS_USE_TRANS  2 /* use transition SIDs, e.g. 
devpts/tmpfs */
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index f5f3e6d..cf583cc 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -2,6 +2,11 @@
  *
  * Added conditional policy language extensions
  *
+ *  Updated: Hewlett-Packard <[EMAIL PROTECTED]>
+ *
+ *  Added support for the policy capability bitmap
+ *
+ * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2003 - 2004 Tresys Technology, LLC
  * Copyright (C) 2004 Red Hat, Inc., James Morris <[EMAIL PROTECTED]>
  * This program is free software; you can redistribute it and/or modify
@@ -35,6 +40,11 @@
 #include "objsec.h"
 #include "conditional.h"
 
+/* Policy capability filenames */
+static char *policycap_names[] = {
+   "network_peer_controls"
+};
+
 unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
 
 #ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
@@ -71,6 +81,9 @@ static int *bool_pending_values = NULL;
 static struct dentry *class_dir = NULL;
 static unsigned long last_class_ino;
 
+/* global data for policy capabilities */
+static struct dentry *policycap_dir = NULL;
+
 extern void selnl_notify_setenforce(int val);
 
 /* Check whether a task is allowed to use a security operation. */
@@ -110,10 +123,11 @@ enum sel_inos {
 
 static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
 
-#define SEL_INITCON_INO_OFFSET 0x0100
-#define SEL_BOOL_INO_OFFSET0x0200
-#define SEL_CLASS_INO_OFFSET   0x0400
-#define SEL_INO_MASK   0x00ff
+#define SEL_INITCON_INO_OFFSET 0x0100
+#define SEL_BOOL_INO_OFFSET0x0200
+#define SEL_CLASS_INO_OFFSET   0x0400
+#define SEL_POLICYCAP_INO_OFFSET   0x0800
+#define SEL_INO_MASK   0x00ff
 
 #define TMPBUFLEN  12
 static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
@@ -262,6 +276,7 @@ static const struct file_operations sel_policyvers_ops = {
 /* declaration for sel_write_load */
 static int sel_make_bools(void);
 static int sel_make_classes(void);
+static int sel_make_po

[RFC PATCH v7 06/13] NetLabel: add IP address family information to the netlbl_skbuff_getattr() function

2007-11-15 Thread Paul Moore
In order to do any sort of IP header inspection of incoming packets we need to
know which address family, AF_INET/AF_INET6/etc., it belongs to and since the
sk_buff structure does not store this information we need to pass along the
address family separate from the packet itself.
---

 include/net/netlabel.h  |2 ++
 net/netlabel/netlabel_kapi.c|2 ++
 security/selinux/hooks.c|   24 ++--
 security/selinux/include/netlabel.h |8 +++-
 security/selinux/netlabel.c |   12 +---
 5 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 18b73cf..a3bffb4 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -363,6 +363,7 @@ int netlbl_sock_setattr(struct sock *sk,
 int netlbl_sock_getattr(struct sock *sk,
struct netlbl_lsm_secattr *secattr);
 int netlbl_skbuff_getattr(const struct sk_buff *skb,
+ u16 family,
  struct netlbl_lsm_secattr *secattr);
 void netlbl_skbuff_err(struct sk_buff *skb, int error);
 
@@ -415,6 +416,7 @@ static inline int netlbl_sock_getattr(struct sock *sk,
return -ENOSYS;
 }
 static inline int netlbl_skbuff_getattr(const struct sk_buff *skb,
+   u16 family,
struct netlbl_lsm_secattr *secattr)
 {
return -ENOSYS;
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index d3762ea..4914615 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -332,6 +332,7 @@ int netlbl_sock_getattr(struct sock *sk, struct 
netlbl_lsm_secattr *secattr)
 /**
  * netlbl_skbuff_getattr - Determine the security attributes of a packet
  * @skb: the packet
+ * @family: protocol family
  * @secattr: the security attributes
  *
  * Description:
@@ -342,6 +343,7 @@ int netlbl_sock_getattr(struct sock *sk, struct 
netlbl_lsm_secattr *secattr)
  *
  */
 int netlbl_skbuff_getattr(const struct sk_buff *skb,
+ u16 family,
  struct netlbl_lsm_secattr *secattr)
 {
if (CIPSO_V4_OPTEXIST(skb) &&
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8bb673b..2188b9c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3192,6 +3192,7 @@ static int selinux_parse_skb(struct sk_buff *skb, struct 
avc_audit_data *ad,
 /**
  * selinux_skb_extlbl_sid - Determine the external label of a packet
  * @skb: the packet
+ * @family: protocol family
  * @sid: the packet's SID
  *
  * Description:
@@ -3204,13 +3205,16 @@ static int selinux_parse_skb(struct sk_buff *skb, 
struct avc_audit_data *ad,
  * selinux_netlbl_skbuff_getsid().
  *
  */
-static void selinux_skb_extlbl_sid(struct sk_buff *skb, u32 *sid)
+static void selinux_skb_extlbl_sid(struct sk_buff *skb,
+  u16 family,
+  u32 *sid)
 {
u32 xfrm_sid;
u32 nlbl_sid;
 
selinux_skb_xfrm_sid(skb, &xfrm_sid);
if (selinux_netlbl_skbuff_getsid(skb,
+family,
 (xfrm_sid == SECSID_NULL ?
  SECINITSID_NETMSG : xfrm_sid),
 &nlbl_sid) != 0)
@@ -3703,7 +3707,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, 
struct sk_buff *skb)
if (err)
goto out;
 
-   err = selinux_netlbl_sock_rcv_skb(sksec, skb, &ad);
+   err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
if (err)
goto out;
 
@@ -3760,11 +3764,19 @@ static int selinux_socket_getpeersec_dgram(struct 
socket *sock, struct sk_buff *
 {
u32 peer_secid = SECSID_NULL;
int err = 0;
+   u16 family;
+
+   if (sock)
+   family = sock->sk->sk_family;
+   else if (skb->sk)
+   family = skb->sk->sk_family;
+   else
+   family = PF_UNSPEC;
 
-   if (sock && sock->sk->sk_family == PF_UNIX)
+   if (sock && family == PF_UNIX)
selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
else if (skb)
-   selinux_skb_extlbl_sid(skb, &peer_secid);
+   selinux_skb_extlbl_sid(skb, family, &peer_secid);
 
if (peer_secid == SECSID_NULL)
err = -EINVAL;
@@ -3825,7 +3837,7 @@ static int selinux_inet_conn_request(struct sock *sk, 
struct sk_buff *skb,
u32 newsid;
u32 peersid;
 
-   selinux_skb_extlbl_sid(skb, &peersid);
+   selinux_skb_extlbl_sid(skb, sk->sk_family, &peersid);
if (peersid == SECSID_NULL) {
req->secid = sksec->sid;
req->peer_secid = SECSID_NULL;
@@ -3863,7 +3875,7 @@ static void selinux_inet_conn_established(struct sock *sk,
 {
struct sk_security_struct *sksec = sk->sk_security;

[RFC PATCH v7 12/13] NetLabel: introduce static network labels for unlabeled connections

2007-11-15 Thread Paul Moore
Most trusted OSs, with the exception of Linux, have the ability to specify
static security labels for unlabeled networks.  This patch adds this ability to
the NetLabel packet labeling framework.

If the NetLabel subsystem is called to determine the security attributes of an
incoming packet it first checks to see if any recognized NetLabel packet
labeling protocols are in-use on the packet.  If none can be found then the
unlabled connection table is queried and based on the packets incoming
interface and address it is matched with a security label as configured by the
administrator using the netlabel_tools package.  The matching security label is
returned to the caller just as if the packet was explicitly labeled using a
labeling protocol.
---

 include/net/netlabel.h|6 
 net/netlabel/netlabel_kapi.c  |   16 
 net/netlabel/netlabel_unlabeled.c | 1373 +
 net/netlabel/netlabel_unlabeled.h |  145 
 4 files changed, 1522 insertions(+), 18 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index a3bffb4..b3213c7 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -67,7 +67,11 @@
  * NetLabel NETLINK protocol
  */
 
-#define NETLBL_PROTO_VERSION1
+/* NetLabel NETLINK protocol version
+ *  1: initial version
+ *  2: added static labels for unlabeled connections
+ */
+#define NETLBL_PROTO_VERSION2
 
 /* NetLabel NETLINK types/families */
 #define NETLBL_NLTYPE_NONE  0
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 4914615..c69e3e1 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -312,7 +312,7 @@ socket_setattr_return:
  * @secattr: the security attributes
  *
  * Description:
- * Examines the given sock to see any NetLabel style labeling has been
+ * Examines the given sock to see if any NetLabel style labeling has been
  * applied to the sock, if so it parses the socket label and returns the
  * security attributes in @secattr.  Returns zero on success, negative values
  * on failure.
@@ -320,13 +320,7 @@ socket_setattr_return:
  */
 int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
 {
-   int ret_val;
-
-   ret_val = cipso_v4_sock_getattr(sk, secattr);
-   if (ret_val == 0)
-   return 0;
-
-   return netlbl_unlabel_getattr(secattr);
+   return cipso_v4_sock_getattr(sk, secattr);
 }
 
 /**
@@ -350,7 +344,7 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
cipso_v4_skbuff_getattr(skb, secattr) == 0)
return 0;
 
-   return netlbl_unlabel_getattr(secattr);
+   return netlbl_unlabel_getattr(skb, family, secattr);
 }
 
 /**
@@ -434,6 +428,10 @@ static int __init netlbl_init(void)
if (ret_val != 0)
goto init_failure;
 
+   ret_val = netlbl_unlabel_init(NETLBL_UNLHSH_BITSIZE);
+   if (ret_val != 0)
+   goto init_failure;
+
ret_val = netlbl_netlink_init();
if (ret_val != 0)
goto init_failure;
diff --git a/net/netlabel/netlabel_unlabeled.c 
b/net/netlabel/netlabel_unlabeled.c
index 5e11394..add0988 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -10,7 +10,7 @@
  */
 
 /*
- * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
+ * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - 2007
  *
  * This program is free software;  you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,22 +36,88 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
-
+#include 
+#include 
 #include 
 #include 
+#include 
 
 #include "netlabel_user.h"
 #include "netlabel_domainhash.h"
 #include "netlabel_unlabeled.h"
+#include "netlabel_mgmt.h"
+
+/* The unlabeled connection hash table which we use to map network interfaces
+ * and addresses of unlabeled packets to a user specified secid value for the
+ * LSM.  The hash table is used to lookup the network interface entry
+ * (struct netlbl_unlhsh_iface) and then the interface entry is used to
+ * lookup an IP address match from an ordered list.  If a network interface
+ * match can not be found in the hash table then the default entry
+ * (netlbl_unlhsh_def) is used.  The IP address entry list
+ * (struct netlbl_unlhsh_addr) is ordered such that the entries with a
+ * larger netmask come first.
+ */
+struct netlbl_unlhsh_tbl {
+   struct list_head *tbl;
+   u32 size;
+};
+struct netlbl_unlhsh_addr4 {
+   __be32 addr;
+   __be32 mask;
+   u32 secid;
+
+   u32 valid;
+   struct list_head list;
+   struct rcu_head rcu;
+};
+struct netlbl_unlhsh_addr6 {
+   struct in6_addr addr;
+   struct in6_addr mask;
+   u32 secid;
+
+   u32 valid;
+   struct list_head list;
+   

Re: [TOMOYO #5 18/18] LSM expansion for TOMOYO Linux.

2007-11-16 Thread Paul Moore
On Friday 16 November 2007 12:34:57 pm [EMAIL PROTECTED] 
wrote:
> LSM hooks for network accept and recv:
>* socket_post_accept is modified to return int.
>* post_recv_datagram is added in skb_recv_datagram.
>
> You can try TOMOYO Linux without this patch, but in that case, you
> can't use access control functionality for restricting signal
> transmission and incoming network data.

As discussed a few times before, I'm still not really excited about adding a 
new LSM hook in skb_recv_datagram() when we already have hooks to control 
locally consumed network traffic.  However, I will admit that these existing 
hooks do not allow the LSM to block and query userspace for an access 
decision like you are trying to do with TOMOYO.  I would prefer not to see 
this new LSM hook added but I do not have an alternative solution to your 
problem so I can't in good conscience completely object to this patch.

Regardless, I have a few comments which are included below ...

> --- linux-2.6-mm.orig/net/core/datagram.c 2007-10-10 05:31:38.0
> +0900 +++ linux-2.6-mm/net/core/datagram.c2007-11-14 15:15:44.0
> +0900 @@ -55,6 +55,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>
>  /*
>   *   Is a socket 'connection oriented' ?
> @@ -178,6 +179,27 @@ struct sk_buff *skb_recv_datagram(struct
>   } else
>   skb = skb_dequeue(&sk->sk_receive_queue);
>
> + error = security_post_recv_datagram(sk, skb, flags);
> + if (error) {
> + unsigned long cpu_flags;

With this patch the 'cpu_flags' variable will be used in two different 
if-blocks in this function and declared locally within each block.  Please 
move the 'cpu_flags' declaration to the top of the function so it only needs 
to be declared once.

> +
> + if (!(flags & MSG_PEEK))
> + goto no_peek;
> +
> + spin_lock_irqsave(&sk->sk_receive_queue.lock,
> +   cpu_flags);
> + if (skb == skb_peek(&sk->sk_receive_queue)) {

I might be missing something here, but why do you need to do a skb_peek() 
again?  You already have the skb and the sock, just do the unlink.

> + __skb_unlink(skb,
> +  &sk->sk_receive_queue);
> + atomic_dec(&skb->users);
> + }
> + spin_unlock_irqrestore(&sk->sk_receive_queue.lock,
> +cpu_flags);
> +no_peek:
> + skb_free_datagram(sk, skb);
> +     goto no_packet;

Two things.  First you can probably just call kfree_skb() instead of 
skb_free_datagram().  Second, why not move the 'no_peek' code to just 
before 'no_packet'?

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [TOMOYO #5 18/18] LSM expansion for TOMOYO Linux.

2007-11-17 Thread Paul Moore
On Friday 16 November 2007 10:45:32 pm Tetsuo Handa wrote:
> Paul Moore wrote:
> > I might be missing something here, but why do you need to do a skb_peek()
> > again?  You already have the skb and the sock, just do the unlink.
>
> The skb might be already dequeued by other thread while I slept inside
> security_post_recv_datagram().

Okay, well if that is the case I think you are going to have another problem 
in that you could end up throwing away skbs that haven't been through your 
security_post_recv_datagram() hook because you _always_ throw away the result 
of the second skb_peek().  Once again, if I'm wrong please correct me.

> > Second, why not move the 'no_peek' code to just before 'no_packet'?
>
> Oh, I didn't notice I can insert here. Now I can also move the rest code
> like
>
> | error = security_post_recv_datagram(sk, skb, flags);
> | if (error)
> |   goto force_dequeue;
> |
> | } while (!wait_for_packet(sk, err, &timeo));

Where did the 'if (skb) return skb;' code go?  Don't you need to do you LSM 
call before you return the skb?

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [TOMOYO #5 18/18] LSM expansion for TOMOYO Linux.

2007-11-19 Thread Paul Moore
On Saturday 17 November 2007 11:00:20 pm Tetsuo Handa wrote:
> Hello.

Hello.

> Paul Moore wrote:
> > Okay, well if that is the case I think you are going to have another
> > problem in that you could end up throwing away skbs that haven't been
> > through your security_post_recv_datagram() hook because you _always_
> > throw away the result of the second skb_peek().  Once again, if I'm wrong
> > please correct me.
>
> I didn't understand what's wrong with throwing away the result of
> the second skb_peek().

My concern is that you stated earlier that you needed to do the second 
skb_peek() because the first skb may have been removed from the socket queue 
while your LSM was making an access decision in 
security_post_recv_datagram().  If that is the case then the second call to 
skb_peek() will return a different skb then the one you passed to 
security_post_recv_datagram().  This is significant because you always throw 
away this second skb without first consulting the LSM via 
security_post_recv_datagram().

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [TOMOYO #5 18/18] LSM expansion for TOMOYO Linux.

2007-11-19 Thread Paul Moore
On Monday 19 November 2007 9:29:52 am Tetsuo Handa wrote:
> Paul Moore wrote:
> > If that is the case then the second call to
> > skb_peek() will return a different skb then the one you passed to
> > security_post_recv_datagram().
>
> Yes. The second call to skb_peek() might return a different skb than the
> one I passed to security_post_recv_datagram().

My apologies, I mistakenly read the following if statement in your patch:

 +   if (skb == skb_peek(&sk->sk_receive_queue)) {
 +   __skb_unlink(skb, &sk->sk_receive_queue);
 +   atomic_dec(&skb->users);
 +   }

I read the conditional as the following:

 +   if (skb = skb_peek(&sk->sk_receive_queue)) {

... which would have caused the problems I was describing.  I'm sorry for all 
of the confusion/frustration, you patient explanations are correct; I was 
wrong in this particular case.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v8 18/18] SELinux: Add network ingress and egress control permission checks

2007-12-14 Thread Paul Moore
This patch implements packet ingress/egress controls for SELinux which allow
SELinux security policy to control the flow of all IPv4 and IPv6 packets into
and out of the system.  Currently SELinux does not have proper control over
forwarded packets and this patch corrects this problem.

Special thanks to Venkat Yekkirala <[EMAIL PROTECTED]> whose earlier
work on this topic eventually led to this patch.
---

 security/selinux/hooks.c |  335 +++---
 1 files changed, 228 insertions(+), 107 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2f221b2..2a6d50f 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -12,8 +12,8 @@
  *  Copyright (C) 2003 Red Hat, Inc., James Morris <[EMAIL PROTECTED]>
  *  Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
  *  <[EMAIL PROTECTED]>
- *  Copyright (C) 2006 Hewlett-Packard Development Company, L.P.
- *     Paul Moore, <[EMAIL PROTECTED]>
+ *  Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
+ *     Paul Moore <[EMAIL PROTECTED]>
  *  Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
  * Yuichi Nakamura <[EMAIL PROTECTED]>
  *
@@ -3608,6 +3608,71 @@ static int selinux_socket_unix_may_send(struct socket 
*sock,
return 0;
 }
 
+static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
+   u32 peer_sid,
+   struct avc_audit_data *ad)
+{
+   int err;
+   u32 if_sid;
+   u32 node_sid;
+
+   err = sel_netif_sid(ifindex, &if_sid);
+   if (err)
+   return err;
+   err = avc_has_perm(if_sid, peer_sid, SECCLASS_PEER, PEER__INGRESS, ad);
+   if (err)
+   return err;
+
+   err = sel_netnode_sid(addrp, family, &node_sid);
+   if (err)
+   return err;
+   return avc_has_perm(node_sid, peer_sid,
+   SECCLASS_PEER, PEER__INGRESS, ad);
+}
+
+static int selinux_inet_sys_snd_skb(struct sk_buff *skb, int family)
+{
+   int err = 0;
+
+   if (!selinux_policycap_netpeer)
+   return 0;
+
+   if (netlbl_enabled() || selinux_xfrm_enabled()) {
+   u32 if_sid;
+   u32 node_sid;
+   u32 peer_sid;
+   char *addrp;
+   struct avc_audit_data ad;
+
+   AVC_AUDIT_DATA_INIT(&ad, NET);
+   ad.u.net.netif = skb->iif;
+   ad.u.net.family = family;
+   err = selinux_parse_skb(skb, &ad, &addrp, 0, NULL);
+   if (err)
+   return err;
+
+   err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
+   if (err)
+   return err;
+
+   err = sel_netif_sid(skb->iif, &if_sid);
+   if (err)
+   return err;
+   err = avc_has_perm(if_sid, peer_sid,
+  SECCLASS_PEER, PEER__EGRESS, &ad);
+   if (err)
+   return err;
+
+   err = sel_netnode_sid(addrp, family, &node_sid);
+   if (err)
+   return err;
+   err = avc_has_perm(node_sid, peer_sid,
+  SECCLASS_PEER, PEER__EGRESS, &ad);
+   }
+
+   return err;
+}
+
 static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk,
struct sk_buff *skb,
struct avc_audit_data *ad,
@@ -3748,6 +3813,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, 
struct sk_buff *skb)
err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
if (err)
return err;
+   err = selinux_inet_sys_rcv_skb(skb->iif, addrp, family,
+  peer_sid, &ad);
+   if (err)
+   return err;
err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER,
   PEER__RECV, &ad);
}
@@ -3965,151 +4034,175 @@ out:
 
 #ifdef CONFIG_NETFILTER
 
-static int selinux_ip_postroute_last_compat(struct sock *sk,
-   struct net_device *dev,
-   struct avc_audit_data *ad,
-   u16 family,
-   char *addrp)
+static unsigned int selinux_ip_forward(struct sk_buff *skb, int ifindex,
+  u16 family)
 {
-   int err = 0;
-   u32 netif_perm, node_perm, node_sid, if_sid, send_perm = 0;
-   struct socket *sock;
-   struct inode *inode;
-   struct inod

[RFC PATCH v8 05/18] LSM: Add secctx_to_secid() LSM hook

2007-12-14 Thread Paul Moore
Add a secctx_to_secid() LSM hook to go along with the existing
secid_to_secctx() LSM hook.  This patch also includes the SELinux
implementation for this hook.
---

 include/linux/security.h |   13 +
 security/dummy.c |6 ++
 security/security.c  |6 ++
 security/selinux/hooks.c |6 ++
 4 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index ac05083..db19c92 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1183,6 +1183,10 @@ struct request_sock;
  * Convert secid to security context.
  * @secid contains the security ID.
  * @secdata contains the pointer that stores the converted security 
context.
+ * @secctx_to_secid:
+ *  Convert security context to secid.
+ *  @secid contains the pointer to the generated security ID.
+ *  @secdata contains the security context.
  *
  * @release_secctx:
  * Release the security context.
@@ -1371,6 +1375,7 @@ struct security_operations {
int (*getprocattr)(struct task_struct *p, char *name, char **value);
int (*setprocattr)(struct task_struct *p, char *name, void *value, 
size_t size);
int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen);
+   int (*secctx_to_secid)(char *secdata, u32 seclen, u32 *secid);
void (*release_secctx)(char *secdata, u32 seclen);
 
 #ifdef CONFIG_SECURITY_NETWORK
@@ -1603,6 +1608,7 @@ int security_setprocattr(struct task_struct *p, char 
*name, void *value, size_t
 int security_netlink_send(struct sock *sk, struct sk_buff *skb);
 int security_netlink_recv(struct sk_buff *skb, int cap);
 int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
+int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid);
 void security_release_secctx(char *secdata, u32 seclen);
 
 #else /* CONFIG_SECURITY */
@@ -2280,6 +2286,13 @@ static inline int security_secid_to_secctx(u32 secid, 
char **secdata, u32 *secle
return -EOPNOTSUPP;
 }
 
+static inline int security_secctx_to_secid(char *secdata,
+  u32 seclen,
+  u32 *secid)
+{
+   return -EOPNOTSUPP;
+}
+
 static inline void security_release_secctx(char *secdata, u32 seclen)
 {
 }
diff --git a/security/dummy.c b/security/dummy.c
index 3ccfbbe..0b62f95 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -928,6 +928,11 @@ static int dummy_secid_to_secctx(u32 secid, char 
**secdata, u32 *seclen)
return -EOPNOTSUPP;
 }
 
+static int dummy_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
+{
+   return -EOPNOTSUPP;
+}
+
 static void dummy_release_secctx(char *secdata, u32 seclen)
 {
 }
@@ -1086,6 +1091,7 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, getprocattr);
set_to_dummy_if_null(ops, setprocattr);
set_to_dummy_if_null(ops, secid_to_secctx);
+   set_to_dummy_if_null(ops, secctx_to_secid);
set_to_dummy_if_null(ops, release_secctx);
 #ifdef CONFIG_SECURITY_NETWORK
set_to_dummy_if_null(ops, unix_stream_connect);
diff --git a/security/security.c b/security/security.c
index 0e1f1f1..3bdcada 100644
--- a/security/security.c
+++ b/security/security.c
@@ -816,6 +816,12 @@ int security_secid_to_secctx(u32 secid, char **secdata, 
u32 *seclen)
 }
 EXPORT_SYMBOL(security_secid_to_secctx);
 
+int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
+{
+   return security_ops->secctx_to_secid(secdata, seclen, secid);
+}
+EXPORT_SYMBOL(security_secctx_to_secid);
+
 void security_release_secctx(char *secdata, u32 seclen)
 {
return security_ops->release_secctx(secdata, seclen);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9f3124b..8bb673b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4710,6 +4710,11 @@ static int selinux_secid_to_secctx(u32 secid, char 
**secdata, u32 *seclen)
return security_sid_to_context(secid, secdata, seclen);
 }
 
+static int selinux_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
+{
+   return security_context_to_sid(secdata, seclen, secid);
+}
+
 static void selinux_release_secctx(char *secdata, u32 seclen)
 {
kfree(secdata);
@@ -4898,6 +4903,7 @@ static struct security_operations selinux_ops = {
.setprocattr =  selinux_setprocattr,
 
.secid_to_secctx =  selinux_secid_to_secctx,
+   .secctx_to_secid =  selinux_secctx_to_secid,
.release_secctx =   selinux_release_secctx,
 
 .unix_stream_connect = selinux_socket_unix_stream_connect,

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v8 09/18] SELinux: Only store the network interface's ifindex

2007-12-14 Thread Paul Moore
Instead of storing the packet's network interface name store the ifindex.  This
allows us to defer the need to lookup the net_device structure until the audit
record is generated meaning that in the majority of cases we never need to
bother with this at all.
---

 security/selinux/avc.c |   15 ---
 security/selinux/hooks.c   |4 ++--
 security/selinux/include/avc.h |7 +--
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 81b3dff..8ecfab9 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -661,9 +661,18 @@ void avc_audit(u32 ssid, u32 tsid,
"daddr", "dest");
break;
}
-   if (a->u.net.netif)
-   audit_log_format(ab, " netif=%s",
-   a->u.net.netif);
+   if (a->u.net.netif >= 0) {
+   struct net_device *dev;
+
+   /* NOTE: we always use init's namespace */
+   dev = dev_get_by_index(&init_net,
+  a->u.net.netif);
+   if (dev) {
+   audit_log_format(ab, " netif=%s",
+dev->name);
+   dev_put(dev);
+   }
+   }
break;
}
}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2ca8dfb..e429a8c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3691,7 +3691,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, 
struct sk_buff *skb)
family = PF_INET;
 
AVC_AUDIT_DATA_INIT(&ad, NET);
-   ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]";
+   ad.u.net.netif = skb->iif;
ad.u.net.family = family;
 
err = selinux_parse_skb(skb, &ad, &addrp, &len, 1, NULL);
@@ -4023,7 +4023,7 @@ static unsigned int selinux_ip_postroute_last(unsigned 
int hooknum,
sksec = sk->sk_security;
 
AVC_AUDIT_DATA_INIT(&ad, NET);
-   ad.u.net.netif = dev->name;
+   ad.u.net.netif = dev->ifindex;
ad.u.net.family = family;
 
err = selinux_parse_skb(skb, &ad, &addrp, &len, 0, &proto);
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h
index 553607a..5185152 100644
--- a/security/selinux/include/avc.h
+++ b/security/selinux/include/avc.h
@@ -51,7 +51,7 @@ struct avc_audit_data {
struct inode *inode;
} fs;
struct {
-   char *netif;
+   int netif;
struct sock *sk;
u16 family;
__be16 dport;
@@ -77,7 +77,10 @@ struct avc_audit_data {
 
 /* Initialize an AVC audit data structure. */
 #define AVC_AUDIT_DATA_INIT(_d,_t) \
-{ memset((_d), 0, sizeof(struct avc_audit_data)); (_d)->type = 
AVC_AUDIT_DATA_##_t; }
+{ memset((_d), 0, sizeof(struct avc_audit_data)); \
+ (_d)->type = AVC_AUDIT_DATA_##_t; \
+ if ((_d)->type == AVC_AUDIT_DATA_NET) \
+ (_d)->u.net.netif = -1; }
 
 /*
  * AVC statistics

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v8 12/18] SELinux: Add new peer permissions to the Flask definitions

2007-12-14 Thread Paul Moore
Add additional Flask definitions to support the new "peer" object class.
---

 security/selinux/include/av_perm_to_string.h |3 +++
 security/selinux/include/av_permissions.h|3 +++
 security/selinux/include/class_to_string.h   |7 +++
 security/selinux/include/flask.h |1 +
 4 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/security/selinux/include/av_perm_to_string.h 
b/security/selinux/include/av_perm_to_string.h
index 049bf69..458b6aa 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -159,3 +159,6 @@
S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NODE_BIND, "node_bind")
S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NAME_CONNECT, "name_connect")
S_(SECCLASS_MEMPROTECT, MEMPROTECT__MMAP_ZERO, "mmap_zero")
+   S_(SECCLASS_PEER, PEER__INGRESS, "ingress")
+   S_(SECCLASS_PEER, PEER__EGRESS, "egress")
+   S_(SECCLASS_PEER, PEER__RECV, "recv")
diff --git a/security/selinux/include/av_permissions.h 
b/security/selinux/include/av_permissions.h
index eda89a2..861a77d 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -824,3 +824,6 @@
 #define DCCP_SOCKET__NODE_BIND0x0040UL
 #define DCCP_SOCKET__NAME_CONNECT 0x0080UL
 #define MEMPROTECT__MMAP_ZERO 0x0001UL
+#define PEER__INGRESS 0x0001UL
+#define PEER__EGRESS  0x0002UL
+#define PEER__RECV0x0004UL
diff --git a/security/selinux/include/class_to_string.h 
b/security/selinux/include/class_to_string.h
index e77de0e..b1b0d1d 100644
--- a/security/selinux/include/class_to_string.h
+++ b/security/selinux/include/class_to_string.h
@@ -64,3 +64,10 @@
 S_(NULL)
 S_("dccp_socket")
 S_("memprotect")
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_("peer")
diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h
index a9c2b20..09e9dd2 100644
--- a/security/selinux/include/flask.h
+++ b/security/selinux/include/flask.h
@@ -50,6 +50,7 @@
 #define SECCLASS_KEY 58
 #define SECCLASS_DCCP_SOCKET 60
 #define SECCLASS_MEMPROTECT  61
+#define SECCLASS_PEER68
 
 /*
  * Security identifier indices for initial entities

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v8 02/18] NetLabel: Cleanup the LSM domain hash functions

2007-12-14 Thread Paul Moore
The NetLabel/LSM domain hash table search function used an argument to specify
if the default entry should be returned if an exact match couldn't be found in
the hash table.  This is a bit against the kernel's style so make two separate
functions to represent the separate behaviors.
---

 net/netlabel/netlabel_domainhash.c |   47 ++--
 1 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/net/netlabel/netlabel_domainhash.c 
b/net/netlabel/netlabel_domainhash.c
index b3675bd..1f8f7ac 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -109,17 +109,14 @@ static u32 netlbl_domhsh_hash(const char *key)
 /**
  * netlbl_domhsh_search - Search for a domain entry
  * @domain: the domain
- * @def: return default if no match is found
  *
  * Description:
  * Searches the domain hash table and returns a pointer to the hash table
- * entry if found, otherwise NULL is returned.  If @def is non-zero and a
- * match is not found in the domain hash table the default mapping is returned
- * if it exists.  The caller is responsibile for the rcu hash table locks
- * (i.e. the caller much call rcu_read_[un]lock()).
+ * entry if found, otherwise NULL is returned.  The caller is responsibile for
+ * the rcu hash table locks (i.e. the caller much call rcu_read_[un]lock()).
  *
  */
-static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain, u32 def)
+static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
 {
u32 bkt;
struct netlbl_dom_map *iter;
@@ -133,10 +130,31 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const 
char *domain, u32 def)
return iter;
}
 
-   if (def != 0) {
-   iter = rcu_dereference(netlbl_domhsh_def);
-   if (iter != NULL && iter->valid)
-   return iter;
+   return NULL;
+}
+
+/**
+ * netlbl_domhsh_search_def - Search for a domain entry
+ * @domain: the domain
+ * @def: return default if no match is found
+ *
+ * Description:
+ * Searches the domain hash table and returns a pointer to the hash table
+ * entry if an exact match is found, if an exact match is not present in the
+ * hash table then the default entry is returned if valid otherwise NULL is
+ * returned.  The caller is responsibile for the rcu hash table locks
+ * (i.e. the caller much call rcu_read_[un]lock()).
+ *
+ */
+static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
+{
+   struct netlbl_dom_map *entry;
+
+   entry = netlbl_domhsh_search(domain);
+   if (entry == NULL) {
+   entry = rcu_dereference(netlbl_domhsh_def);
+   if (entry != NULL && entry->valid)
+   return entry;
}
 
return NULL;
@@ -224,7 +242,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
if (entry->domain != NULL) {
bkt = netlbl_domhsh_hash(entry->domain);
spin_lock(&netlbl_domhsh_lock);
-   if (netlbl_domhsh_search(entry->domain, 0) == NULL)
+   if (netlbl_domhsh_search(entry->domain) == NULL)
list_add_tail_rcu(&entry->list,
&rcu_dereference(netlbl_domhsh)->tbl[bkt]);
else
@@ -307,7 +325,10 @@ int netlbl_domhsh_remove(const char *domain, struct 
netlbl_audit *audit_info)
struct audit_buffer *audit_buf;
 
rcu_read_lock();
-   entry = netlbl_domhsh_search(domain, (domain != NULL ? 0 : 1));
+   if (domain)
+   entry = netlbl_domhsh_search(domain);
+   else
+   entry = netlbl_domhsh_search_def(domain);
if (entry == NULL)
goto remove_return;
switch (entry->type) {
@@ -377,7 +398,7 @@ int netlbl_domhsh_remove_default(struct netlbl_audit 
*audit_info)
  */
 struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain)
 {
-   return netlbl_domhsh_search(domain, 1);
+   return netlbl_domhsh_search_def(domain);
 }
 
 /**

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v8 15/18] SELinux: Allow NetLabel to directly cache SIDs

2007-12-14 Thread Paul Moore
Now that the SELinux NetLabel "base SID" is always the netmsg initial SID we
can do a big optimization - caching the SID and not just the MLS attributes.
This not only saves a lot of per-packet memory allocations and copies but it
has a nice side effect of removing a chunk of code.
---

 security/selinux/hooks.c|6 --
 security/selinux/include/netlabel.h |2 -
 security/selinux/include/security.h |2 -
 security/selinux/netlabel.c |   55 ++--
 security/selinux/ss/services.c  |  124 ++-
 5 files changed, 55 insertions(+), 134 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c384949..2f221b2 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3231,11 +3231,7 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, 
u16 family, u32 *sid)
u32 nlbl_type;
 
selinux_skb_xfrm_sid(skb, &xfrm_sid);
-   selinux_netlbl_skbuff_getsid(skb,
-family,
-SECINITSID_NETMSG,
-&nlbl_type,
-&nlbl_sid);
+   selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
 
if (security_net_peersid_resolve(nlbl_sid, nlbl_type,
 xfrm_sid,
diff --git a/security/selinux/include/netlabel.h 
b/security/selinux/include/netlabel.h
index c8c05a6..00a2809 100644
--- a/security/selinux/include/netlabel.h
+++ b/security/selinux/include/netlabel.h
@@ -48,7 +48,6 @@ void selinux_netlbl_sk_security_clone(struct 
sk_security_struct *ssec,
 
 int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
 u16 family,
-u32 base_sid,
 u32 *type,
 u32 *sid);
 
@@ -89,7 +88,6 @@ static inline void selinux_netlbl_sk_security_clone(
 
 static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
   u16 family,
-  u32 base_sid,
   u32 *type,
   u32 *sid)
 {
diff --git a/security/selinux/include/security.h 
b/security/selinux/include/security.h
index 9347e2d..23137c1 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -124,7 +124,6 @@ int security_genfs_sid(const char *fstype, char *name, u16 
sclass,
 
 #ifdef CONFIG_NETLABEL
 int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
-  u32 base_sid,
   u32 *sid);
 
 int security_netlbl_sid_to_secattr(u32 sid,
@@ -132,7 +131,6 @@ int security_netlbl_sid_to_secattr(u32 sid,
 #else
 static inline int security_netlbl_secattr_to_sid(
struct netlbl_lsm_secattr *secattr,
-   u32 base_sid,
u32 *sid)
 {
return -EIDRM;
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index af78cb9..e07adf9 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -36,6 +36,33 @@
 #include "security.h"
 
 /**
+ * selinux_netlbl_sidlookup_cached - Cache a SID lookup
+ * @skb: the packet
+ * @secattr: the NetLabel security attributes
+ * @sid: the SID
+ *
+ * Description:
+ * Query the SELinux security server to lookup the correct SID for the given
+ * security attributes.  If the query is successful, cache the result to speed
+ * up future lookups.  Returns zero on success, negative values on failure.
+ *
+ */
+static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
+  struct netlbl_lsm_secattr *secattr,
+  u32 *sid)
+{
+   int rc;
+
+   rc = security_netlbl_secattr_to_sid(secattr, sid);
+   if (rc == 0 &&
+   (secattr->flags & NETLBL_SECATTR_CACHEABLE) &&
+   (secattr->flags & NETLBL_SECATTR_CACHE))
+   netlbl_cache_add(skb, secattr);
+
+   return rc;
+}
+
+/**
  * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism
  * @sk: the socket to label
  * @sid: the SID to use
@@ -141,7 +168,6 @@ void selinux_netlbl_sk_security_clone(struct 
sk_security_struct *ssec,
  * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel
  * @skb: the packet
  * @family: protocol family
- * @base_sid: the SELinux SID to use as a context for MLS only attributes
  * @type: NetLabel labeling protocol type
  * @sid: the SID
  *
@@ -153,7 +179,6 @@ void selinux_netlbl_sk_security_clone(struct 
sk_security_struct *ssec,
  */
 int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
 u16 family,
-u3

[RFC PATCH v8 17/18] NetLabel: Add auditing to the static labeling mechanism

2007-12-14 Thread Paul Moore
This patch adds auditing support to the NetLabel static labeling mechanism.
---

 include/linux/audit.h |2 
 net/netlabel/netlabel_unlabeled.c |  207 ++---
 2 files changed, 195 insertions(+), 14 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index c687816..bdd6f5d 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -115,6 +115,8 @@
 #define AUDIT_MAC_IPSEC_ADDSPD 1413/* Not used */
 #define AUDIT_MAC_IPSEC_DELSPD 1414/* Not used */
 #define AUDIT_MAC_IPSEC_EVENT  1415/* Audit an IPSec event */
+#define AUDIT_MAC_UNLBL_STCADD 1416/* NetLabel: add a static label */
+#define AUDIT_MAC_UNLBL_STCDEL 1417/* NetLabel: del a static label */
 
 #define AUDIT_FIRST_KERN_ANOM_MSG   1700
 #define AUDIT_LAST_KERN_ANOM_MSG1799
diff --git a/net/netlabel/netlabel_unlabeled.c 
b/net/netlabel/netlabel_unlabeled.c
index d289ff4..cdeb6d9 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -148,6 +148,74 @@ static const struct nla_policy 
netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1
 };
 
 /*
+ * Audit Helper Functions
+ */
+
+/**
+ * netlbl_unlabel_audit_addr4 - Audit an IPv4 address
+ * @audit_buf: audit buffer
+ * @dev: network interface
+ * @addr: IP address
+ * @mask: IP address mask
+ *
+ * Description:
+ * Write the IPv4 address and address mask, if necessary, to @audit_buf.
+ *
+ */
+static void netlbl_unlabel_audit_addr4(struct audit_buffer *audit_buf,
+const char *dev,
+__be32 addr, __be32 mask)
+{
+   u32 mask_val = ntohl(mask);
+
+   if (dev != NULL)
+   audit_log_format(audit_buf, " netif=%s", dev);
+   audit_log_format(audit_buf, " src=" NIPQUAD_FMT, NIPQUAD(addr));
+   if (mask_val != 0x) {
+   u32 mask_len = 0;
+   while (mask_val > 0) {
+   mask_val <<= 1;
+   mask_len++;
+   }
+   audit_log_format(audit_buf, " src_prefixlen=%d", mask_len);
+   }
+}
+
+/**
+ * netlbl_unlabel_audit_addr6 - Audit an IPv6 address
+ * @audit_buf: audit buffer
+ * @dev: network interface
+ * @addr: IP address
+ * @mask: IP address mask
+ *
+ * Description:
+ * Write the IPv6 address and address mask, if necessary, to @audit_buf.
+ *
+ */
+static void netlbl_unlabel_audit_addr6(struct audit_buffer *audit_buf,
+const char *dev,
+const struct in6_addr *addr,
+const struct in6_addr *mask)
+{
+   if (dev != NULL)
+   audit_log_format(audit_buf, " netif=%s", dev);
+   audit_log_format(audit_buf, " src=" NIP6_FMT, NIP6(*addr));
+   if (ntohl(mask->s6_addr32[3]) != 0x) {
+   u32 mask_len = 0;
+   u32 mask_val;
+   int iter = -1;
+   while (ntohl(mask->s6_addr32[++iter]) == 0x)
+   mask_len += 32;
+   mask_val = ntohl(mask->s6_addr32[iter]);
+   while (mask_val > 0) {
+   mask_val <<= 1;
+   mask_len++;
+   }
+   audit_log_format(audit_buf, " src_prefixlen=%d", mask_len);
+   }
+}
+
+/*
  * Unlabeled Connection Hash Table Functions
  */
 
@@ -524,6 +592,7 @@ add_iface_failure:
  * @mask: address mask in network byte order
  * @addr_len: length of address/mask (4 for IPv4, 16 for IPv6)
  * @secid: LSM secid value for the entry
+ * @audit_info: NetLabel audit information
  *
  * Description:
  * Adds a new entry to the unlabeled connection hash table.  Returns zero on
@@ -535,12 +604,18 @@ static int netlbl_unlhsh_add(struct net *net,
 const void *addr,
 const void *mask,
 u32 addr_len,
-u32 secid)
+u32 secid,
+struct netlbl_audit *audit_info)
 {
int ret_val;
int ifindex;
struct net_device *dev;
struct netlbl_unlhsh_iface *iface;
+   struct in_addr *addr4, *mask4;
+   struct in6_addr *addr6, *mask6;
+   struct audit_buffer *audit_buf = NULL;
+   char *secctx = NULL;
+   u32 secctx_len;
 
if (addr_len != sizeof(struct in_addr) &&
addr_len != sizeof(struct in6_addr))
@@ -567,13 +642,28 @@ static int netlbl_unlhsh_add(struct net *net,
goto unlhsh_add_return;
}
}
+   audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCADD,
+ audit_info);
switch (addr_len) {
case sizeof(struct in_addr):
-   ret_val = netlbl_unlhsh_add_addr4(iface, addr, mask, secid);
+   addr4 = (struct in_addr *)addr;
+   mask4 = (struct in_ad

[RFC PATCH v8 04/18] NetLabel: Add secid token support to the NetLabel secattr struct

2007-12-14 Thread Paul Moore
This patch adds support to the NetLabel LSM secattr struct for a secid token
and a type field, paving the way for full LSM/SELinux context support and
"static" or "fallback" labels.  In addition, this patch adds a fair amount
of documentation to the core NetLabel structures used as part of the
NetLabel kernel API.
---

 include/net/netlabel.h|   91 ++---
 net/ipv4/cipso_ipv4.c |   59 +++-
 net/netlabel/netlabel_unlabeled.c |1 
 security/selinux/ss/mls.c |   10 ++--
 security/selinux/ss/services.c|5 ++
 5 files changed, 120 insertions(+), 46 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 2e5b2f6..18b73cf 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -105,17 +105,49 @@ struct netlbl_dom_map;
 /* Domain mapping operations */
 int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
 
-/* LSM security attributes */
+/*
+ * LSM security attributes
+ */
+
+/**
+ * struct netlbl_lsm_cache - NetLabel LSM security attribute cache
+ * @refcount: atomic reference counter
+ * @free: LSM supplied function to free the cache data
+ * @data: LSM supplied cache data
+ *
+ * Description:
+ * This structure is provided for LSMs which wish to make use of the NetLabel
+ * caching mechanism to store LSM specific data/attributes in the NetLabel
+ * cache.  If the LSM has to perform a lot of translation from the NetLabel
+ * security attributes into it's own internal representation then the cache
+ * mechanism can provide a way to eliminate some or all of that translation
+ * overhead on a cache hit.
+ *
+ */
 struct netlbl_lsm_cache {
atomic_t refcount;
void (*free) (const void *data);
void *data;
 };
-/* The catmap bitmap field MUST be a power of two in length and large
+
+/**
+ * struct netlbl_lsm_secattr_catmap - NetLabel LSM secattr category bitmap
+ * @startbit: the value of the lowest order bit in the bitmap
+ * @bitmap: the category bitmap
+ * @next: pointer to the next bitmap "node" or NULL
+ *
+ * Description:
+ * This structure is used to represent category bitmaps.  Due to the large
+ * number of categories supported by most labeling protocols it is not
+ * practical to transfer a full bitmap internally so NetLabel adopts a sparse
+ * bitmap structure modeled after SELinux's ebitmap structure.
+ * The catmap bitmap field MUST be a power of two in length and large
  * enough to hold at least 240 bits.  Special care (i.e. check the code!)
  * should be used when changing these values as the LSM implementation
  * probably has functions which rely on the sizes of these types to speed
- * processing. */
+ * processing.
+ *
+ */
 #define NETLBL_CATMAP_MAPTYPE   u64
 #define NETLBL_CATMAP_MAPCNT4
 #define NETLBL_CATMAP_MAPSIZE   (sizeof(NETLBL_CATMAP_MAPTYPE) * 8)
@@ -127,22 +159,48 @@ struct netlbl_lsm_secattr_catmap {
NETLBL_CATMAP_MAPTYPE bitmap[NETLBL_CATMAP_MAPCNT];
struct netlbl_lsm_secattr_catmap *next;
 };
+
+/**
+ * struct netlbl_lsm_secattr - NetLabel LSM security attributes
+ * @flags: indicate which attributes are contained in this structure
+ * @type: indicate the NLTYPE of the attributes
+ * @domain: the NetLabel LSM domain
+ * @cache: NetLabel LSM specific cache
+ * @attr.mls: MLS sensitivity label
+ * @attr.mls.cat: MLS category bitmap
+ * @attr.mls.lvl: MLS sensitivity level
+ * @attr.secid: LSM specific secid token
+ *
+ * Description:
+ * This structure is used to pass security attributes between NetLabel and the
+ * LSM modules.  The flags field is used to specify which fields within the
+ * struct are valid and valid values can be created by bitwise OR'ing the
+ * NETLBL_SECATTR_* defines.  The domain field is typically set by the LSM to
+ * specify domain specific configuration settings and is not usually used by
+ * NetLabel itself when returning security attributes to the LSM.
+ *
+ */
 #define NETLBL_SECATTR_NONE 0x
 #define NETLBL_SECATTR_DOMAIN   0x0001
 #define NETLBL_SECATTR_CACHE0x0002
 #define NETLBL_SECATTR_MLS_LVL  0x0004
 #define NETLBL_SECATTR_MLS_CAT  0x0008
+#define NETLBL_SECATTR_SECID0x0010
 #define NETLBL_SECATTR_CACHEABLE(NETLBL_SECATTR_MLS_LVL | \
-NETLBL_SECATTR_MLS_CAT)
+NETLBL_SECATTR_MLS_CAT | \
+NETLBL_SECATTR_SECID)
 struct netlbl_lsm_secattr {
u32 flags;
-
+   u32 type;
char *domain;
-
-   u32 mls_lvl;
-   struct netlbl_lsm_secattr_catmap *mls_cat;
-
struct netlbl_lsm_cache *cache;
+   union {
+   struct {
+   struct netlbl_lsm_secattr_catmap *cat;
+   u32 lvl;
+   } mls;
+   u32 secid;
+   } attr;
 };
 
 /*

[RFC PATCH v8 01/18] NetLabel: Remove unneeded RCU read locks

2007-12-14 Thread Paul Moore
This patch removes some unneeded RCU read locks as we can treat the reads as
"safe" even without RCU.  It also converts the NetLabel configuration refcount
from a spinlock protected u32 into atomic_t to be more consistent with the rest
of the kernel.
---

 net/netlabel/netlabel_cipso_v4.c  |5 ++-
 net/netlabel/netlabel_kapi.c  |3 +-
 net/netlabel/netlabel_mgmt.c  |   63 ++---
 net/netlabel/netlabel_mgmt.h  |7 ++--
 net/netlabel/netlabel_unlabeled.c |   17 ++
 5 files changed, 15 insertions(+), 80 deletions(-)

diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index ba0ca8d..becf91a 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "netlabel_user.h"
 #include "netlabel_cipso_v4.h"
@@ -421,7 +422,7 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct 
genl_info *info)
break;
}
if (ret_val == 0)
-   netlbl_mgmt_protocount_inc();
+   atomic_inc(&netlabel_mgmt_protocount);
 
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
  &audit_info);
@@ -698,7 +699,7 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, 
struct genl_info *info)
  &audit_info,
  netlbl_cipsov4_doi_free);
if (ret_val == 0)
-   netlbl_mgmt_protocount_dec();
+   atomic_dec(&netlabel_mgmt_protocount);
 
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
  &audit_info);
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 4f50949..d3762ea 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "netlabel_domainhash.h"
 #include "netlabel_unlabeled.h"
@@ -262,7 +263,7 @@ int netlbl_enabled(void)
/* At some point we probably want to expose this mechanism to the user
 * as well so that admins can toggle NetLabel regardless of the
 * configuration */
-   return (netlbl_mgmt_protocount_value() > 0 ? 1 : 0);
+   return (atomic_read(&netlabel_mgmt_protocount) > 0);
 }
 
 /**
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index 5648337..e2258dc 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -37,14 +37,14 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "netlabel_domainhash.h"
 #include "netlabel_user.h"
 #include "netlabel_mgmt.h"
 
-/* NetLabel configured protocol count */
-static DEFINE_SPINLOCK(netlabel_mgmt_protocount_lock);
-static u32 netlabel_mgmt_protocount = 0;
+/* NetLabel configured protocol counter */
+atomic_t netlabel_mgmt_protocount = ATOMIC_INIT(0);
 
 /* Argument struct for netlbl_domhsh_walk() */
 struct netlbl_domhsh_walk_arg {
@@ -71,63 +71,6 @@ static const struct nla_policy 
netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
 };
 
 /*
- * NetLabel Misc Managment Functions
- */
-
-/**
- * netlbl_mgmt_protocount_inc - Increment the configured labeled protocol count
- *
- * Description:
- * Increment the number of labeled protocol configurations in the current
- * NetLabel configuration.  Keep track of this for use in determining if
- * NetLabel label enforcement should be active/enabled or not in the LSM.
- *
- */
-void netlbl_mgmt_protocount_inc(void)
-{
-   spin_lock(&netlabel_mgmt_protocount_lock);
-   netlabel_mgmt_protocount++;
-   spin_unlock(&netlabel_mgmt_protocount_lock);
-}
-
-/**
- * netlbl_mgmt_protocount_dec - Decrement the configured labeled protocol count
- *
- * Description:
- * Decrement the number of labeled protocol configurations in the current
- * NetLabel configuration.  Keep track of this for use in determining if
- * NetLabel label enforcement should be active/enabled or not in the LSM.
- *
- */
-void netlbl_mgmt_protocount_dec(void)
-{
-   spin_lock(&netlabel_mgmt_protocount_lock);
-   if (netlabel_mgmt_protocount > 0)
-   netlabel_mgmt_protocount--;
-   spin_unlock(&netlabel_mgmt_protocount_lock);
-}
-
-/**
- * netlbl_mgmt_protocount_value - Return the number of configured protocols
- *
- * Description:
- * Return the number of labeled protocols in the current NetLabel
- * configuration.  This value is useful in  determining if NetLabel label
- * enforcement should be active/enabled or not in the LSM.
- *
- */
-u32 netlbl_mgmt_protocount_value(void)
-{
-   u32 val;
-
-   rcu_read_lock();
-   val = netlabel_mgmt_protocount;
-   rcu_read_unlock();
-
-   return val;
-}
-
-/*
  * NetLabel Command Handlers
  */
 
diff --git a/net/netlabel/netlabel_mgmt.h b/net/netlabel/netlabel_mgmt.h
index ccb2b39..a43bff1 100644
--- a/net/netlabel/netlabel_mgmt.h
+++

[RFC PATCH v8 03/18] NetLabel: Consolidate the LSM domain mapping/hashing locks

2007-12-14 Thread Paul Moore
Currently we use two separate spinlocks to protect both the hash/mapping table
and the default entry.  This could be considered a bit foolish because it adds
complexity without offering any real performance advantage.  This patch
removes the dedicated default spinlock and protects the default entry with the
hash/mapping table spinlock.
---

 net/netlabel/netlabel_domainhash.c |   30 +-
 1 files changed, 9 insertions(+), 21 deletions(-)

diff --git a/net/netlabel/netlabel_domainhash.c 
b/net/netlabel/netlabel_domainhash.c
index 1f8f7ac..9a8ea01 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -54,9 +54,6 @@ struct netlbl_domhsh_tbl {
  * hash table should be okay */
 static DEFINE_SPINLOCK(netlbl_domhsh_lock);
 static struct netlbl_domhsh_tbl *netlbl_domhsh = NULL;
-
-/* Default domain mapping */
-static DEFINE_SPINLOCK(netlbl_domhsh_def_lock);
 static struct netlbl_dom_map *netlbl_domhsh_def = NULL;
 
 /*
@@ -239,24 +236,22 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
INIT_RCU_HEAD(&entry->rcu);
 
rcu_read_lock();
+   spin_lock(&netlbl_domhsh_lock);
if (entry->domain != NULL) {
bkt = netlbl_domhsh_hash(entry->domain);
-   spin_lock(&netlbl_domhsh_lock);
if (netlbl_domhsh_search(entry->domain) == NULL)
list_add_tail_rcu(&entry->list,
&rcu_dereference(netlbl_domhsh)->tbl[bkt]);
else
ret_val = -EEXIST;
-   spin_unlock(&netlbl_domhsh_lock);
} else {
INIT_LIST_HEAD(&entry->list);
-   spin_lock(&netlbl_domhsh_def_lock);
if (rcu_dereference(netlbl_domhsh_def) == NULL)
rcu_assign_pointer(netlbl_domhsh_def, entry);
else
ret_val = -EEXIST;
-   spin_unlock(&netlbl_domhsh_def_lock);
}
+   spin_unlock(&netlbl_domhsh_lock);
audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
if (audit_buf != NULL) {
audit_log_format(audit_buf,
@@ -337,23 +332,16 @@ int netlbl_domhsh_remove(const char *domain, struct 
netlbl_audit *audit_info)
   entry->domain);
break;
}
-   if (entry != rcu_dereference(netlbl_domhsh_def)) {
-   spin_lock(&netlbl_domhsh_lock);
-   if (entry->valid) {
-   entry->valid = 0;
+   spin_lock(&netlbl_domhsh_lock);
+   if (entry->valid) {
+   entry->valid = 0;
+   if (entry != rcu_dereference(netlbl_domhsh_def))
list_del_rcu(&entry->list);
-   ret_val = 0;
-   }
-   spin_unlock(&netlbl_domhsh_lock);
-   } else {
-   spin_lock(&netlbl_domhsh_def_lock);
-   if (entry->valid) {
-   entry->valid = 0;
+   else
rcu_assign_pointer(netlbl_domhsh_def, NULL);
-   ret_val = 0;
-   }
-   spin_unlock(&netlbl_domhsh_def_lock);
+   ret_val = 0;
}
+   spin_unlock(&netlbl_domhsh_lock);
 
audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info);
if (audit_buf != NULL) {

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v8 16/18] NetLabel: Introduce static network labels for unlabeled connections

2007-12-14 Thread Paul Moore
Most trusted OSs, with the exception of Linux, have the ability to specify
static security labels for unlabeled networks.  This patch adds this ability to
the NetLabel packet labeling framework.

If the NetLabel subsystem is called to determine the security attributes of an
incoming packet it first checks to see if any recognized NetLabel packet
labeling protocols are in-use on the packet.  If none can be found then the
unlabled connection table is queried and based on the packets incoming
interface and address it is matched with a security label as configured by the
administrator using the netlabel_tools package.  The matching security label is
returned to the caller just as if the packet was explicitly labeled using a
labeling protocol.
---

 include/net/netlabel.h|6 
 net/netlabel/netlabel_kapi.c  |   16 
 net/netlabel/netlabel_unlabeled.c | 1367 +
 net/netlabel/netlabel_unlabeled.h |  145 
 4 files changed, 1516 insertions(+), 18 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index a3bffb4..b3213c7 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -67,7 +67,11 @@
  * NetLabel NETLINK protocol
  */
 
-#define NETLBL_PROTO_VERSION1
+/* NetLabel NETLINK protocol version
+ *  1: initial version
+ *  2: added static labels for unlabeled connections
+ */
+#define NETLBL_PROTO_VERSION2
 
 /* NetLabel NETLINK types/families */
 #define NETLBL_NLTYPE_NONE  0
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 4914615..c69e3e1 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -312,7 +312,7 @@ socket_setattr_return:
  * @secattr: the security attributes
  *
  * Description:
- * Examines the given sock to see any NetLabel style labeling has been
+ * Examines the given sock to see if any NetLabel style labeling has been
  * applied to the sock, if so it parses the socket label and returns the
  * security attributes in @secattr.  Returns zero on success, negative values
  * on failure.
@@ -320,13 +320,7 @@ socket_setattr_return:
  */
 int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
 {
-   int ret_val;
-
-   ret_val = cipso_v4_sock_getattr(sk, secattr);
-   if (ret_val == 0)
-   return 0;
-
-   return netlbl_unlabel_getattr(secattr);
+   return cipso_v4_sock_getattr(sk, secattr);
 }
 
 /**
@@ -350,7 +344,7 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
cipso_v4_skbuff_getattr(skb, secattr) == 0)
return 0;
 
-   return netlbl_unlabel_getattr(secattr);
+   return netlbl_unlabel_getattr(skb, family, secattr);
 }
 
 /**
@@ -434,6 +428,10 @@ static int __init netlbl_init(void)
if (ret_val != 0)
goto init_failure;
 
+   ret_val = netlbl_unlabel_init(NETLBL_UNLHSH_BITSIZE);
+   if (ret_val != 0)
+   goto init_failure;
+
ret_val = netlbl_netlink_init();
if (ret_val != 0)
goto init_failure;
diff --git a/net/netlabel/netlabel_unlabeled.c 
b/net/netlabel/netlabel_unlabeled.c
index 5e11394..d289ff4 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -10,7 +10,7 @@
  */
 
 /*
- * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
+ * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - 2007
  *
  * This program is free software;  you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -36,22 +36,93 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
-
+#include 
+#include 
+#include 
 #include 
 #include 
+#include 
 
 #include "netlabel_user.h"
 #include "netlabel_domainhash.h"
 #include "netlabel_unlabeled.h"
+#include "netlabel_mgmt.h"
+
+/* NOTE: at present we always use init's network namespace since we don't
+ *   presently support different namespaces even though the majority of
+ *   the functions in this file are "namespace safe" */
+
+/* The unlabeled connection hash table which we use to map network interfaces
+ * and addresses of unlabeled packets to a user specified secid value for the
+ * LSM.  The hash table is used to lookup the network interface entry
+ * (struct netlbl_unlhsh_iface) and then the interface entry is used to
+ * lookup an IP address match from an ordered list.  If a network interface
+ * match can not be found in the hash table then the default entry
+ * (netlbl_unlhsh_def) is used.  The IP address entry list
+ * (struct netlbl_unlhsh_addr) is ordered such that the entries with a
+ * larger netmask come first.
+ */
+struct netlbl_unlhsh_tbl {
+   struct list_head *tbl;
+   u32 size;
+};
+struct netlbl_unlhsh_addr4 {
+   __be32 addr;
+   __be32 mask;
+   u32 secid;
+
+   u32 valid;
+  

[RFC PATCH v8 11/18] SELinux: Add a capabilities bitmap to SELinux policy version 22

2007-12-14 Thread Paul Moore
Add a new policy capabilities bitmap to SELinux policy version 22.  This bitmap
will enable the security server to query the policy to determine which features
it supports.
---

 security/selinux/Kconfig|2 -
 security/selinux/include/security.h |   15 ++
 security/selinux/selinuxfs.c|   89 +--
 security/selinux/ss/policydb.c  |   18 +++
 security/selinux/ss/policydb.h  |2 +
 security/selinux/ss/services.c  |   67 ++
 6 files changed, 185 insertions(+), 8 deletions(-)

diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
index b32a459..2b517d6 100644
--- a/security/selinux/Kconfig
+++ b/security/selinux/Kconfig
@@ -145,7 +145,7 @@ config SECURITY_SELINUX_POLICYDB_VERSION_MAX
 config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
int "NSA SELinux maximum supported policy format version value"
depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX
-   range 15 21
+   range 15 22
default 19
help
  This option sets the value for the maximum policy format version
diff --git a/security/selinux/include/security.h 
b/security/selinux/include/security.h
index a33437b..a22de97 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -25,13 +25,14 @@
 #define POLICYDB_VERSION_MLS   19
 #define POLICYDB_VERSION_AVTAB 20
 #define POLICYDB_VERSION_RANGETRANS21
+#define POLICYDB_VERSION_POLCAP22
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX   
CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_RANGETRANS
+#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_POLCAP
 #endif
 
 struct netlbl_lsm_secattr;
@@ -39,8 +40,19 @@ struct netlbl_lsm_secattr;
 extern int selinux_enabled;
 extern int selinux_mls_enabled;
 
+/* Policy capabilities */
+enum {
+   POLICYDB_CAPABILITY_NETPEER,
+   __POLICYDB_CAPABILITY_MAX
+};
+#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
+
+extern int selinux_policycap_netpeer;
+
 int security_load_policy(void * data, size_t len);
 
+int security_policycap_supported(unsigned int req_cap);
+
 #define SEL_VEC_MAX 32
 struct av_decision {
u32 allowed;
@@ -91,6 +103,7 @@ int security_get_classes(char ***classes, int *nclasses);
 int security_get_permissions(char *class, char ***perms, int *nperms);
 int security_get_reject_unknown(void);
 int security_get_allow_unknown(void);
+int security_get_policycaps(int *len, int **values);
 
 #define SECURITY_FS_USE_XATTR  1 /* use xattr */
 #define SECURITY_FS_USE_TRANS  2 /* use transition SIDs, e.g. 
devpts/tmpfs */
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 2fa483f..b87e9eb 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -2,6 +2,11 @@
  *
  * Added conditional policy language extensions
  *
+ *  Updated: Hewlett-Packard <[EMAIL PROTECTED]>
+ *
+ *  Added support for the policy capability bitmap
+ *
+ * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2003 - 2004 Tresys Technology, LLC
  * Copyright (C) 2004 Red Hat, Inc., James Morris <[EMAIL PROTECTED]>
  * This program is free software; you can redistribute it and/or modify
@@ -35,6 +40,11 @@
 #include "objsec.h"
 #include "conditional.h"
 
+/* Policy capability filenames */
+static char *policycap_names[] = {
+   "network_peer_controls"
+};
+
 unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
 
 #ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
@@ -72,6 +82,9 @@ static int *bool_pending_values = NULL;
 static struct dentry *class_dir = NULL;
 static unsigned long last_class_ino;
 
+/* global data for policy capabilities */
+static struct dentry *policycap_dir = NULL;
+
 extern void selnl_notify_setenforce(int val);
 
 /* Check whether a task is allowed to use a security operation. */
@@ -111,10 +124,11 @@ enum sel_inos {
 
 static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
 
-#define SEL_INITCON_INO_OFFSET 0x0100
-#define SEL_BOOL_INO_OFFSET0x0200
-#define SEL_CLASS_INO_OFFSET   0x0400
-#define SEL_INO_MASK   0x00ff
+#define SEL_INITCON_INO_OFFSET 0x0100
+#define SEL_BOOL_INO_OFFSET0x0200
+#define SEL_CLASS_INO_OFFSET   0x0400
+#define SEL_POLICYCAP_INO_OFFSET   0x0800
+#define SEL_INO_MASK   0x00ff
 
 #define TMPBUFLEN  12
 static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
@@ -263,6 +277,7 @@ static const struct file_operations sel_policyvers_ops = {
 /* declaration for sel_write_load */
 static int sel_make_bools(void);
 static int sel_make_classes(void);
+static int sel_make_po

[RFC PATCH v8 08/18] SELinux: Convert the netif code to use ifindex values

2007-12-14 Thread Paul Moore
The current SELinux netif code requires the caller have a valid net_device
struct pointer to lookup network interface information.  However, we don't
always have a valid net_device pointer so convert the netif code to use
the ifindex values we always have as part of the sk_buff.  This patch also
removes the default message SID from the network interface record, it is
not being used and therefore is "dead code".
---

 security/selinux/hooks.c|4 -
 security/selinux/include/netif.h|4 -
 security/selinux/include/objsec.h   |5 -
 security/selinux/include/security.h |3 
 security/selinux/netif.c|  254 ---
 security/selinux/ss/services.c  |   10 -
 6 files changed, 155 insertions(+), 125 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 2188b9c..2ca8dfb 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3616,7 +3616,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, 
struct sk_buff *skb,
if (!skb->dev)
goto out;
 
-   err = sel_netif_sids(skb->dev, &if_sid, NULL);
+   err = sel_netif_sid(skb->iif, &if_sid);
if (err)
goto out;
 
@@ -3942,7 +3942,7 @@ static int selinux_ip_postroute_last_compat(struct sock 
*sk, struct net_device *
 
isec = inode->i_security;

-   err = sel_netif_sids(dev, &if_sid, NULL);
+   err = sel_netif_sid(dev->ifindex, &if_sid);
if (err)
goto out;
 
diff --git a/security/selinux/include/netif.h b/security/selinux/include/netif.h
index 8bd6f99..ce23edd 100644
--- a/security/selinux/include/netif.h
+++ b/security/selinux/include/netif.h
@@ -7,6 +7,8 @@
  * Author: James Morris <[EMAIL PROTECTED]>
  *
  * Copyright (C) 2003 Red Hat, Inc., James Morris <[EMAIL PROTECTED]>
+ * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
+ *Paul Moore, <[EMAIL PROTECTED]>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2,
@@ -15,7 +17,7 @@
 #ifndef _SELINUX_NETIF_H_
 #define _SELINUX_NETIF_H_
 
-int sel_netif_sids(struct net_device *dev, u32 *if_sid, u32 *msg_sid);
+int sel_netif_sid(int ifindex, u32 *sid);
 
 #endif /* _SELINUX_NETIF_H_ */
 
diff --git a/security/selinux/include/objsec.h 
b/security/selinux/include/objsec.h
index 642a9fd..e41a2aa 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -95,9 +95,8 @@ struct bprm_security_struct {
 };
 
 struct netif_security_struct {
-   struct net_device *dev; /* back pointer */
-   u32 if_sid; /* SID for this interface */
-   u32 msg_sid;/* default SID for messages received on 
this interface */
+   int ifindex;/* device index */
+   u32 sid;/* SID for this interface */
 };
 
 struct sk_security_struct {
diff --git a/security/selinux/include/security.h 
b/security/selinux/include/security.h
index 39337af..a33437b 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -77,8 +77,7 @@ int security_get_user_sids(u32 callsid, char *username,
 int security_port_sid(u16 domain, u16 type, u8 protocol, u16 port,
u32 *out_sid);
 
-int security_netif_sid(char *name, u32 *if_sid,
-   u32 *msg_sid);
+int security_netif_sid(char *name, u32 *if_sid);
 
 int security_node_sid(u16 domain, void *addr, u32 addrlen,
u32 *out_sid);
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index e87ab94..ee49a73 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -7,6 +7,8 @@
  * Author: James Morris <[EMAIL PROTECTED]>
  *
  * Copyright (C) 2003 Red Hat, Inc., James Morris <[EMAIL PROTECTED]>
+ * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
+ *Paul Moore <[EMAIL PROTECTED]>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2,
@@ -29,14 +31,6 @@
 #define SEL_NETIF_HASH_SIZE64
 #define SEL_NETIF_HASH_MAX 1024
 
-#undef DEBUG
-
-#ifdef DEBUG
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 struct sel_netif
 {
struct list_head list;
@@ -49,174 +43,217 @@ static LIST_HEAD(sel_netif_list);
 static DEFINE_SPINLOCK(sel_netif_lock);
 static struct list_head sel_netif_hash[SEL_NETIF_HASH_SIZE];
 
-static inline u32 sel_netif_hasfn(struct net_device *dev)
+/**
+ * sel_netif_hashfn - Hashing function for the interface table
+ * @ifindex: the network interface
+ *
+ * Description:
+ * This is the hashing function for the network interface table, it returns the
+ * bucket number for the given interface.
+ *
+ */
+static inline u32 sel_ne

[RFC PATCH v8 13/18] SELinux: Better integration between peer labeling subsystems

2007-12-14 Thread Paul Moore
Rework the handling of network peer labels so that the different peer labeling
subsystems work better together.  This includes moving both subsystems to a
single "peer" object class which involves not only changes to the permission
checks but an improved method of consolidating multiple packet peer labels.
As part of this work the inbound packet permission check code has been heavily
modified to handle both the old and new behavior in as sane a fashion as
possible.
---

 security/selinux/hooks.c|  204 +++
 security/selinux/include/netlabel.h |3 +
 security/selinux/include/objsec.h   |2 
 security/selinux/include/security.h |4 +
 security/selinux/netlabel.c |   10 +-
 security/selinux/ss/services.c  |   85 +++
 6 files changed, 208 insertions(+), 100 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 05b58cc..e088a31 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -50,6 +50,7 @@
 #include 
 #include /* for local_port_range[] */
 #include/* struct or_callable used in sock_rcv_skb */
+#include 
 #include 
 #include 
 #include 
@@ -3189,36 +3190,39 @@ static int selinux_parse_skb(struct sk_buff *skb, 
struct avc_audit_data *ad,
 }
 
 /**
- * selinux_skb_extlbl_sid - Determine the external label of a packet
+ * selinux_skb_peerlbl_sid - Determine the peer label of a packet
  * @skb: the packet
  * @family: protocol family
- * @sid: the packet's SID
+ * @sid: the packet's peer label SID
  *
  * Description:
- * Check the various different forms of external packet labeling and determine
- * the external SID for the packet.  If only one form of external labeling is
- * present then it is used, if both labeled IPsec and NetLabel labels are
- * present then the SELinux type information is taken from the labeled IPsec
- * SA and the MLS sensitivity label information is taken from the NetLabel
- * security attributes.  This bit of "magic" is done in the call to
- * selinux_netlbl_skbuff_getsid().
+ * Check the various different forms of network peer labeling and determine
+ * the peer label/SID for the packet; most of the magic actually occurs in
+ * the security server function security_net_peersid_cmp().  The function
+ * returns zero if the value in @sid is valid (although it may be SECSID_NULL)
+ * or -EACCES if @sid is invalid due to inconsistencies with the different
+ * peer labels.
  *
  */
-static void selinux_skb_extlbl_sid(struct sk_buff *skb,
-  u16 family,
-  u32 *sid)
+static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
 {
u32 xfrm_sid;
u32 nlbl_sid;
+   u32 nlbl_type;
 
selinux_skb_xfrm_sid(skb, &xfrm_sid);
-   if (selinux_netlbl_skbuff_getsid(skb,
-family,
-(xfrm_sid == SECSID_NULL ?
- SECINITSID_NETMSG : xfrm_sid),
-&nlbl_sid) != 0)
-   nlbl_sid = SECSID_NULL;
-   *sid = (nlbl_sid == SECSID_NULL ? xfrm_sid : nlbl_sid);
+   selinux_netlbl_skbuff_getsid(skb,
+family,
+SECINITSID_NETMSG,
+&nlbl_type,
+&nlbl_sid);
+
+   if (security_net_peersid_resolve(nlbl_sid, nlbl_type,
+xfrm_sid,
+sid) != 0)
+   return -EACCES;
+
+   return 0;
 }
 
 /* socket security operations */
@@ -3284,6 +3288,7 @@ static int selinux_socket_post_create(struct socket 
*sock, int family,
if (sock->sk) {
sksec = sock->sk->sk_security;
sksec->sid = isec->sid;
+   sksec->sclass = isec->sclass;
err = selinux_netlbl_socket_post_create(sock);
}
 
@@ -3587,104 +3592,114 @@ static int selinux_socket_unix_may_send(struct socket 
*sock,
return 0;
 }
 
-static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
-  struct avc_audit_data *ad,
-  u16 family, char *addrp)
+static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk,
+   struct sk_buff *skb,
+   struct avc_audit_data *ad,
+   u16 family,
+   char *addrp)
 {
-   int err = 0;
-   u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0;
-   struct socket *sock;
-   u16 sock_class = 0;
-   u32 sock_sid = 0;
-
-   read_lock_bh(&sk->sk_callback_lock);
-   sock = sk->sk_socket;
-   if (sock) {
-   st

[RFC PATCH v8 10/18] SELinux: Add a network node caching mechanism similar to the sel_netif_*() functions

2007-12-14 Thread Paul Moore
-3922,9 +3921,11 @@ out:
 
 #ifdef CONFIG_NETFILTER
 
-static int selinux_ip_postroute_last_compat(struct sock *sk, struct net_device 
*dev,
+static int selinux_ip_postroute_last_compat(struct sock *sk,
+   struct net_device *dev,
struct avc_audit_data *ad,
-   u16 family, char *addrp, int len)
+   u16 family,
+   char *addrp)
 {
int err = 0;
u32 netif_perm, node_perm, node_sid, if_sid, send_perm = 0;
@@ -3975,7 +3976,7 @@ static int selinux_ip_postroute_last_compat(struct sock 
*sk, struct net_device *
if (err)
goto out;

-   err = security_node_sid(family, addrp, len, &node_sid);
+   err = sel_netnode_sid(addrp, family, &node_sid);
if (err)
goto out;

@@ -4009,7 +4010,7 @@ static unsigned int selinux_ip_postroute_last(unsigned 
int hooknum,
   u16 family)
 {
char *addrp;
-   int len, err = 0;
+   int err = 0;
struct sock *sk;
struct avc_audit_data ad;
struct net_device *dev = (struct net_device *)out;
@@ -4026,13 +4027,13 @@ static unsigned int selinux_ip_postroute_last(unsigned 
int hooknum,
ad.u.net.netif = dev->ifindex;
ad.u.net.family = family;
 
-   err = selinux_parse_skb(skb, &ad, &addrp, &len, 0, &proto);
+   err = selinux_parse_skb(skb, &ad, &addrp, 0, &proto);
if (err)
goto out;
 
if (selinux_compat_net)
err = selinux_ip_postroute_last_compat(sk, dev, &ad,
-  family, addrp, len);
+  family, addrp);
else
err = avc_has_perm(sksec->sid, skb->secmark, SECCLASS_PACKET,
   PACKET__SEND, &ad);
diff --git a/security/selinux/include/netnode.h 
b/security/selinux/include/netnode.h
new file mode 100644
index 000..1b94450
--- /dev/null
+++ b/security/selinux/include/netnode.h
@@ -0,0 +1,32 @@
+/*
+ * Network node table
+ *
+ * SELinux must keep a mapping of network nodes to labels/SIDs.  This
+ * mapping is maintained as part of the normal policy but a fast cache is
+ * needed to reduce the lookup overhead since most of these queries happen on
+ * a per-packet basis.
+ *
+ * Author: Paul Moore <[EMAIL PROTECTED]>
+ *
+ */
+
+/*
+ * (c) Copyright Hewlett-Packard Development Company, L.P., 2007
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _SELINUX_NETNODE_H
+#define _SELINUX_NETNODE_H
+
+int sel_netnode_sid(void *addr, u16 family, u32 *sid);
+
+#endif
diff --git a/security/selinux/include/objsec.h 
b/security/selinux/include/objsec.h
index e41a2aa..6140734 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -99,6 +99,15 @@ struct netif_security_struct {
u32 sid;/* SID for this interface */
 };
 
+struct netnode_security_struct {
+   union {
+   __be32 ipv4;/* IPv4 node address */
+   struct in6_addr ipv6;   /* IPv6 node address */
+   } addr;
+   u32 sid;/* SID for this node */
+   u16 family; /* address family */
+};
+
 struct sk_security_struct {
struct sock *sk;/* back pointer to sk object */
u32 sid;/* SID of this object */
diff --git a/security/selinux/netnode.c b/security/selinux/netnode.c
new file mode 100644
index 000..0cd66b8
--- /dev/null
+++ b/security/selinux/netnode.c
@@ -0,0 +1,351 @@
+/*
+ * Network node table
+ *
+ * SELinux must keep a mapping of network nodes to labels/SIDs.  This
+ * mapping is maintained as part of the normal policy but a fast cache is
+ * needed to reduce the lookup overhead since most of these queries happen on
+ * a per-packet basis.
+ *
+ * Author: Paul Moore <[EMAIL PROTECTED]>
+ *
+ * This code is heavily based on the "netif" concept originally developed by
+ * James Morris <[EMAIL PROTECTED]>
+ *   (see security/selinux/netif.c for more information)
+ * 
+ */
+
+/*
+ * (c) Copyright Hewlett-Packard Development Company, L.P., 2007
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of ver

[RFC PATCH v8 00/18] Update to the labeled networking patches for 2.6.25

2007-12-14 Thread Paul Moore
Another update to the labeled networking patchset, the lblnet-2.6_testing
git tree on infradead.org has been updated too for those of you who prefer to
get the changes that way.

With this version of the patchset I'm now considering the patches "feature
complete" for 2.6.25.  However, the push to get the features done in time has
meant that my testing has been, and continues to be, pretty light so please
don't consider this patch ready for inclusion anywhere yet.  I'm posting these
changes for people to review and test.

Since v7 there have been quite a few changes, although they have all been in
support of the big change - packet ingress/egress controls (formerly know as
"flow controls" to some SELinux folks).  This should allow SELinux (and other
LSMs) to provide packet level access control to all IP traffic entering and
leaving the system.  The two other big changes, the shift from skb->dev to
skb->iif and the SELinux network node caching mechanism, are in support of
these new controls although other aspects of the SELinux code benefit as
well (check out the patches).

Comments are always welcome and people willing to help test are even more
welcome.  I'll get some SELinux policy patches out next week to help enable
the new functionality and if everything is still looking okay I'll ping Andew
Morton to see if I can get the latest version of these patches included in the
-mm tree (previous versions are already included).

Thanks.

-- 
paul moore
linux security @ hp

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v8 06/18] LSM: Add inet_sys_snd_skb() LSM hook

2007-12-14 Thread Paul Moore
Add an inet_sys_snd_skb() LSM hook to allow the LSM to provide packet level
access control for all outbound packets.  Using the existing postroute_last
netfilter hook turns out to be problematic as it is can be invoked multiple
times for a single packet, e.g. individual IPsec transforms, adding unwanted
overhead and complicating the security policy.
---

 include/linux/security.h |   11 +++
 net/ipv4/ip_output.c |7 +++
 net/ipv6/ip6_output.c|5 +
 security/dummy.c |8 +++-
 security/security.c  |6 ++
 5 files changed, 36 insertions(+), 1 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index db19c92..1b8d332 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -876,6 +876,10 @@ struct request_sock;
  * Sets the connection's peersid to the secmark on skb.
  * @req_classify_flow:
  * Sets the flow's sid to the openreq sid.
+ * @inet_sys_snd_skb:
+ * Check permissions on outgoing network packets.
+ * @skb is the packet to check
+ * @family is the packet's address family
  *
  * Security hooks for XFRM operations.
  *
@@ -1416,6 +1420,7 @@ struct security_operations {
void (*inet_csk_clone)(struct sock *newsk, const struct request_sock 
*req);
void (*inet_conn_established)(struct sock *sk, struct sk_buff *skb);
void (*req_classify_flow)(const struct request_sock *req, struct flowi 
*fl);
+   int (*inet_sys_snd_skb)(struct sk_buff *skb, int family);
 #endif /* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -2328,6 +2333,7 @@ void security_sk_free(struct sock *sk);
 void security_sk_clone(const struct sock *sk, struct sock *newsk);
 void security_sk_classify_flow(struct sock *sk, struct flowi *fl);
 void security_req_classify_flow(const struct request_sock *req, struct flowi 
*fl);
+int security_inet_sys_snd_skb(struct sk_buff *skb, int family);
 void security_sock_graft(struct sock*sk, struct socket *parent);
 int security_inet_conn_request(struct sock *sk,
struct sk_buff *skb, struct request_sock *req);
@@ -2471,6 +2477,11 @@ static inline void security_req_classify_flow(const 
struct request_sock *req, st
 {
 }
 
+static inline int security_inet_sys_snd_skb(struct sk_buff *skb, int family)
+{
+   return 0;
+}
+
 static inline void security_sock_graft(struct sock* sk, struct socket *parent)
 {
 }
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index fd99fbd..82a7297 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -204,6 +204,8 @@ static inline int ip_skb_dst_mtu(struct sk_buff *skb)
 
 static int ip_finish_output(struct sk_buff *skb)
 {
+   int err;
+
 #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
/* Policy lookup after SNAT yielded a new policy */
if (skb->dst->xfrm != NULL) {
@@ -211,6 +213,11 @@ static int ip_finish_output(struct sk_buff *skb)
return dst_output(skb);
}
 #endif
+
+   err = security_inet_sys_snd_skb(skb, AF_INET);
+   if (err)
+   return err;
+
if (skb->len > ip_skb_dst_mtu(skb) && !skb_is_gso(skb))
return ip_fragment(skb, ip_finish_output2);
else
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 6338a9c..44ddf32 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -72,8 +72,13 @@ static __inline__ void ipv6_select_ident(struct sk_buff 
*skb, struct frag_hdr *f
 
 static int ip6_output_finish(struct sk_buff *skb)
 {
+   int err;
struct dst_entry *dst = skb->dst;
 
+   err = security_inet_sys_snd_skb(skb, AF_INET6);
+   if (err)
+   return err;
+
if (dst->hh)
return neigh_hh_output(dst->hh, skb);
else if (dst->neighbour)
diff --git a/security/dummy.c b/security/dummy.c
index 0b62f95..384979a 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -848,6 +848,11 @@ static inline void dummy_req_classify_flow(const struct 
request_sock *req,
struct flowi *fl)
 {
 }
+
+static inline int dummy_inet_sys_snd_skb(struct sk_buff *skb, int family)
+{
+   return 0;
+}
 #endif /* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -1122,7 +1127,8 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, inet_csk_clone);
set_to_dummy_if_null(ops, inet_conn_established);
set_to_dummy_if_null(ops, req_classify_flow);
- #endif/* CONFIG_SECURITY_NETWORK */
+   set_to_dummy_if_null(ops, inet_sys_snd_skb);
+#endif /* CONFIG_SECURITY_NETWORK */
 #ifdef  CONFIG_SECURITY_NETWORK_XFRM
set_to_dummy_if_null(ops, xfrm_policy_alloc_security);
set_to_dummy_if_null(ops, xfrm_policy_clone_security);
diff --git a/security/security.c b/security/security.c
index 3bdcada..7f55459 100644
--- a/security/security.c
+++ b/security/security.c
@@ -961,6 +961,12 @@ void security_req_classify_

[RFC PATCH v8 07/18] NetLabel: Add IP address family information to the netlbl_skbuff_getattr() function

2007-12-14 Thread Paul Moore
In order to do any sort of IP header inspection of incoming packets we need to
know which address family, AF_INET/AF_INET6/etc., it belongs to and since the
sk_buff structure does not store this information we need to pass along the
address family separate from the packet itself.
---

 include/net/netlabel.h  |2 ++
 net/netlabel/netlabel_kapi.c|2 ++
 security/selinux/hooks.c|   24 ++--
 security/selinux/include/netlabel.h |8 +++-
 security/selinux/netlabel.c |   12 +---
 5 files changed, 38 insertions(+), 10 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 18b73cf..a3bffb4 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -363,6 +363,7 @@ int netlbl_sock_setattr(struct sock *sk,
 int netlbl_sock_getattr(struct sock *sk,
struct netlbl_lsm_secattr *secattr);
 int netlbl_skbuff_getattr(const struct sk_buff *skb,
+ u16 family,
  struct netlbl_lsm_secattr *secattr);
 void netlbl_skbuff_err(struct sk_buff *skb, int error);
 
@@ -415,6 +416,7 @@ static inline int netlbl_sock_getattr(struct sock *sk,
return -ENOSYS;
 }
 static inline int netlbl_skbuff_getattr(const struct sk_buff *skb,
+   u16 family,
struct netlbl_lsm_secattr *secattr)
 {
return -ENOSYS;
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index d3762ea..4914615 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -332,6 +332,7 @@ int netlbl_sock_getattr(struct sock *sk, struct 
netlbl_lsm_secattr *secattr)
 /**
  * netlbl_skbuff_getattr - Determine the security attributes of a packet
  * @skb: the packet
+ * @family: protocol family
  * @secattr: the security attributes
  *
  * Description:
@@ -342,6 +343,7 @@ int netlbl_sock_getattr(struct sock *sk, struct 
netlbl_lsm_secattr *secattr)
  *
  */
 int netlbl_skbuff_getattr(const struct sk_buff *skb,
+ u16 family,
  struct netlbl_lsm_secattr *secattr)
 {
if (CIPSO_V4_OPTEXIST(skb) &&
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8bb673b..2188b9c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3192,6 +3192,7 @@ static int selinux_parse_skb(struct sk_buff *skb, struct 
avc_audit_data *ad,
 /**
  * selinux_skb_extlbl_sid - Determine the external label of a packet
  * @skb: the packet
+ * @family: protocol family
  * @sid: the packet's SID
  *
  * Description:
@@ -3204,13 +3205,16 @@ static int selinux_parse_skb(struct sk_buff *skb, 
struct avc_audit_data *ad,
  * selinux_netlbl_skbuff_getsid().
  *
  */
-static void selinux_skb_extlbl_sid(struct sk_buff *skb, u32 *sid)
+static void selinux_skb_extlbl_sid(struct sk_buff *skb,
+  u16 family,
+  u32 *sid)
 {
u32 xfrm_sid;
u32 nlbl_sid;
 
selinux_skb_xfrm_sid(skb, &xfrm_sid);
if (selinux_netlbl_skbuff_getsid(skb,
+family,
 (xfrm_sid == SECSID_NULL ?
  SECINITSID_NETMSG : xfrm_sid),
 &nlbl_sid) != 0)
@@ -3703,7 +3707,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, 
struct sk_buff *skb)
if (err)
goto out;
 
-   err = selinux_netlbl_sock_rcv_skb(sksec, skb, &ad);
+   err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
if (err)
goto out;
 
@@ -3760,11 +3764,19 @@ static int selinux_socket_getpeersec_dgram(struct 
socket *sock, struct sk_buff *
 {
u32 peer_secid = SECSID_NULL;
int err = 0;
+   u16 family;
+
+   if (sock)
+   family = sock->sk->sk_family;
+   else if (skb->sk)
+   family = skb->sk->sk_family;
+   else
+   family = PF_UNSPEC;
 
-   if (sock && sock->sk->sk_family == PF_UNIX)
+   if (sock && family == PF_UNIX)
selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
else if (skb)
-   selinux_skb_extlbl_sid(skb, &peer_secid);
+   selinux_skb_extlbl_sid(skb, family, &peer_secid);
 
if (peer_secid == SECSID_NULL)
err = -EINVAL;
@@ -3825,7 +3837,7 @@ static int selinux_inet_conn_request(struct sock *sk, 
struct sk_buff *skb,
u32 newsid;
u32 peersid;
 
-   selinux_skb_extlbl_sid(skb, &peersid);
+   selinux_skb_extlbl_sid(skb, sk->sk_family, &peersid);
if (peersid == SECSID_NULL) {
req->secid = sksec->sid;
req->peer_secid = SECSID_NULL;
@@ -3863,7 +3875,7 @@ static void selinux_inet_conn_established(struct sock *sk,
 {
struct sk_security_struct *sksec = sk->sk_security;

[RFC PATCH v8 14/18] SELinux: Enable dynamic enable/disable of the network access checks

2007-12-14 Thread Paul Moore
This patch introduces a mechanism for checking when labeled IPsec or SECMARK
are in use by keeping introducing a configuration reference counter for each
subsystem.  In the case of labeled IPsec, whenever a labeled SA or SPD entry
is created the labeled IPsec/XFRM reference count is increased and when the
entry is removed it is decreased.  In the case of SECMARK, when a SECMARK
target is created the reference count is increased and later decreased when the
target is removed.  These reference counters allow SELinux to quickly determine
if either of these subsystems are enabled.

NetLabel already has a similar mechanism which provides the netlbl_enabled()
function.

This patch also renames the selinux_relabel_packet_permission() function to
selinux_secmark_relabel_packet_permission() as the original name and
description were misleading in that they referenced a single packet label which
is not the case.
---

 include/linux/selinux.h |   45 +++---
 net/netfilter/xt_SECMARK.c  |   13 ++-
 security/selinux/exports.c  |   20 +++--
 security/selinux/hooks.c|   46 +++
 security/selinux/include/xfrm.h |   12 ++
 security/selinux/xfrm.c |   18 ++-
 6 files changed, 132 insertions(+), 22 deletions(-)

diff --git a/include/linux/selinux.h b/include/linux/selinux.h
index 6080f73..8c2cc4c 100644
--- a/include/linux/selinux.h
+++ b/include/linux/selinux.h
@@ -120,16 +120,35 @@ void selinux_get_task_sid(struct task_struct *tsk, u32 
*sid);
 int selinux_string_to_sid(char *str, u32 *sid);
 
 /**
- * selinux_relabel_packet_permission - check permission to relabel a packet
- * @sid: ID value to be applied to network packet (via SECMARK, most 
likely)
+ * selinux_secmark_relabel_packet_permission - secmark permission check
+ * @sid: SECMARK ID value to be applied to network packet
  *
- * Returns 0 if the current task is allowed to label packets with the
- * supplied security ID.  Note that it is implicit that the packet is 
always
- * being relabeled from the default unlabled value, and that the access
- * control decision is made in the AVC.
+ * Returns 0 if the current task is allowed to set the SECMARK label of
+ * packets with the supplied security ID.  Note that it is implicit that
+ * the packet is always being relabeled from the default unlabeled value,
+ * and that the access control decision is made in the AVC.
  */
-int selinux_relabel_packet_permission(u32 sid);
+int selinux_secmark_relabel_packet_permission(u32 sid);
 
+/**
+ * selinux_secmark_refcount_inc - increments the secmark use counter
+ *
+ * SELinux keeps track of the current SECMARK targets in use so it knows
+ * when to apply SECMARK label access checks to network packets.  This
+ * function incements this reference count to indicate that a new SECMARK
+ * target has been configured.
+ */
+void selinux_secmark_refcount_inc(void);
+
+/**
+ * selinux_secmark_refcount_dec - decrements the secmark use counter
+ *
+ * SELinux keeps track of the current SECMARK targets in use so it knows
+ * when to apply SECMARK label access checks to network packets.  This
+ * function decements this reference count to indicate that one of the
+ * existing SECMARK targets has been removed/flushed.
+ */
+void selinux_secmark_refcount_dec(void);
 #else
 
 static inline int selinux_audit_rule_init(u32 field, u32 op,
@@ -184,11 +203,21 @@ static inline int selinux_string_to_sid(const char *str, 
u32 *sid)
return 0;
 }
 
-static inline int selinux_relabel_packet_permission(u32 sid)
+static inline int selinux_secmark_relabel_packet_permission(u32 sid)
 {
return 0;
 }
 
+static inline void selinux_secmark_refcount_inc(void)
+{
+   return;
+}
+
+static inline void selinux_secmark_refcount_dec(void)
+{
+   return;
+}
+
 #endif /* CONFIG_SECURITY_SELINUX */
 
 #endif /* _LINUX_SELINUX_H */
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 235806e..db4a1fe 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -72,12 +72,13 @@ static bool checkentry_selinux(struct 
xt_secmark_target_info *info)
return false;
}
 
-   err = selinux_relabel_packet_permission(sel->selsid);
+   err = selinux_secmark_relabel_packet_permission(sel->selsid);
if (err) {
printk(KERN_INFO PFX "unable to obtain relabeling 
permission\n");
return false;
}
 
+   selinux_secmark_refcount_inc();
return true;
 }
 
@@ -109,11 +110,20 @@ static bool checkentry(const char *tablename, const void 
*entry,
return true;
 }
 
+void destroy(const struct xt_target *target, void *targinfo)
+{
+   switch (mode) {
+   case SECMARK_MODE_SEL:
+   selinux_secmark_refcount_dec();
+   }
+}
+
 static struct xt_target xt_s

Re: [RFC PATCH v8 18/18] SELinux: Add network ingress and egress control permission checks

2007-12-16 Thread Paul Moore
On Friday 14 December 2007 4:51:29 pm Paul Moore wrote:
> This patch implements packet ingress/egress controls for SELinux which
> allow SELinux security policy to control the flow of all IPv4 and IPv6
> packets into and out of the system.  Currently SELinux does not have proper
> control over forwarded packets and this patch corrects this problem.
>
> Special thanks to Venkat Yekkirala <[EMAIL PROTECTED]> whose earlier
> work on this topic eventually led to this patch.

I've been thinking about this over the weekend and realized a few things ...

{snip}

> +static int selinux_inet_sys_snd_skb(struct sk_buff *skb, int family)
> +{
> + int err = 0;
> +
> + if (!selinux_policycap_netpeer)
> + return 0;
> +
> + if (netlbl_enabled() || selinux_xfrm_enabled()) {
> + u32 if_sid;
> + u32 node_sid;
> + u32 peer_sid;
> + char *addrp;
> + struct avc_audit_data ad;
> +
> + AVC_AUDIT_DATA_INIT(&ad, NET);
> + ad.u.net.netif = skb->iif;
> + ad.u.net.family = family;
> + err = selinux_parse_skb(skb, &ad, &addrp, 0, NULL);
> + if (err)
> + return err;
> +
> + err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
> + if (err)
> + return err;

I realized I made a mistake here: we should check to see if the skb has a 
socket associated with it and if it does get the peer_sid from there instead.  
If there is no socket to be found then do what we are already going above.

> + err = sel_netif_sid(skb->iif, &if_sid);
> + if (err)
> + return err;
> + err = avc_has_perm(if_sid, peer_sid,
> +SECCLASS_PEER, PEER__EGRESS, &ad);
> + if (err)
> + return err;
> +
> + err = sel_netnode_sid(addrp, family, &node_sid);
> + if (err)
> + return err;
> + err = avc_has_perm(node_sid, peer_sid,
> +SECCLASS_PEER, PEER__EGRESS, &ad);

We should probably have different permissions for the interface and node 
cases.  Take the example of an admin who is only interested in enforcing 
interface controls and not node controls.  They would most likely write the 
following policy rule to nullify the node check ...

 allow unlabeled_t peer_t:peer egress;

... which would end up applying to both the interface and node checks because 
they use the same permission.  I'm thinking we should split the permissions 
like this:

 allow netif_t peer_t:peer if_egress;
 allow netnode_t peer_t: peer node_egress;

... and do something similar for the ingress side.  Thoughts?

> + }
> +
> + return err;
> +}

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v8 06/18] LSM: Add inet_sys_snd_skb() LSM hook

2007-12-17 Thread Paul Moore
On Monday 17 December 2007 2:45:50 pm Stephen Smalley wrote:
> On Fri, 2007-12-14 at 16:50 -0500, Paul Moore wrote:
> > Add an inet_sys_snd_skb() LSM hook to allow the LSM to provide packet
> > level access control for all outbound packets.  Using the existing
> > postroute_last netfilter hook turns out to be problematic as it is can be
> > invoked multiple times for a single packet, e.g. individual IPsec
> > transforms, adding unwanted overhead and complicating the security
> > policy.
>
> None of the netfilter hooks works for this purpose?

None that we have found, no.  Although if you can prove me wrong I'd be very 
happy.  The problem is that the existing netfilter hooks can get hit multiple 
times in the case of labeled IPsec which was decided to be a no-no.

> Obviously this one needs to get seen on netdev.

Yep.  I just wanted to make sure we were all in agreement on what we 
wanted/needed before I tried to make our case to the netdev folks.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v8 09/18] SELinux: Only store the network interface's ifindex

2007-12-17 Thread Paul Moore
On Monday 17 December 2007 2:56:41 pm Stephen Smalley wrote:
> On Fri, 2007-12-14 at 16:50 -0500, Paul Moore wrote:
> >  /* Initialize an AVC audit data structure. */
> >  #define AVC_AUDIT_DATA_INIT(_d,_t) \
> > -{ memset((_d), 0, sizeof(struct avc_audit_data)); (_d)->type =
> > AVC_AUDIT_DATA_##_t; }
> > +{ memset((_d), 0, sizeof(struct 
> > avc_audit_data)); \
> > + (_d)->type = AVC_AUDIT_DATA_##_t; \
> > + if ((_d)->type == AVC_AUDIT_DATA_NET) \
> > + (_d)->u.net.netif = -1; }
>
> As a minor nit, at the same time you do this, turn this into a static
> inline function please.

Can do ... although when talking about this with some other people I'm not 
sure I need to use -1 as a sentinel value, zero should work.  If that is the 
case I won't need to change this definition.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v8 10/18] SELinux: Add a network node caching mechanism similar to the sel_netif_*() functions

2007-12-17 Thread Paul Moore
On Monday 17 December 2007 3:35:28 pm Stephen Smalley wrote:
> On Fri, 2007-12-14 at 16:50 -0500, Paul Moore wrote:
> > This patch adds a SELinux IP address/node SID caching mechanism similar
> > to the sel_netif_*() functions.  The node SID queries in the SELinux
> > hooks files are also modified to take advantage of this new
> > functionality.  In addition, remove the address length information from
> > the sk_buff parsing routines as it is redundant since we already have the
> > address family.
>
> This is very nice - we also need the same kind of cache for port SIDs.

Thanks.  Any problem if we wait until 2.6.26 for a port SID cache?  It 
shouldn't be any worse than it is now (the new code is not concerned with 
ports) and the current patchset is already large enough that it keeps me up 
at night thinking about all the places it could go wrong ...

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v8 18/18] SELinux: Add network ingress and egress control permission checks

2007-12-17 Thread Paul Moore
On Monday 17 December 2007 3:05:37 pm Stephen Smalley wrote:
> On Sun, 2007-12-16 at 11:47 -0500, Paul Moore wrote:
> > On Friday 14 December 2007 4:51:29 pm Paul Moore wrote:
> > > This patch implements packet ingress/egress controls for SELinux which
> > > allow SELinux security policy to control the flow of all IPv4 and IPv6
> > > packets into and out of the system.  Currently SELinux does not have
> > > proper control over forwarded packets and this patch corrects this
> > > problem.
> > >
> > > Special thanks to Venkat Yekkirala <[EMAIL PROTECTED]> whose
> > > earlier work on this topic eventually led to this patch.
> >
> > I've been thinking about this over the weekend and realized a few things
> > ...
> >
> > {snip}
> >
> > > +static int selinux_inet_sys_snd_skb(struct sk_buff *skb, int family)
> > > +{
> > > + int err = 0;
> > > +
> > > + if (!selinux_policycap_netpeer)
> > > + return 0;
> > > +
> > > + if (netlbl_enabled() || selinux_xfrm_enabled()) {
> > > + u32 if_sid;
> > > + u32 node_sid;
> > > + u32 peer_sid;
> > > + char *addrp;
> > > + struct avc_audit_data ad;
> > > +
> > > + AVC_AUDIT_DATA_INIT(&ad, NET);
> > > + ad.u.net.netif = skb->iif;
> > > + ad.u.net.family = family;
> > > + err = selinux_parse_skb(skb, &ad, &addrp, 0, NULL);
> > > + if (err)
> > > + return err;
> > > +
> > > + err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
> > > + if (err)
> > > + return err;
> >
> > I realized I made a mistake here: we should check to see if the skb has a
> > socket associated with it and if it does get the peer_sid from there
> > instead. If there is no socket to be found then do what we are already
> > going above.
>
> In what case do you expect the two SIDs to diverge?

The case of CIPSO immediately springs to mind.  If you query the packet 
directly you will get a SID similar to what you see on incoming packets: 
the "netlabel_peer_t" type plus the CIPSO MLS sensitivity label.  If you 
query the socket which originated the packet you'll get the original, native 
SELinux label/SID.  In my mind using the socket's label is a shortcut to get 
the full/true/original/etc. label quickly.

There is most likely also a performance advantage in pulling the SID from the 
socket.

> What if we later provide an API to allow a sender to send a datagram
> with a particular label rather than always requiring them to be the same
> as the sending socket?

Then we can transition from using a mix between socket and packet labels to 
just packet labels.  I don't see any _significant_ barriers to that approach 
in the ingress/egress controls as proposed.  If you do, let me know.

> > > + err = sel_netif_sid(skb->iif, &if_sid);
> > > + if (err)
> > > + return err;
> > > + err = avc_has_perm(if_sid, peer_sid,
> > > +SECCLASS_PEER, PEER__EGRESS, &ad);
> > > + if (err)
> > > + return err;
> > > +
> > > + err = sel_netnode_sid(addrp, family, &node_sid);
> > > + if (err)
> > > + return err;
> > > + err = avc_has_perm(node_sid, peer_sid,
> > > +SECCLASS_PEER, PEER__EGRESS, &ad);
> >
> > We should probably have different permissions for the interface and node
> > cases.  Take the example of an admin who is only interested in enforcing
> > interface controls and not node controls.  They would most likely write
> > the following policy rule to nullify the node check ...
> >
> >  allow unlabeled_t peer_t:peer egress;
> >
> > ... which would end up applying to both the interface and node checks
> > because they use the same permission.  I'm thinking we should split the
> > permissions like this:
> >
> >  allow netif_t peer_t:peer if_egress;
> >  allow netnode_t peer_t: peer node_egress;
> >
> > ... and do something similar for the ingress side.  Thoughts?
>
> That starts to sound a lot like using netif and node classes instead of
> the peer class.
>   allow peer_t netif_t:netif egress;
>   allow peer_t netnode_t:node egress;

I see you noticed that too :)

I've been mulling this over and over in my head for some time and I'm not sure 
which is better.  I'm leaning towards sticking with the peer object class 
just because it reinforces the decision to treat the packet as an object.  
Good or bad, that is how SELinux currently treats packets and I fear that 
using the packet's peer label as the subject here could get confusing.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v8 10/18] SELinux: Add a network node caching mechanism similar to the sel_netif_*() functions

2007-12-18 Thread Paul Moore
On Tuesday 18 December 2007 8:26:35 am Stephen Smalley wrote:
> On Mon, 2007-12-17 at 15:56 -0500, Paul Moore wrote:
> > On Monday 17 December 2007 3:35:28 pm Stephen Smalley wrote:
> > > On Fri, 2007-12-14 at 16:50 -0500, Paul Moore wrote:
> > > > This patch adds a SELinux IP address/node SID caching mechanism
> > > > similar to the sel_netif_*() functions.  The node SID queries in the
> > > > SELinux hooks files are also modified to take advantage of this new
> > > > functionality.  In addition, remove the address length information
> > > > from the sk_buff parsing routines as it is redundant since we already
> > > > have the address family.
> > >
> > > This is very nice - we also need the same kind of cache for port SIDs.
> >
> > Thanks.  Any problem if we wait until 2.6.26 for a port SID cache?  It
> > shouldn't be any worse than it is now (the new code is not concerned with
> > ports) and the current patchset is already large enough that it keeps me
> > up at night thinking about all the places it could go wrong ...
>
> Yes, that's fine - just a note to file away for the future.  We'll still
> want the cache eventually though since the name_bind and name_connect
> checks are based on the port SIDs and will remain even when the compat
> checks are obsoleted.

All righty, since neither you or James are in a hurry for this I'll "file it 
away" for 2.6.26.

Thanks.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v8 05/18] LSM: Add secctx_to_secid() LSM hook

2007-12-18 Thread Paul Moore
On Tuesday 18 December 2007 3:25:54 am James Morris wrote:
> On Fri, 14 Dec 2007, Paul Moore wrote:
> > Add a secctx_to_secid() LSM hook to go along with the existing
> > secid_to_secctx() LSM hook.  This patch also includes the SELinux
> > implementation for this hook.
>
> Please sign off your patches (especially this one asap, so I can push it
> upstream).

The lack of a sign-off line is actually intentional at this point as I wanted 
to make sure they didn't go anywhere before they were ready.  For instance, 
I've got the changes that were pointed out yesterday on-list as well as a 
handful of IPv6 changes from some IPv6 folks here at HP.

Most of the new peer object class code paths haven't even been tested yet.  I 
realize we can still get fixes/corrections in after -rc1 but I'd like to try 
and minimize that if I can.

I've been operating under the assumption that I've most likely got until the 
end of next week before I need to post "final-ish" version of the patches, 
complete with a signed-off line.  If that isn't the case and you need these 
bits sooner (or now) please let me know.

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v8 18/18] SELinux: Add network ingress and egress control permission checks

2007-12-18 Thread Paul Moore
On Monday 17 December 2007 3:05:37 pm Stephen Smalley wrote:
> On Sun, 2007-12-16 at 11:47 -0500, Paul Moore wrote:
> > We should probably have different permissions for the interface and node
> > cases.  Take the example of an admin who is only interested in enforcing
> > interface controls and not node controls.  They would most likely write
> > the following policy rule to nullify the node check ...
> >
> >  allow unlabeled_t peer_t:peer egress;
> >
> > ... which would end up applying to both the interface and node checks
> > because they use the same permission.  I'm thinking we should split the
> > permissions like this:
> >
> >  allow netif_t peer_t:peer if_egress;
> >  allow netnode_t peer_t: peer node_egress;
> >
> > ... and do something similar for the ingress side.  Thoughts?
>
> That starts to sound a lot like using netif and node classes instead of
> the peer class.
>   allow peer_t netif_t:netif egress;
>   allow peer_t netnode_t:node egress;

Thinking about this some more ... egress/ingress make sense from an interface 
point of view but they sound out of place from a node point of view.  After 
all, you are not "egressing" to a node, to are "sending to" a node.  The same 
thing applies in the opposite direction, you don't "ingress" from a node, 
you "receive from" a node.  With that in mind I'm thinking of going with the 
following:

 allow netif_t peer_t:peer { ingress egress };
 allow netnode_t peer_t:peer { recv_from send_to };

Thoughts?  Should I just forget all this and use the peer label as a subject 
label?

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC PATCH v8 18/18] SELinux: Add network ingress and egress control permission checks

2007-12-18 Thread Paul Moore
On Tuesday 18 December 2007 10:14:41 am Stephen Smalley wrote:
> On Tue, 2007-12-18 at 08:59 -0500, Paul Moore wrote:
> > Thoughts?  Should I just forget all this and use the peer label as a
> > subject label?
>
> I'm not certain what we gain by using the peer as the object and class
> in these checks, and it seems to make their meaning less clear.  It
> should be noted that we already use process labels as both subjects
> (when the actor) and objects (when the target/recipient of an action, as
> in signal delivery or IPC), and that process labels "flow" to sockets
> they create and socket labels "flow" to packets they send, and socket
> labels likewise serve dual roles as subjects (Can this socket send/recv
> this packet?) and objects (Can this process send/recv on this socket?).
>
> In the case of locally generated or destined traffic, we always have a
> local socket that we can use as the subject of the check, which I think
> is why we end up not using packet/peer as the subject generally - we
> essentially have two subjects to choose from, and we favor the local
> one.  But in the forwarded case, the packet/peer is the only
> subject/actor in view really.

Yep, I think you are right and I'm just slow to realize it.  As pointed out 
earlier in the discussion, the awkwardness of using the packet's peer label 
as an object should have clued me into the fact that this was a bad idea.

So, my last question is what permissions do we want to use for the netif/node 
object classes?

 allow peer_t netif_t:netif { egress ingress };
 allow peer_t netnode_t:node { sendto/send recvfrom/recv };

What I'd like to avoid if possible is the protocol specific permissions we 
currently have for the netif and node object classes; it requires extra work 
in the kernel, it doesn't work at all for the forwarding case, and I have my 
doubts about the usefulness of the distinction.  I think the ingress/egress 
permissions still make sense when applied to the netif object class but it's 
a bit of a stretch when applied to the node object class.  I personally like 
the sendto/recvfrom permissions but if that is too much of a violation from 
existing precedence I imagine send/recv would work.

Thoughts?

-- 
paul moore
linux security @ hp
-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v9 13/18] SELinux: Better integration between peer labeling subsystems

2007-12-21 Thread Paul Moore
Rework the handling of network peer labels so that the different peer labeling
subsystems work better together.  This includes moving both subsystems to a
single "peer" object class which involves not only changes to the permission
checks but an improved method of consolidating multiple packet peer labels.
As part of this work the inbound packet permission check code has been heavily
modified to handle both the old and new behavior in as sane a fashion as
possible.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 security/selinux/hooks.c|  204 +++
 security/selinux/include/netlabel.h |3 +
 security/selinux/include/objsec.h   |2 
 security/selinux/include/security.h |4 +
 security/selinux/netlabel.c |   10 +-
 security/selinux/ss/services.c  |   85 +++
 6 files changed, 208 insertions(+), 100 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 4250642..c156f6c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -50,6 +50,7 @@
 #include 
 #include /* for local_port_range[] */
 #include/* struct or_callable used in sock_rcv_skb */
+#include 
 #include 
 #include 
 #include 
@@ -3189,36 +3190,39 @@ static int selinux_parse_skb(struct sk_buff *skb, 
struct avc_audit_data *ad,
 }
 
 /**
- * selinux_skb_extlbl_sid - Determine the external label of a packet
+ * selinux_skb_peerlbl_sid - Determine the peer label of a packet
  * @skb: the packet
  * @family: protocol family
- * @sid: the packet's SID
+ * @sid: the packet's peer label SID
  *
  * Description:
- * Check the various different forms of external packet labeling and determine
- * the external SID for the packet.  If only one form of external labeling is
- * present then it is used, if both labeled IPsec and NetLabel labels are
- * present then the SELinux type information is taken from the labeled IPsec
- * SA and the MLS sensitivity label information is taken from the NetLabel
- * security attributes.  This bit of "magic" is done in the call to
- * selinux_netlbl_skbuff_getsid().
+ * Check the various different forms of network peer labeling and determine
+ * the peer label/SID for the packet; most of the magic actually occurs in
+ * the security server function security_net_peersid_cmp().  The function
+ * returns zero if the value in @sid is valid (although it may be SECSID_NULL)
+ * or -EACCES if @sid is invalid due to inconsistencies with the different
+ * peer labels.
  *
  */
-static void selinux_skb_extlbl_sid(struct sk_buff *skb,
-  u16 family,
-  u32 *sid)
+static int selinux_skb_peerlbl_sid(struct sk_buff *skb, u16 family, u32 *sid)
 {
u32 xfrm_sid;
u32 nlbl_sid;
+   u32 nlbl_type;
 
selinux_skb_xfrm_sid(skb, &xfrm_sid);
-   if (selinux_netlbl_skbuff_getsid(skb,
-family,
-(xfrm_sid == SECSID_NULL ?
- SECINITSID_NETMSG : xfrm_sid),
-&nlbl_sid) != 0)
-   nlbl_sid = SECSID_NULL;
-   *sid = (nlbl_sid == SECSID_NULL ? xfrm_sid : nlbl_sid);
+   selinux_netlbl_skbuff_getsid(skb,
+family,
+SECINITSID_NETMSG,
+&nlbl_type,
+&nlbl_sid);
+
+   if (security_net_peersid_resolve(nlbl_sid, nlbl_type,
+xfrm_sid,
+sid) != 0)
+   return -EACCES;
+
+   return 0;
 }
 
 /* socket security operations */
@@ -3284,6 +3288,7 @@ static int selinux_socket_post_create(struct socket 
*sock, int family,
if (sock->sk) {
sksec = sock->sk->sk_security;
sksec->sid = isec->sid;
+   sksec->sclass = isec->sclass;
err = selinux_netlbl_socket_post_create(sock);
}
 
@@ -3587,104 +3592,114 @@ static int selinux_socket_unix_may_send(struct socket 
*sock,
return 0;
 }
 
-static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
-  struct avc_audit_data *ad,
-  u16 family, char *addrp)
+static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk,
+   struct sk_buff *skb,
+   struct avc_audit_data *ad,
+   u16 family,
+   char *addrp)
 {
-   int err = 0;
-   u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0;
-   struct socket *sock;
-   u16 sock_class = 0;
-   u32 sock_

[RFC PATCH v9 10/18] SELinux: Add a network node caching mechanism similar to the sel_netif_*() functions

2007-12-21 Thread Paul Moore
This patch adds a SELinux IP address/node SID caching mechanism similar to the
sel_netif_*() functions.  The node SID queries in the SELinux hooks files are
also modified to take advantage of this new functionality.  In addition, remove
the address length information from the sk_buff parsing routines as it is
redundant since we already have the address family.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 security/selinux/Makefile  |9 +
 security/selinux/hooks.c   |   33 ++-
 security/selinux/include/netnode.h |   32 +++
 security/selinux/include/objsec.h  |9 +
 security/selinux/netnode.c |  350 
 5 files changed, 416 insertions(+), 17 deletions(-)

diff --git a/security/selinux/Makefile b/security/selinux/Makefile
index dc3502e..00afd85 100644
--- a/security/selinux/Makefile
+++ b/security/selinux/Makefile
@@ -4,7 +4,14 @@
 
 obj-$(CONFIG_SECURITY_SELINUX) := selinux.o ss/
 
-selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o exports.o
+selinux-y := avc.o \
+hooks.o \
+selinuxfs.o \
+netlink.o \
+nlmsgtab.o \
+netif.o \
+netnode.o \
+exports.o
 
 selinux-$(CONFIG_SECURITY_NETWORK_XFRM) += xfrm.o
 
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b451b4c..4250642 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -76,6 +76,7 @@
 #include "avc.h"
 #include "objsec.h"
 #include "netif.h"
+#include "netnode.h"
 #include "xfrm.h"
 #include "netlabel.h"
 
@@ -3158,7 +3159,7 @@ out:
 #endif /* IPV6 */
 
 static int selinux_parse_skb(struct sk_buff *skb, struct avc_audit_data *ad,
-char **addrp, int *len, int src, u8 *proto)
+char **addrp, int src, u8 *proto)
 {
int ret = 0;
 
@@ -3167,7 +3168,6 @@ static int selinux_parse_skb(struct sk_buff *skb, struct 
avc_audit_data *ad,
ret = selinux_parse_skb_ipv4(skb, ad, proto);
if (ret || !addrp)
break;
-   *len = 4;
*addrp = (char *)(src ? &ad->u.net.v4info.saddr :
&ad->u.net.v4info.daddr);
break;
@@ -3177,7 +3177,6 @@ static int selinux_parse_skb(struct sk_buff *skb, struct 
avc_audit_data *ad,
ret = selinux_parse_skb_ipv6(skb, ad, proto);
if (ret || !addrp)
break;
-   *len = 16;
*addrp = (char *)(src ? &ad->u.net.v6info.saddr :
&ad->u.net.v6info.daddr);
break;
@@ -3377,7 +3376,7 @@ static int selinux_socket_bind(struct socket *sock, 
struct sockaddr *address, in
break;
}

-   err = security_node_sid(family, addrp, addrlen, &sid);
+   err = sel_netnode_sid(addrp, family, &sid);
if (err)
goto out;

@@ -3589,7 +3588,8 @@ static int selinux_socket_unix_may_send(struct socket 
*sock,
 }
 
 static int selinux_sock_rcv_skb_compat(struct sock *sk, struct sk_buff *skb,
-   struct avc_audit_data *ad, u16 family, char *addrp, int len)
+  struct avc_audit_data *ad,
+  u16 family, char *addrp)
 {
int err = 0;
u32 netif_perm, node_perm, node_sid, if_sid, recv_perm = 0;
@@ -3649,7 +3649,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, 
struct sk_buff *skb,
if (err)
goto out;

-   err = security_node_sid(family, addrp, len, &node_sid);
+   err = sel_netnode_sid(addrp, family, &node_sid);
if (err)
goto out;

@@ -3678,7 +3678,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, 
struct sk_buff *skb)
 {
u16 family;
char *addrp;
-   int len, err = 0;
+   int err = 0;
struct avc_audit_data ad;
struct sk_security_struct *sksec = sk->sk_security;
 
@@ -3694,13 +3694,12 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, 
struct sk_buff *skb)
ad.u.net.netif = skb->iif;
ad.u.net.family = family;
 
-   err = selinux_parse_skb(skb, &ad, &addrp, &len, 1, NULL);
+   err = selinux_parse_skb(skb, &ad, &addrp, 1, NULL);
if (err)
goto out;
 
if (selinux_compat_net)
-   err = selinux_sock_rcv_skb_compat(sk, skb, &ad, family,
- addrp, len);
+   err = selinux_sock_rcv_skb_compat(sk, skb, &ad, family, addrp);
else
err = avc_has_perm(sksec->sid, skb->secmark, SECCLASS_PACKET,
  

[RFC PATCH v9 18/18] SELinux: Add network ingress and egress control permission checks

2007-12-21 Thread Paul Moore
This patch implements packet ingress/egress controls for SELinux which allow
SELinux security policy to control the flow of all IPv4 and IPv6 packets into
and out of the system.  Currently SELinux does not have proper control over
forwarded packets and this patch corrects this problem.

Special thanks to Venkat Yekkirala <[EMAIL PROTECTED]> whose earlier
work on this topic eventually led to this patch.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 security/selinux/hooks.c |  347 --
 1 files changed, 240 insertions(+), 107 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index d16f586..474ffe8 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -12,8 +12,8 @@
  *  Copyright (C) 2003 Red Hat, Inc., James Morris <[EMAIL PROTECTED]>
  *  Copyright (C) 2004-2005 Trusted Computer Solutions, Inc.
  *  <[EMAIL PROTECTED]>
- *  Copyright (C) 2006 Hewlett-Packard Development Company, L.P.
- *     Paul Moore, <[EMAIL PROTECTED]>
+ *  Copyright (C) 2006, 2007 Hewlett-Packard Development Company, L.P.
+ * Paul Moore <[EMAIL PROTECTED]>
  *  Copyright (C) 2007 Hitachi Software Engineering Co., Ltd.
  * Yuichi Nakamura <[EMAIL PROTECTED]>
  *
@@ -3608,6 +3608,83 @@ static int selinux_socket_unix_may_send(struct socket 
*sock,
return 0;
 }
 
+static int selinux_inet_sys_rcv_skb(int ifindex, char *addrp, u16 family,
+   u32 peer_sid,
+   struct avc_audit_data *ad)
+{
+   int err;
+   u32 if_sid;
+   u32 node_sid;
+
+   err = sel_netif_sid(ifindex, &if_sid);
+   if (err)
+   return err;
+   err = avc_has_perm(peer_sid, if_sid,
+  SECCLASS_NETIF, NETIF__INGRESS, ad);
+   if (err)
+   return err;
+
+   err = sel_netnode_sid(addrp, family, &node_sid);
+   if (err)
+   return err;
+   return avc_has_perm(peer_sid, node_sid,
+   SECCLASS_NODE, NODE__RECVFROM, ad);
+}
+
+static int selinux_inet_sys_snd_skb(struct sk_buff *skb, int family)
+{
+   int err = 0;
+
+   if (!selinux_policycap_netpeer)
+   return 0;
+
+   if (netlbl_enabled() || selinux_xfrm_enabled()) {
+   u32 if_sid;
+   u32 node_sid;
+   u32 peer_sid;
+   int ifindex = skb->dev->ifindex;
+   char *addrp;
+   struct sock *sk = skb->sk;
+   struct avc_audit_data ad;
+
+   AVC_AUDIT_DATA_INIT(&ad, NET);
+   ad.u.net.netif = ifindex;
+   ad.u.net.family = family;
+   err = selinux_parse_skb(skb, &ad, &addrp, 0, NULL);
+   if (err)
+   return err;
+
+   if (sk) {
+   /* packet was locally generated, get the peer label
+* from the originating socket */
+   struct sk_security_struct *sksec = sk->sk_security;
+   peer_sid = sksec->sid;
+   } else {
+   /* packet was generated by another host, get the peer
+* label directly from the packet */
+   err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
+   if (err)
+   return err;
+   }
+
+   err = sel_netif_sid(ifindex, &if_sid);
+   if (err)
+   return err;
+   err = avc_has_perm(peer_sid, if_sid,
+  SECCLASS_NETIF, NETIF__EGRESS, &ad);
+   if (err)
+   return err;
+
+   err = sel_netnode_sid(addrp, family, &node_sid);
+   if (err)
+   return err;
+   err = avc_has_perm(peer_sid, node_sid,
+  SECCLASS_NODE, NODE__SENDTO, &ad);
+   }
+
+   return err;
+}
+
 static int selinux_sock_rcv_skb_iptables_compat(struct sock *sk,
struct sk_buff *skb,
struct avc_audit_data *ad,
@@ -3748,6 +3825,10 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, 
struct sk_buff *skb)
err = selinux_skb_peerlbl_sid(skb, family, &peer_sid);
if (err)
return err;
+   err = selinux_inet_sys_rcv_skb(skb->iif, addrp, family,
+  peer_sid, &ad);
+   if (err)
+   return err;
err = avc_has_perm(sk_sid, peer_sid, SECCLASS_PEER,
   PEER__RECV, &ad);
}
@@ -3964

[RFC PATCH v9 08/18] SELinux: Convert the netif code to use ifindex values

2007-12-21 Thread Paul Moore
The current SELinux netif code requires the caller have a valid net_device
struct pointer to lookup network interface information.  However, we don't
always have a valid net_device pointer so convert the netif code to use
the ifindex values we always have as part of the sk_buff.  This patch also
removes the default message SID from the network interface record, it is
not being used and therefore is "dead code".

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 security/selinux/hooks.c|4 -
 security/selinux/include/netif.h|4 -
 security/selinux/include/objsec.h   |5 -
 security/selinux/include/security.h |3 
 security/selinux/netif.c|  254 ---
 security/selinux/ss/services.c  |   10 -
 6 files changed, 155 insertions(+), 125 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7b99d52..8336c93 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3616,7 +3616,7 @@ static int selinux_sock_rcv_skb_compat(struct sock *sk, 
struct sk_buff *skb,
if (!skb->dev)
goto out;
 
-   err = sel_netif_sids(skb->dev, &if_sid, NULL);
+   err = sel_netif_sid(skb->iif, &if_sid);
if (err)
goto out;
 
@@ -3941,7 +3941,7 @@ static int selinux_ip_postroute_last_compat(struct sock 
*sk, struct net_device *
 
isec = inode->i_security;

-   err = sel_netif_sids(dev, &if_sid, NULL);
+   err = sel_netif_sid(dev->ifindex, &if_sid);
if (err)
goto out;
 
diff --git a/security/selinux/include/netif.h b/security/selinux/include/netif.h
index 8bd6f99..ce23edd 100644
--- a/security/selinux/include/netif.h
+++ b/security/selinux/include/netif.h
@@ -7,6 +7,8 @@
  * Author: James Morris <[EMAIL PROTECTED]>
  *
  * Copyright (C) 2003 Red Hat, Inc., James Morris <[EMAIL PROTECTED]>
+ * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
+ *Paul Moore, <[EMAIL PROTECTED]>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2,
@@ -15,7 +17,7 @@
 #ifndef _SELINUX_NETIF_H_
 #define _SELINUX_NETIF_H_
 
-int sel_netif_sids(struct net_device *dev, u32 *if_sid, u32 *msg_sid);
+int sel_netif_sid(int ifindex, u32 *sid);
 
 #endif /* _SELINUX_NETIF_H_ */
 
diff --git a/security/selinux/include/objsec.h 
b/security/selinux/include/objsec.h
index 642a9fd..e41a2aa 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -95,9 +95,8 @@ struct bprm_security_struct {
 };
 
 struct netif_security_struct {
-   struct net_device *dev; /* back pointer */
-   u32 if_sid; /* SID for this interface */
-   u32 msg_sid;/* default SID for messages received on 
this interface */
+   int ifindex;/* device index */
+   u32 sid;/* SID for this interface */
 };
 
 struct sk_security_struct {
diff --git a/security/selinux/include/security.h 
b/security/selinux/include/security.h
index 39337af..a33437b 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -77,8 +77,7 @@ int security_get_user_sids(u32 callsid, char *username,
 int security_port_sid(u16 domain, u16 type, u8 protocol, u16 port,
u32 *out_sid);
 
-int security_netif_sid(char *name, u32 *if_sid,
-   u32 *msg_sid);
+int security_netif_sid(char *name, u32 *if_sid);
 
 int security_node_sid(u16 domain, void *addr, u32 addrlen,
u32 *out_sid);
diff --git a/security/selinux/netif.c b/security/selinux/netif.c
index e87ab94..ee49a73 100644
--- a/security/selinux/netif.c
+++ b/security/selinux/netif.c
@@ -7,6 +7,8 @@
  * Author: James Morris <[EMAIL PROTECTED]>
  *
  * Copyright (C) 2003 Red Hat, Inc., James Morris <[EMAIL PROTECTED]>
+ * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
+ *Paul Moore <[EMAIL PROTECTED]>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2,
@@ -29,14 +31,6 @@
 #define SEL_NETIF_HASH_SIZE64
 #define SEL_NETIF_HASH_MAX 1024
 
-#undef DEBUG
-
-#ifdef DEBUG
-#define DEBUGP printk
-#else
-#define DEBUGP(format, args...)
-#endif
-
 struct sel_netif
 {
struct list_head list;
@@ -49,174 +43,217 @@ static LIST_HEAD(sel_netif_list);
 static DEFINE_SPINLOCK(sel_netif_lock);
 static struct list_head sel_netif_hash[SEL_NETIF_HASH_SIZE];
 
-static inline u32 sel_netif_hasfn(struct net_device *dev)
+/**
+ * sel_netif_hashfn - Hashing function for the interface table
+ * @ifindex: the network interface
+ *
+ * Description:
+ * This is the hashing function for the network interface table, it returns the
+ * bucket number for the give

[RFC PATCH v9 15/18] SELinux: Allow NetLabel to directly cache SIDs

2007-12-21 Thread Paul Moore
Now that the SELinux NetLabel "base SID" is always the netmsg initial SID we
can do a big optimization - caching the SID and not just the MLS attributes.
This not only saves a lot of per-packet memory allocations and copies but it
has a nice side effect of removing a chunk of code.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 security/selinux/hooks.c|6 --
 security/selinux/include/netlabel.h |2 -
 security/selinux/include/security.h |2 -
 security/selinux/netlabel.c |   55 ++--
 security/selinux/ss/services.c  |  124 ++-
 5 files changed, 55 insertions(+), 134 deletions(-)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 90b0901..d16f586 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3231,11 +3231,7 @@ static int selinux_skb_peerlbl_sid(struct sk_buff *skb, 
u16 family, u32 *sid)
u32 nlbl_type;
 
selinux_skb_xfrm_sid(skb, &xfrm_sid);
-   selinux_netlbl_skbuff_getsid(skb,
-family,
-SECINITSID_NETMSG,
-&nlbl_type,
-&nlbl_sid);
+   selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
 
if (security_net_peersid_resolve(nlbl_sid, nlbl_type,
 xfrm_sid,
diff --git a/security/selinux/include/netlabel.h 
b/security/selinux/include/netlabel.h
index c8c05a6..00a2809 100644
--- a/security/selinux/include/netlabel.h
+++ b/security/selinux/include/netlabel.h
@@ -48,7 +48,6 @@ void selinux_netlbl_sk_security_clone(struct 
sk_security_struct *ssec,
 
 int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
 u16 family,
-u32 base_sid,
 u32 *type,
 u32 *sid);
 
@@ -89,7 +88,6 @@ static inline void selinux_netlbl_sk_security_clone(
 
 static inline int selinux_netlbl_skbuff_getsid(struct sk_buff *skb,
   u16 family,
-  u32 base_sid,
   u32 *type,
   u32 *sid)
 {
diff --git a/security/selinux/include/security.h 
b/security/selinux/include/security.h
index 9347e2d..23137c1 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -124,7 +124,6 @@ int security_genfs_sid(const char *fstype, char *name, u16 
sclass,
 
 #ifdef CONFIG_NETLABEL
 int security_netlbl_secattr_to_sid(struct netlbl_lsm_secattr *secattr,
-  u32 base_sid,
   u32 *sid);
 
 int security_netlbl_sid_to_secattr(u32 sid,
@@ -132,7 +131,6 @@ int security_netlbl_sid_to_secattr(u32 sid,
 #else
 static inline int security_netlbl_secattr_to_sid(
struct netlbl_lsm_secattr *secattr,
-   u32 base_sid,
u32 *sid)
 {
return -EIDRM;
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c
index af78cb9..e07adf9 100644
--- a/security/selinux/netlabel.c
+++ b/security/selinux/netlabel.c
@@ -36,6 +36,33 @@
 #include "security.h"
 
 /**
+ * selinux_netlbl_sidlookup_cached - Cache a SID lookup
+ * @skb: the packet
+ * @secattr: the NetLabel security attributes
+ * @sid: the SID
+ *
+ * Description:
+ * Query the SELinux security server to lookup the correct SID for the given
+ * security attributes.  If the query is successful, cache the result to speed
+ * up future lookups.  Returns zero on success, negative values on failure.
+ *
+ */
+static int selinux_netlbl_sidlookup_cached(struct sk_buff *skb,
+  struct netlbl_lsm_secattr *secattr,
+  u32 *sid)
+{
+   int rc;
+
+   rc = security_netlbl_secattr_to_sid(secattr, sid);
+   if (rc == 0 &&
+   (secattr->flags & NETLBL_SECATTR_CACHEABLE) &&
+   (secattr->flags & NETLBL_SECATTR_CACHE))
+   netlbl_cache_add(skb, secattr);
+
+   return rc;
+}
+
+/**
  * selinux_netlbl_sock_setsid - Label a socket using the NetLabel mechanism
  * @sk: the socket to label
  * @sid: the SID to use
@@ -141,7 +168,6 @@ void selinux_netlbl_sk_security_clone(struct 
sk_security_struct *ssec,
  * selinux_netlbl_skbuff_getsid - Get the sid of a packet using NetLabel
  * @skb: the packet
  * @family: protocol family
- * @base_sid: the SELinux SID to use as a context for MLS only attributes
  * @type: NetLabel labeling protocol type
  * @sid: the SID
  *
@@ -153,7 +179,6 @@ void selinux_netlbl_sk_security_clone(struct 
sk_secur

[RFC PATCH v9 04/18] NetLabel: Add secid token support to the NetLabel secattr struct

2007-12-21 Thread Paul Moore
This patch adds support to the NetLabel LSM secattr struct for a secid token
and a type field, paving the way for full LSM/SELinux context support and
"static" or "fallback" labels.  In addition, this patch adds a fair amount
of documentation to the core NetLabel structures used as part of the
NetLabel kernel API.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 include/net/netlabel.h|   91 ++---
 net/ipv4/cipso_ipv4.c |   59 +++-
 net/netlabel/netlabel_unlabeled.c |1 
 security/selinux/ss/mls.c |   10 ++--
 security/selinux/ss/services.c|5 ++
 5 files changed, 120 insertions(+), 46 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 2e5b2f6..18b73cf 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -105,17 +105,49 @@ struct netlbl_dom_map;
 /* Domain mapping operations */
 int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);
 
-/* LSM security attributes */
+/*
+ * LSM security attributes
+ */
+
+/**
+ * struct netlbl_lsm_cache - NetLabel LSM security attribute cache
+ * @refcount: atomic reference counter
+ * @free: LSM supplied function to free the cache data
+ * @data: LSM supplied cache data
+ *
+ * Description:
+ * This structure is provided for LSMs which wish to make use of the NetLabel
+ * caching mechanism to store LSM specific data/attributes in the NetLabel
+ * cache.  If the LSM has to perform a lot of translation from the NetLabel
+ * security attributes into it's own internal representation then the cache
+ * mechanism can provide a way to eliminate some or all of that translation
+ * overhead on a cache hit.
+ *
+ */
 struct netlbl_lsm_cache {
atomic_t refcount;
void (*free) (const void *data);
void *data;
 };
-/* The catmap bitmap field MUST be a power of two in length and large
+
+/**
+ * struct netlbl_lsm_secattr_catmap - NetLabel LSM secattr category bitmap
+ * @startbit: the value of the lowest order bit in the bitmap
+ * @bitmap: the category bitmap
+ * @next: pointer to the next bitmap "node" or NULL
+ *
+ * Description:
+ * This structure is used to represent category bitmaps.  Due to the large
+ * number of categories supported by most labeling protocols it is not
+ * practical to transfer a full bitmap internally so NetLabel adopts a sparse
+ * bitmap structure modeled after SELinux's ebitmap structure.
+ * The catmap bitmap field MUST be a power of two in length and large
  * enough to hold at least 240 bits.  Special care (i.e. check the code!)
  * should be used when changing these values as the LSM implementation
  * probably has functions which rely on the sizes of these types to speed
- * processing. */
+ * processing.
+ *
+ */
 #define NETLBL_CATMAP_MAPTYPE   u64
 #define NETLBL_CATMAP_MAPCNT4
 #define NETLBL_CATMAP_MAPSIZE   (sizeof(NETLBL_CATMAP_MAPTYPE) * 8)
@@ -127,22 +159,48 @@ struct netlbl_lsm_secattr_catmap {
NETLBL_CATMAP_MAPTYPE bitmap[NETLBL_CATMAP_MAPCNT];
struct netlbl_lsm_secattr_catmap *next;
 };
+
+/**
+ * struct netlbl_lsm_secattr - NetLabel LSM security attributes
+ * @flags: indicate which attributes are contained in this structure
+ * @type: indicate the NLTYPE of the attributes
+ * @domain: the NetLabel LSM domain
+ * @cache: NetLabel LSM specific cache
+ * @attr.mls: MLS sensitivity label
+ * @attr.mls.cat: MLS category bitmap
+ * @attr.mls.lvl: MLS sensitivity level
+ * @attr.secid: LSM specific secid token
+ *
+ * Description:
+ * This structure is used to pass security attributes between NetLabel and the
+ * LSM modules.  The flags field is used to specify which fields within the
+ * struct are valid and valid values can be created by bitwise OR'ing the
+ * NETLBL_SECATTR_* defines.  The domain field is typically set by the LSM to
+ * specify domain specific configuration settings and is not usually used by
+ * NetLabel itself when returning security attributes to the LSM.
+ *
+ */
 #define NETLBL_SECATTR_NONE 0x
 #define NETLBL_SECATTR_DOMAIN   0x0001
 #define NETLBL_SECATTR_CACHE0x0002
 #define NETLBL_SECATTR_MLS_LVL  0x0004
 #define NETLBL_SECATTR_MLS_CAT  0x0008
+#define NETLBL_SECATTR_SECID0x0010
 #define NETLBL_SECATTR_CACHEABLE(NETLBL_SECATTR_MLS_LVL | \
-NETLBL_SECATTR_MLS_CAT)
+NETLBL_SECATTR_MLS_CAT | \
+NETLBL_SECATTR_SECID)
 struct netlbl_lsm_secattr {
u32 flags;
-
+   u32 type;
char *domain;
-
-   u32 mls_lvl;
-   struct netlbl_lsm_secattr_catmap *mls_cat;
-
struct netlbl_lsm_cache *cache;
+   union {
+   struct {
+   struct netlbl_lsm_secattr_catmap *cat;
+  

[RFC PATCH v9 07/18] NetLabel: Add IP address family information to the netlbl_skbuff_getattr() function

2007-12-21 Thread Paul Moore
In order to do any sort of IP header inspection of incoming packets we need to
know which address family, AF_INET/AF_INET6/etc., it belongs to and since the
sk_buff structure does not store this information we need to pass along the
address family separate from the packet itself.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 include/net/netlabel.h  |2 ++
 net/netlabel/netlabel_kapi.c|2 ++
 security/selinux/hooks.c|   33 ++---
 security/selinux/include/netlabel.h |8 +++-
 security/selinux/netlabel.c |   12 +---
 5 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index 18b73cf..a3bffb4 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -363,6 +363,7 @@ int netlbl_sock_setattr(struct sock *sk,
 int netlbl_sock_getattr(struct sock *sk,
struct netlbl_lsm_secattr *secattr);
 int netlbl_skbuff_getattr(const struct sk_buff *skb,
+ u16 family,
  struct netlbl_lsm_secattr *secattr);
 void netlbl_skbuff_err(struct sk_buff *skb, int error);
 
@@ -415,6 +416,7 @@ static inline int netlbl_sock_getattr(struct sock *sk,
return -ENOSYS;
 }
 static inline int netlbl_skbuff_getattr(const struct sk_buff *skb,
+   u16 family,
struct netlbl_lsm_secattr *secattr)
 {
return -ENOSYS;
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index d3762ea..4914615 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -332,6 +332,7 @@ int netlbl_sock_getattr(struct sock *sk, struct 
netlbl_lsm_secattr *secattr)
 /**
  * netlbl_skbuff_getattr - Determine the security attributes of a packet
  * @skb: the packet
+ * @family: protocol family
  * @secattr: the security attributes
  *
  * Description:
@@ -342,6 +343,7 @@ int netlbl_sock_getattr(struct sock *sk, struct 
netlbl_lsm_secattr *secattr)
  *
  */
 int netlbl_skbuff_getattr(const struct sk_buff *skb,
+ u16 family,
  struct netlbl_lsm_secattr *secattr)
 {
if (CIPSO_V4_OPTEXIST(skb) &&
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8bb673b..7b99d52 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3192,6 +3192,7 @@ static int selinux_parse_skb(struct sk_buff *skb, struct 
avc_audit_data *ad,
 /**
  * selinux_skb_extlbl_sid - Determine the external label of a packet
  * @skb: the packet
+ * @family: protocol family
  * @sid: the packet's SID
  *
  * Description:
@@ -3204,13 +3205,16 @@ static int selinux_parse_skb(struct sk_buff *skb, 
struct avc_audit_data *ad,
  * selinux_netlbl_skbuff_getsid().
  *
  */
-static void selinux_skb_extlbl_sid(struct sk_buff *skb, u32 *sid)
+static void selinux_skb_extlbl_sid(struct sk_buff *skb,
+  u16 family,
+  u32 *sid)
 {
u32 xfrm_sid;
u32 nlbl_sid;
 
selinux_skb_xfrm_sid(skb, &xfrm_sid);
if (selinux_netlbl_skbuff_getsid(skb,
+family,
 (xfrm_sid == SECSID_NULL ?
  SECINITSID_NETMSG : xfrm_sid),
 &nlbl_sid) != 0)
@@ -3703,7 +3707,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, 
struct sk_buff *skb)
if (err)
goto out;
 
-   err = selinux_netlbl_sock_rcv_skb(sksec, skb, &ad);
+   err = selinux_netlbl_sock_rcv_skb(sksec, skb, family, &ad);
if (err)
goto out;
 
@@ -3759,18 +3763,25 @@ out:
 static int selinux_socket_getpeersec_dgram(struct socket *sock, struct sk_buff 
*skb, u32 *secid)
 {
u32 peer_secid = SECSID_NULL;
-   int err = 0;
+   u16 family;
 
-   if (sock && sock->sk->sk_family == PF_UNIX)
+   if (sock)
+   family = sock->sk->sk_family;
+   else if (skb && skb->sk)
+   family = skb->sk->sk_family;
+   else
+   goto out;
+
+   if (sock && family == PF_UNIX)
selinux_get_inode_sid(SOCK_INODE(sock), &peer_secid);
else if (skb)
-   selinux_skb_extlbl_sid(skb, &peer_secid);
+   selinux_skb_extlbl_sid(skb, family, &peer_secid);
 
-   if (peer_secid == SECSID_NULL)
-   err = -EINVAL;
+out:
*secid = peer_secid;
-
-   return err;
+   if (peer_secid == SECSID_NULL)
+   return -EINVAL;
+   return 0;
 }
 
 static int selinux_sk_alloc_security(struct sock *sk, int family, gfp_t 
priority)
@@ -3825,7 +3836,7 @@ static int selinux_inet_conn_request(struct sock *sk, 
struct sk_buff *

[RFC PATCH v9 01/18] NetLabel: Remove unneeded RCU read locks

2007-12-21 Thread Paul Moore
This patch removes some unneeded RCU read locks as we can treat the reads as
"safe" even without RCU.  It also converts the NetLabel configuration refcount
from a spinlock protected u32 into atomic_t to be more consistent with the rest
of the kernel.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 net/netlabel/netlabel_cipso_v4.c  |5 ++-
 net/netlabel/netlabel_kapi.c  |3 +-
 net/netlabel/netlabel_mgmt.c  |   63 ++---
 net/netlabel/netlabel_mgmt.h  |7 ++--
 net/netlabel/netlabel_unlabeled.c |   22 ++---
 5 files changed, 15 insertions(+), 85 deletions(-)

diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index ba0ca8d..becf91a 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "netlabel_user.h"
 #include "netlabel_cipso_v4.h"
@@ -421,7 +422,7 @@ static int netlbl_cipsov4_add(struct sk_buff *skb, struct 
genl_info *info)
break;
}
if (ret_val == 0)
-   netlbl_mgmt_protocount_inc();
+   atomic_inc(&netlabel_mgmt_protocount);
 
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_ADD,
  &audit_info);
@@ -698,7 +699,7 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, 
struct genl_info *info)
  &audit_info,
  netlbl_cipsov4_doi_free);
if (ret_val == 0)
-   netlbl_mgmt_protocount_dec();
+   atomic_dec(&netlabel_mgmt_protocount);
 
audit_buf = netlbl_audit_start_common(AUDIT_MAC_CIPSOV4_DEL,
  &audit_info);
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 4f50949..d3762ea 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -34,6 +34,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "netlabel_domainhash.h"
 #include "netlabel_unlabeled.h"
@@ -262,7 +263,7 @@ int netlbl_enabled(void)
/* At some point we probably want to expose this mechanism to the user
 * as well so that admins can toggle NetLabel regardless of the
 * configuration */
-   return (netlbl_mgmt_protocount_value() > 0 ? 1 : 0);
+   return (atomic_read(&netlabel_mgmt_protocount) > 0);
 }
 
 /**
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index 5648337..e2258dc 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -37,14 +37,14 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "netlabel_domainhash.h"
 #include "netlabel_user.h"
 #include "netlabel_mgmt.h"
 
-/* NetLabel configured protocol count */
-static DEFINE_SPINLOCK(netlabel_mgmt_protocount_lock);
-static u32 netlabel_mgmt_protocount = 0;
+/* NetLabel configured protocol counter */
+atomic_t netlabel_mgmt_protocount = ATOMIC_INIT(0);
 
 /* Argument struct for netlbl_domhsh_walk() */
 struct netlbl_domhsh_walk_arg {
@@ -71,63 +71,6 @@ static const struct nla_policy 
netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
 };
 
 /*
- * NetLabel Misc Managment Functions
- */
-
-/**
- * netlbl_mgmt_protocount_inc - Increment the configured labeled protocol count
- *
- * Description:
- * Increment the number of labeled protocol configurations in the current
- * NetLabel configuration.  Keep track of this for use in determining if
- * NetLabel label enforcement should be active/enabled or not in the LSM.
- *
- */
-void netlbl_mgmt_protocount_inc(void)
-{
-   spin_lock(&netlabel_mgmt_protocount_lock);
-   netlabel_mgmt_protocount++;
-   spin_unlock(&netlabel_mgmt_protocount_lock);
-}
-
-/**
- * netlbl_mgmt_protocount_dec - Decrement the configured labeled protocol count
- *
- * Description:
- * Decrement the number of labeled protocol configurations in the current
- * NetLabel configuration.  Keep track of this for use in determining if
- * NetLabel label enforcement should be active/enabled or not in the LSM.
- *
- */
-void netlbl_mgmt_protocount_dec(void)
-{
-   spin_lock(&netlabel_mgmt_protocount_lock);
-   if (netlabel_mgmt_protocount > 0)
-   netlabel_mgmt_protocount--;
-   spin_unlock(&netlabel_mgmt_protocount_lock);
-}
-
-/**
- * netlbl_mgmt_protocount_value - Return the number of configured protocols
- *
- * Description:
- * Return the number of labeled protocols in the current NetLabel
- * configuration.  This value is useful in  determining if NetLabel label
- * enforcement should be active/enabled or not in the LSM.
- *
- */
-u32 netlbl_mgmt_protocount_value(void)
-{
-   u32 val;
-
-   rcu_read_lock();
-   val = netlabel_mgmt_protocount;
-   rcu_read_unlock();
-
-   return va

[RFC PATCH v9 06/18] LSM: Add inet_sys_snd_skb() LSM hook

2007-12-21 Thread Paul Moore
Add an inet_sys_snd_skb() LSM hook to allow the LSM to provide packet level
access control for all outbound packets.  Using the existing postroute_last
netfilter hook turns out to be problematic as it is can be invoked multiple
times for a single packet, e.g. individual IPsec transforms, adding unwanted
overhead and complicating the security policy.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 include/linux/security.h |   11 +++
 net/ipv4/ip_output.c |7 +++
 net/ipv6/ip6_output.c|5 +
 security/dummy.c |8 +++-
 security/security.c  |6 ++
 5 files changed, 36 insertions(+), 1 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index db19c92..1b8d332 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -876,6 +876,10 @@ struct request_sock;
  * Sets the connection's peersid to the secmark on skb.
  * @req_classify_flow:
  * Sets the flow's sid to the openreq sid.
+ * @inet_sys_snd_skb:
+ * Check permissions on outgoing network packets.
+ * @skb is the packet to check
+ * @family is the packet's address family
  *
  * Security hooks for XFRM operations.
  *
@@ -1416,6 +1420,7 @@ struct security_operations {
void (*inet_csk_clone)(struct sock *newsk, const struct request_sock 
*req);
void (*inet_conn_established)(struct sock *sk, struct sk_buff *skb);
void (*req_classify_flow)(const struct request_sock *req, struct flowi 
*fl);
+   int (*inet_sys_snd_skb)(struct sk_buff *skb, int family);
 #endif /* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -2328,6 +2333,7 @@ void security_sk_free(struct sock *sk);
 void security_sk_clone(const struct sock *sk, struct sock *newsk);
 void security_sk_classify_flow(struct sock *sk, struct flowi *fl);
 void security_req_classify_flow(const struct request_sock *req, struct flowi 
*fl);
+int security_inet_sys_snd_skb(struct sk_buff *skb, int family);
 void security_sock_graft(struct sock*sk, struct socket *parent);
 int security_inet_conn_request(struct sock *sk,
struct sk_buff *skb, struct request_sock *req);
@@ -2471,6 +2477,11 @@ static inline void security_req_classify_flow(const 
struct request_sock *req, st
 {
 }
 
+static inline int security_inet_sys_snd_skb(struct sk_buff *skb, int family)
+{
+   return 0;
+}
+
 static inline void security_sock_graft(struct sock* sk, struct socket *parent)
 {
 }
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index fd99fbd..82a7297 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -204,6 +204,8 @@ static inline int ip_skb_dst_mtu(struct sk_buff *skb)
 
 static int ip_finish_output(struct sk_buff *skb)
 {
+   int err;
+
 #if defined(CONFIG_NETFILTER) && defined(CONFIG_XFRM)
/* Policy lookup after SNAT yielded a new policy */
if (skb->dst->xfrm != NULL) {
@@ -211,6 +213,11 @@ static int ip_finish_output(struct sk_buff *skb)
return dst_output(skb);
}
 #endif
+
+   err = security_inet_sys_snd_skb(skb, AF_INET);
+   if (err)
+   return err;
+
if (skb->len > ip_skb_dst_mtu(skb) && !skb_is_gso(skb))
return ip_fragment(skb, ip_finish_output2);
else
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 6338a9c..44ddf32 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -72,8 +72,13 @@ static __inline__ void ipv6_select_ident(struct sk_buff 
*skb, struct frag_hdr *f
 
 static int ip6_output_finish(struct sk_buff *skb)
 {
+   int err;
struct dst_entry *dst = skb->dst;
 
+   err = security_inet_sys_snd_skb(skb, AF_INET6);
+   if (err)
+   return err;
+
if (dst->hh)
return neigh_hh_output(dst->hh, skb);
else if (dst->neighbour)
diff --git a/security/dummy.c b/security/dummy.c
index 0b62f95..384979a 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -848,6 +848,11 @@ static inline void dummy_req_classify_flow(const struct 
request_sock *req,
struct flowi *fl)
 {
 }
+
+static inline int dummy_inet_sys_snd_skb(struct sk_buff *skb, int family)
+{
+   return 0;
+}
 #endif /* CONFIG_SECURITY_NETWORK */
 
 #ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -1122,7 +1127,8 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, inet_csk_clone);
set_to_dummy_if_null(ops, inet_conn_established);
set_to_dummy_if_null(ops, req_classify_flow);
- #endif/* CONFIG_SECURITY_NETWORK */
+   set_to_dummy_if_null(ops, inet_sys_snd_skb);
+#endif /* CONFIG_SECURITY_NETWORK */
 #ifdef  CONFIG_SECURITY_NETWORK_XFRM
set_to_dummy_if_null(ops, xfrm_policy_alloc_security);
set_to_dummy_if_null(ops, xfrm_policy_clone_security);
diff --git a/security/security.c b/security/security.c
index 3bdcada..7f554

[RFC PATCH v9 02/18] NetLabel: Cleanup the LSM domain hash functions

2007-12-21 Thread Paul Moore
The NetLabel/LSM domain hash table search function used an argument to specify
if the default entry should be returned if an exact match couldn't be found in
the hash table.  This is a bit against the kernel's style so make two separate
functions to represent the separate behaviors.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 net/netlabel/netlabel_domainhash.c |   47 ++--
 1 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/net/netlabel/netlabel_domainhash.c 
b/net/netlabel/netlabel_domainhash.c
index b3675bd..1f8f7ac 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -109,17 +109,14 @@ static u32 netlbl_domhsh_hash(const char *key)
 /**
  * netlbl_domhsh_search - Search for a domain entry
  * @domain: the domain
- * @def: return default if no match is found
  *
  * Description:
  * Searches the domain hash table and returns a pointer to the hash table
- * entry if found, otherwise NULL is returned.  If @def is non-zero and a
- * match is not found in the domain hash table the default mapping is returned
- * if it exists.  The caller is responsibile for the rcu hash table locks
- * (i.e. the caller much call rcu_read_[un]lock()).
+ * entry if found, otherwise NULL is returned.  The caller is responsibile for
+ * the rcu hash table locks (i.e. the caller much call rcu_read_[un]lock()).
  *
  */
-static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain, u32 def)
+static struct netlbl_dom_map *netlbl_domhsh_search(const char *domain)
 {
u32 bkt;
struct netlbl_dom_map *iter;
@@ -133,10 +130,31 @@ static struct netlbl_dom_map *netlbl_domhsh_search(const 
char *domain, u32 def)
return iter;
}
 
-   if (def != 0) {
-   iter = rcu_dereference(netlbl_domhsh_def);
-   if (iter != NULL && iter->valid)
-   return iter;
+   return NULL;
+}
+
+/**
+ * netlbl_domhsh_search_def - Search for a domain entry
+ * @domain: the domain
+ * @def: return default if no match is found
+ *
+ * Description:
+ * Searches the domain hash table and returns a pointer to the hash table
+ * entry if an exact match is found, if an exact match is not present in the
+ * hash table then the default entry is returned if valid otherwise NULL is
+ * returned.  The caller is responsibile for the rcu hash table locks
+ * (i.e. the caller much call rcu_read_[un]lock()).
+ *
+ */
+static struct netlbl_dom_map *netlbl_domhsh_search_def(const char *domain)
+{
+   struct netlbl_dom_map *entry;
+
+   entry = netlbl_domhsh_search(domain);
+   if (entry == NULL) {
+   entry = rcu_dereference(netlbl_domhsh_def);
+   if (entry != NULL && entry->valid)
+   return entry;
}
 
return NULL;
@@ -224,7 +242,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
if (entry->domain != NULL) {
bkt = netlbl_domhsh_hash(entry->domain);
spin_lock(&netlbl_domhsh_lock);
-   if (netlbl_domhsh_search(entry->domain, 0) == NULL)
+   if (netlbl_domhsh_search(entry->domain) == NULL)
list_add_tail_rcu(&entry->list,
&rcu_dereference(netlbl_domhsh)->tbl[bkt]);
else
@@ -307,7 +325,10 @@ int netlbl_domhsh_remove(const char *domain, struct 
netlbl_audit *audit_info)
struct audit_buffer *audit_buf;
 
rcu_read_lock();
-   entry = netlbl_domhsh_search(domain, (domain != NULL ? 0 : 1));
+   if (domain)
+   entry = netlbl_domhsh_search(domain);
+   else
+   entry = netlbl_domhsh_search_def(domain);
if (entry == NULL)
goto remove_return;
switch (entry->type) {
@@ -377,7 +398,7 @@ int netlbl_domhsh_remove_default(struct netlbl_audit 
*audit_info)
  */
 struct netlbl_dom_map *netlbl_domhsh_getentry(const char *domain)
 {
-   return netlbl_domhsh_search(domain, 1);
+   return netlbl_domhsh_search_def(domain);
 }
 
 /**

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v9 00/18] Labeled networking patches for 2.6.25 (against 2.6.24-rc6)

2007-12-21 Thread Paul Moore
One more revision before the end of the year, backed against 2.6.24-rc6
or rather Linus' linux-2.6 tree from an hour ago.  The changes this time are
pretty minor: some IPv6 address tweaks and the object class/permission changes
already discussed on the SELinux list.

I've also update the git tree available here:

 * git://git.infradead.org/users/pcmoore/lblnet-2.6_testing

-- 
paul moore
linux security @ hp

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v9 03/18] NetLabel: Consolidate the LSM domain mapping/hashing locks

2007-12-21 Thread Paul Moore
Currently we use two separate spinlocks to protect both the hash/mapping table
and the default entry.  This could be considered a bit foolish because it adds
complexity without offering any real performance advantage.  This patch
removes the dedicated default spinlock and protects the default entry with the
hash/mapping table spinlock.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 net/netlabel/netlabel_domainhash.c |   30 +-
 1 files changed, 9 insertions(+), 21 deletions(-)

diff --git a/net/netlabel/netlabel_domainhash.c 
b/net/netlabel/netlabel_domainhash.c
index 1f8f7ac..9a8ea01 100644
--- a/net/netlabel/netlabel_domainhash.c
+++ b/net/netlabel/netlabel_domainhash.c
@@ -54,9 +54,6 @@ struct netlbl_domhsh_tbl {
  * hash table should be okay */
 static DEFINE_SPINLOCK(netlbl_domhsh_lock);
 static struct netlbl_domhsh_tbl *netlbl_domhsh = NULL;
-
-/* Default domain mapping */
-static DEFINE_SPINLOCK(netlbl_domhsh_def_lock);
 static struct netlbl_dom_map *netlbl_domhsh_def = NULL;
 
 /*
@@ -239,24 +236,22 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
INIT_RCU_HEAD(&entry->rcu);
 
rcu_read_lock();
+   spin_lock(&netlbl_domhsh_lock);
if (entry->domain != NULL) {
bkt = netlbl_domhsh_hash(entry->domain);
-   spin_lock(&netlbl_domhsh_lock);
if (netlbl_domhsh_search(entry->domain) == NULL)
list_add_tail_rcu(&entry->list,
&rcu_dereference(netlbl_domhsh)->tbl[bkt]);
else
ret_val = -EEXIST;
-   spin_unlock(&netlbl_domhsh_lock);
} else {
INIT_LIST_HEAD(&entry->list);
-   spin_lock(&netlbl_domhsh_def_lock);
if (rcu_dereference(netlbl_domhsh_def) == NULL)
rcu_assign_pointer(netlbl_domhsh_def, entry);
else
ret_val = -EEXIST;
-   spin_unlock(&netlbl_domhsh_def_lock);
}
+   spin_unlock(&netlbl_domhsh_lock);
audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
if (audit_buf != NULL) {
audit_log_format(audit_buf,
@@ -337,23 +332,16 @@ int netlbl_domhsh_remove(const char *domain, struct 
netlbl_audit *audit_info)
   entry->domain);
break;
}
-   if (entry != rcu_dereference(netlbl_domhsh_def)) {
-   spin_lock(&netlbl_domhsh_lock);
-   if (entry->valid) {
-   entry->valid = 0;
+   spin_lock(&netlbl_domhsh_lock);
+   if (entry->valid) {
+   entry->valid = 0;
+   if (entry != rcu_dereference(netlbl_domhsh_def))
list_del_rcu(&entry->list);
-   ret_val = 0;
-   }
-   spin_unlock(&netlbl_domhsh_lock);
-   } else {
-   spin_lock(&netlbl_domhsh_def_lock);
-   if (entry->valid) {
-   entry->valid = 0;
+   else
rcu_assign_pointer(netlbl_domhsh_def, NULL);
-   ret_val = 0;
-   }
-   spin_unlock(&netlbl_domhsh_def_lock);
+   ret_val = 0;
}
+   spin_unlock(&netlbl_domhsh_lock);
 
audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_DEL, audit_info);
if (audit_buf != NULL) {

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v9 05/18] LSM: Add secctx_to_secid() LSM hook

2007-12-21 Thread Paul Moore
Add a secctx_to_secid() LSM hook to go along with the existing
secid_to_secctx() LSM hook.  This patch also includes the SELinux
implementation for this hook.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
Acked-by: Stephen Smalley <[EMAIL PROTECTED]>
---

 include/linux/security.h |   13 +
 security/dummy.c |6 ++
 security/security.c  |6 ++
 security/selinux/hooks.c |6 ++
 4 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index ac05083..db19c92 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1183,6 +1183,10 @@ struct request_sock;
  * Convert secid to security context.
  * @secid contains the security ID.
  * @secdata contains the pointer that stores the converted security 
context.
+ * @secctx_to_secid:
+ *  Convert security context to secid.
+ *  @secid contains the pointer to the generated security ID.
+ *  @secdata contains the security context.
  *
  * @release_secctx:
  * Release the security context.
@@ -1371,6 +1375,7 @@ struct security_operations {
int (*getprocattr)(struct task_struct *p, char *name, char **value);
int (*setprocattr)(struct task_struct *p, char *name, void *value, 
size_t size);
int (*secid_to_secctx)(u32 secid, char **secdata, u32 *seclen);
+   int (*secctx_to_secid)(char *secdata, u32 seclen, u32 *secid);
void (*release_secctx)(char *secdata, u32 seclen);
 
 #ifdef CONFIG_SECURITY_NETWORK
@@ -1603,6 +1608,7 @@ int security_setprocattr(struct task_struct *p, char 
*name, void *value, size_t
 int security_netlink_send(struct sock *sk, struct sk_buff *skb);
 int security_netlink_recv(struct sk_buff *skb, int cap);
 int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
+int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid);
 void security_release_secctx(char *secdata, u32 seclen);
 
 #else /* CONFIG_SECURITY */
@@ -2280,6 +2286,13 @@ static inline int security_secid_to_secctx(u32 secid, 
char **secdata, u32 *secle
return -EOPNOTSUPP;
 }
 
+static inline int security_secctx_to_secid(char *secdata,
+  u32 seclen,
+  u32 *secid)
+{
+   return -EOPNOTSUPP;
+}
+
 static inline void security_release_secctx(char *secdata, u32 seclen)
 {
 }
diff --git a/security/dummy.c b/security/dummy.c
index 3ccfbbe..0b62f95 100644
--- a/security/dummy.c
+++ b/security/dummy.c
@@ -928,6 +928,11 @@ static int dummy_secid_to_secctx(u32 secid, char 
**secdata, u32 *seclen)
return -EOPNOTSUPP;
 }
 
+static int dummy_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
+{
+   return -EOPNOTSUPP;
+}
+
 static void dummy_release_secctx(char *secdata, u32 seclen)
 {
 }
@@ -1086,6 +1091,7 @@ void security_fixup_ops (struct security_operations *ops)
set_to_dummy_if_null(ops, getprocattr);
set_to_dummy_if_null(ops, setprocattr);
set_to_dummy_if_null(ops, secid_to_secctx);
+   set_to_dummy_if_null(ops, secctx_to_secid);
set_to_dummy_if_null(ops, release_secctx);
 #ifdef CONFIG_SECURITY_NETWORK
set_to_dummy_if_null(ops, unix_stream_connect);
diff --git a/security/security.c b/security/security.c
index 0e1f1f1..3bdcada 100644
--- a/security/security.c
+++ b/security/security.c
@@ -816,6 +816,12 @@ int security_secid_to_secctx(u32 secid, char **secdata, 
u32 *seclen)
 }
 EXPORT_SYMBOL(security_secid_to_secctx);
 
+int security_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
+{
+   return security_ops->secctx_to_secid(secdata, seclen, secid);
+}
+EXPORT_SYMBOL(security_secctx_to_secid);
+
 void security_release_secctx(char *secdata, u32 seclen)
 {
return security_ops->release_secctx(secdata, seclen);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 9f3124b..8bb673b 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -4710,6 +4710,11 @@ static int selinux_secid_to_secctx(u32 secid, char 
**secdata, u32 *seclen)
return security_sid_to_context(secid, secdata, seclen);
 }
 
+static int selinux_secctx_to_secid(char *secdata, u32 seclen, u32 *secid)
+{
+   return security_context_to_sid(secdata, seclen, secid);
+}
+
 static void selinux_release_secctx(char *secdata, u32 seclen)
 {
kfree(secdata);
@@ -4898,6 +4903,7 @@ static struct security_operations selinux_ops = {
.setprocattr =  selinux_setprocattr,
 
.secid_to_secctx =  selinux_secid_to_secctx,
+   .secctx_to_secid =  selinux_secctx_to_secid,
.release_secctx =   selinux_release_secctx,
 
 .unix_stream_connect = selinux_socket_unix_stream_connect,

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]

[RFC PATCH v9 12/18] SELinux: Add a new peer class and permissions to the Flask definitions

2007-12-21 Thread Paul Moore
Add additional Flask definitions to support the new "peer" object class and
additional permissions to the netif and node object classes.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 security/selinux/include/av_perm_to_string.h |5 +
 security/selinux/include/av_permissions.h|5 +
 security/selinux/include/class_to_string.h   |7 +++
 security/selinux/include/flask.h |1 +
 4 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/security/selinux/include/av_perm_to_string.h 
b/security/selinux/include/av_perm_to_string.h
index 049bf69..caa0634 100644
--- a/security/selinux/include/av_perm_to_string.h
+++ b/security/selinux/include/av_perm_to_string.h
@@ -37,6 +37,8 @@
S_(SECCLASS_NODE, NODE__ENFORCE_DEST, "enforce_dest")
S_(SECCLASS_NODE, NODE__DCCP_RECV, "dccp_recv")
S_(SECCLASS_NODE, NODE__DCCP_SEND, "dccp_send")
+   S_(SECCLASS_NODE, NODE__RECVFROM, "recvfrom")
+   S_(SECCLASS_NODE, NODE__SENDTO, "sendto")
S_(SECCLASS_NETIF, NETIF__TCP_RECV, "tcp_recv")
S_(SECCLASS_NETIF, NETIF__TCP_SEND, "tcp_send")
S_(SECCLASS_NETIF, NETIF__UDP_RECV, "udp_recv")
@@ -45,6 +47,8 @@
S_(SECCLASS_NETIF, NETIF__RAWIP_SEND, "rawip_send")
S_(SECCLASS_NETIF, NETIF__DCCP_RECV, "dccp_recv")
S_(SECCLASS_NETIF, NETIF__DCCP_SEND, "dccp_send")
+   S_(SECCLASS_NETIF, NETIF__INGRESS, "ingress")
+   S_(SECCLASS_NETIF, NETIF__EGRESS, "egress")
S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__CONNECTTO, "connectto")
S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN, "newconn")
S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__ACCEPTFROM, 
"acceptfrom")
@@ -159,3 +163,4 @@
S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NODE_BIND, "node_bind")
S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NAME_CONNECT, "name_connect")
S_(SECCLASS_MEMPROTECT, MEMPROTECT__MMAP_ZERO, "mmap_zero")
+   S_(SECCLASS_PEER, PEER__RECV, "recv")
diff --git a/security/selinux/include/av_permissions.h 
b/security/selinux/include/av_permissions.h
index eda89a2..c2b5bb2 100644
--- a/security/selinux/include/av_permissions.h
+++ b/security/selinux/include/av_permissions.h
@@ -292,6 +292,8 @@
 #define NODE__ENFORCE_DEST0x0040UL
 #define NODE__DCCP_RECV   0x0080UL
 #define NODE__DCCP_SEND   0x0100UL
+#define NODE__RECVFROM0x0200UL
+#define NODE__SENDTO  0x0400UL
 #define NETIF__TCP_RECV   0x0001UL
 #define NETIF__TCP_SEND   0x0002UL
 #define NETIF__UDP_RECV   0x0004UL
@@ -300,6 +302,8 @@
 #define NETIF__RAWIP_SEND 0x0020UL
 #define NETIF__DCCP_RECV  0x0040UL
 #define NETIF__DCCP_SEND  0x0080UL
+#define NETIF__INGRESS0x0100UL
+#define NETIF__EGRESS 0x0200UL
 #define NETLINK_SOCKET__IOCTL 0x0001UL
 #define NETLINK_SOCKET__READ  0x0002UL
 #define NETLINK_SOCKET__WRITE 0x0004UL
@@ -824,3 +828,4 @@
 #define DCCP_SOCKET__NODE_BIND0x0040UL
 #define DCCP_SOCKET__NAME_CONNECT 0x0080UL
 #define MEMPROTECT__MMAP_ZERO 0x0001UL
+#define PEER__RECV0x0001UL
diff --git a/security/selinux/include/class_to_string.h 
b/security/selinux/include/class_to_string.h
index e77de0e..b1b0d1d 100644
--- a/security/selinux/include/class_to_string.h
+++ b/security/selinux/include/class_to_string.h
@@ -64,3 +64,10 @@
 S_(NULL)
 S_("dccp_socket")
 S_("memprotect")
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_(NULL)
+S_("peer")
diff --git a/security/selinux/include/flask.h b/security/selinux/include/flask.h
index a9c2b20..09e9dd2 100644
--- a/security/selinux/include/flask.h
+++ b/security/selinux/include/flask.h
@@ -50,6 +50,7 @@
 #define SECCLASS_KEY 58
 #define SECCLASS_DCCP_SOCKET 60
 #define SECCLASS_MEMPROTECT  61
+#define SECCLASS_PEER68
 
 /*
  * Security identifier indices for initial entities

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v9 09/18] SELinux: Only store the network interface's ifindex

2007-12-21 Thread Paul Moore
Instead of storing the packet's network interface name store the ifindex.  This
allows us to defer the need to lookup the net_device structure until the audit
record is generated meaning that in the majority of cases we never need to
bother with this at all.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 security/selinux/avc.c |   15 ---
 security/selinux/hooks.c   |4 ++--
 security/selinux/include/avc.h |2 +-
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 81b3dff..e8529e2 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -661,9 +661,18 @@ void avc_audit(u32 ssid, u32 tsid,
"daddr", "dest");
break;
}
-   if (a->u.net.netif)
-   audit_log_format(ab, " netif=%s",
-   a->u.net.netif);
+   if (a->u.net.netif > 0) {
+   struct net_device *dev;
+
+   /* NOTE: we always use init's namespace */
+   dev = dev_get_by_index(&init_net,
+  a->u.net.netif);
+   if (dev) {
+   audit_log_format(ab, " netif=%s",
+dev->name);
+   dev_put(dev);
+   }
+   }
break;
}
}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 8336c93..b451b4c 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3691,7 +3691,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, 
struct sk_buff *skb)
family = PF_INET;
 
AVC_AUDIT_DATA_INIT(&ad, NET);
-   ad.u.net.netif = skb->dev ? skb->dev->name : "[unknown]";
+   ad.u.net.netif = skb->iif;
ad.u.net.family = family;
 
err = selinux_parse_skb(skb, &ad, &addrp, &len, 1, NULL);
@@ -4022,7 +4022,7 @@ static unsigned int selinux_ip_postroute_last(unsigned 
int hooknum,
sksec = sk->sk_security;
 
AVC_AUDIT_DATA_INIT(&ad, NET);
-   ad.u.net.netif = dev->name;
+   ad.u.net.netif = dev->ifindex;
ad.u.net.family = family;
 
err = selinux_parse_skb(skb, &ad, &addrp, &len, 0, &proto);
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h
index 553607a..80c28fa 100644
--- a/security/selinux/include/avc.h
+++ b/security/selinux/include/avc.h
@@ -51,7 +51,7 @@ struct avc_audit_data {
struct inode *inode;
} fs;
struct {
-   char *netif;
+   int netif;
struct sock *sk;
u16 family;
__be16 dport;

-
To unsubscribe from this list: send the line "unsubscribe 
linux-security-module" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC PATCH v9 14/18] SELinux: Enable dynamic enable/disable of the network access checks

2007-12-21 Thread Paul Moore
This patch introduces a mechanism for checking when labeled IPsec or SECMARK
are in use by keeping introducing a configuration reference counter for each
subsystem.  In the case of labeled IPsec, whenever a labeled SA or SPD entry
is created the labeled IPsec/XFRM reference count is increased and when the
entry is removed it is decreased.  In the case of SECMARK, when a SECMARK
target is created the reference count is increased and later decreased when the
target is removed.  These reference counters allow SELinux to quickly determine
if either of these subsystems are enabled.

NetLabel already has a similar mechanism which provides the netlbl_enabled()
function.

This patch also renames the selinux_relabel_packet_permission() function to
selinux_secmark_relabel_packet_permission() as the original name and
description were misleading in that they referenced a single packet label which
is not the case.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 include/linux/selinux.h |   45 +++---
 net/netfilter/xt_SECMARK.c  |   13 ++-
 security/selinux/exports.c  |   20 +++--
 security/selinux/hooks.c|   46 +++
 security/selinux/include/xfrm.h |   12 ++
 security/selinux/xfrm.c |   18 ++-
 6 files changed, 132 insertions(+), 22 deletions(-)

diff --git a/include/linux/selinux.h b/include/linux/selinux.h
index 6080f73..8c2cc4c 100644
--- a/include/linux/selinux.h
+++ b/include/linux/selinux.h
@@ -120,16 +120,35 @@ void selinux_get_task_sid(struct task_struct *tsk, u32 
*sid);
 int selinux_string_to_sid(char *str, u32 *sid);
 
 /**
- * selinux_relabel_packet_permission - check permission to relabel a packet
- * @sid: ID value to be applied to network packet (via SECMARK, most 
likely)
+ * selinux_secmark_relabel_packet_permission - secmark permission check
+ * @sid: SECMARK ID value to be applied to network packet
  *
- * Returns 0 if the current task is allowed to label packets with the
- * supplied security ID.  Note that it is implicit that the packet is 
always
- * being relabeled from the default unlabled value, and that the access
- * control decision is made in the AVC.
+ * Returns 0 if the current task is allowed to set the SECMARK label of
+ * packets with the supplied security ID.  Note that it is implicit that
+ * the packet is always being relabeled from the default unlabeled value,
+ * and that the access control decision is made in the AVC.
  */
-int selinux_relabel_packet_permission(u32 sid);
+int selinux_secmark_relabel_packet_permission(u32 sid);
 
+/**
+ * selinux_secmark_refcount_inc - increments the secmark use counter
+ *
+ * SELinux keeps track of the current SECMARK targets in use so it knows
+ * when to apply SECMARK label access checks to network packets.  This
+ * function incements this reference count to indicate that a new SECMARK
+ * target has been configured.
+ */
+void selinux_secmark_refcount_inc(void);
+
+/**
+ * selinux_secmark_refcount_dec - decrements the secmark use counter
+ *
+ * SELinux keeps track of the current SECMARK targets in use so it knows
+ * when to apply SECMARK label access checks to network packets.  This
+ * function decements this reference count to indicate that one of the
+ * existing SECMARK targets has been removed/flushed.
+ */
+void selinux_secmark_refcount_dec(void);
 #else
 
 static inline int selinux_audit_rule_init(u32 field, u32 op,
@@ -184,11 +203,21 @@ static inline int selinux_string_to_sid(const char *str, 
u32 *sid)
return 0;
 }
 
-static inline int selinux_relabel_packet_permission(u32 sid)
+static inline int selinux_secmark_relabel_packet_permission(u32 sid)
 {
return 0;
 }
 
+static inline void selinux_secmark_refcount_inc(void)
+{
+   return;
+}
+
+static inline void selinux_secmark_refcount_dec(void)
+{
+   return;
+}
+
 #endif /* CONFIG_SECURITY_SELINUX */
 
 #endif /* _LINUX_SELINUX_H */
diff --git a/net/netfilter/xt_SECMARK.c b/net/netfilter/xt_SECMARK.c
index 235806e..db4a1fe 100644
--- a/net/netfilter/xt_SECMARK.c
+++ b/net/netfilter/xt_SECMARK.c
@@ -72,12 +72,13 @@ static bool checkentry_selinux(struct 
xt_secmark_target_info *info)
return false;
}
 
-   err = selinux_relabel_packet_permission(sel->selsid);
+   err = selinux_secmark_relabel_packet_permission(sel->selsid);
if (err) {
printk(KERN_INFO PFX "unable to obtain relabeling 
permission\n");
return false;
}
 
+   selinux_secmark_refcount_inc();
return true;
 }
 
@@ -109,11 +110,20 @@ static bool checkentry(const char *tablename, const void 
*entry,
return true;
 }
 
+void destroy(const struct xt_target *target, void *targinfo)
+{
+   switch (mode) {
+   case SECMARK_MODE_SEL:
+   selinu

[RFC PATCH v9 11/18] SELinux: Add a capabilities bitmap to SELinux policy version 22

2007-12-21 Thread Paul Moore
Add a new policy capabilities bitmap to SELinux policy version 22.  This bitmap
will enable the security server to query the policy to determine which features
it supports.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 security/selinux/Kconfig|2 -
 security/selinux/include/security.h |   15 ++
 security/selinux/selinuxfs.c|   89 +--
 security/selinux/ss/policydb.c  |   18 +++
 security/selinux/ss/policydb.h  |2 +
 security/selinux/ss/services.c  |   67 ++
 6 files changed, 185 insertions(+), 8 deletions(-)

diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
index b32a459..2b517d6 100644
--- a/security/selinux/Kconfig
+++ b/security/selinux/Kconfig
@@ -145,7 +145,7 @@ config SECURITY_SELINUX_POLICYDB_VERSION_MAX
 config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
int "NSA SELinux maximum supported policy format version value"
depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX
-   range 15 21
+   range 15 22
default 19
help
  This option sets the value for the maximum policy format version
diff --git a/security/selinux/include/security.h 
b/security/selinux/include/security.h
index a33437b..a22de97 100644
--- a/security/selinux/include/security.h
+++ b/security/selinux/include/security.h
@@ -25,13 +25,14 @@
 #define POLICYDB_VERSION_MLS   19
 #define POLICYDB_VERSION_AVTAB 20
 #define POLICYDB_VERSION_RANGETRANS21
+#define POLICYDB_VERSION_POLCAP22
 
 /* Range of policy versions we understand*/
 #define POLICYDB_VERSION_MIN   POLICYDB_VERSION_BASE
 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
 #define POLICYDB_VERSION_MAX   
CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
 #else
-#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_RANGETRANS
+#define POLICYDB_VERSION_MAX   POLICYDB_VERSION_POLCAP
 #endif
 
 struct netlbl_lsm_secattr;
@@ -39,8 +40,19 @@ struct netlbl_lsm_secattr;
 extern int selinux_enabled;
 extern int selinux_mls_enabled;
 
+/* Policy capabilities */
+enum {
+   POLICYDB_CAPABILITY_NETPEER,
+   __POLICYDB_CAPABILITY_MAX
+};
+#define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1)
+
+extern int selinux_policycap_netpeer;
+
 int security_load_policy(void * data, size_t len);
 
+int security_policycap_supported(unsigned int req_cap);
+
 #define SEL_VEC_MAX 32
 struct av_decision {
u32 allowed;
@@ -91,6 +103,7 @@ int security_get_classes(char ***classes, int *nclasses);
 int security_get_permissions(char *class, char ***perms, int *nperms);
 int security_get_reject_unknown(void);
 int security_get_allow_unknown(void);
+int security_get_policycaps(int *len, int **values);
 
 #define SECURITY_FS_USE_XATTR  1 /* use xattr */
 #define SECURITY_FS_USE_TRANS  2 /* use transition SIDs, e.g. 
devpts/tmpfs */
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 2fa483f..b87e9eb 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -2,6 +2,11 @@
  *
  * Added conditional policy language extensions
  *
+ *  Updated: Hewlett-Packard <[EMAIL PROTECTED]>
+ *
+ *  Added support for the policy capability bitmap
+ *
+ * Copyright (C) 2007 Hewlett-Packard Development Company, L.P.
  * Copyright (C) 2003 - 2004 Tresys Technology, LLC
  * Copyright (C) 2004 Red Hat, Inc., James Morris <[EMAIL PROTECTED]>
  * This program is free software; you can redistribute it and/or modify
@@ -35,6 +40,11 @@
 #include "objsec.h"
 #include "conditional.h"
 
+/* Policy capability filenames */
+static char *policycap_names[] = {
+   "network_peer_controls"
+};
+
 unsigned int selinux_checkreqprot = CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE;
 
 #ifdef CONFIG_SECURITY_SELINUX_ENABLE_SECMARK_DEFAULT
@@ -72,6 +82,9 @@ static int *bool_pending_values = NULL;
 static struct dentry *class_dir = NULL;
 static unsigned long last_class_ino;
 
+/* global data for policy capabilities */
+static struct dentry *policycap_dir = NULL;
+
 extern void selnl_notify_setenforce(int val);
 
 /* Check whether a task is allowed to use a security operation. */
@@ -111,10 +124,11 @@ enum sel_inos {
 
 static unsigned long sel_last_ino = SEL_INO_NEXT - 1;
 
-#define SEL_INITCON_INO_OFFSET 0x0100
-#define SEL_BOOL_INO_OFFSET0x0200
-#define SEL_CLASS_INO_OFFSET   0x0400
-#define SEL_INO_MASK   0x00ff
+#define SEL_INITCON_INO_OFFSET 0x0100
+#define SEL_BOOL_INO_OFFSET0x0200
+#define SEL_CLASS_INO_OFFSET   0x0400
+#define SEL_POLICYCAP_INO_OFFSET   0x0800
+#define SEL_INO_MASK   0x00ff
 
 #define TMPBUFLEN  12
 static ssize_t sel_read_enforce(struct file *filp, char __user *buf,
@@ -263,6 +277,7 @@ static const struct file_operations sel_policyvers_ops = {
 /* declaration for sel_w

[RFC PATCH v9 17/18] NetLabel: Add auditing to the static labeling mechanism

2007-12-21 Thread Paul Moore
This patch adds auditing support to the NetLabel static labeling mechanism.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 include/linux/audit.h |2 
 net/netlabel/netlabel_unlabeled.c |  207 ++---
 2 files changed, 195 insertions(+), 14 deletions(-)

diff --git a/include/linux/audit.h b/include/linux/audit.h
index c687816..bdd6f5d 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -115,6 +115,8 @@
 #define AUDIT_MAC_IPSEC_ADDSPD 1413/* Not used */
 #define AUDIT_MAC_IPSEC_DELSPD 1414/* Not used */
 #define AUDIT_MAC_IPSEC_EVENT  1415/* Audit an IPSec event */
+#define AUDIT_MAC_UNLBL_STCADD 1416/* NetLabel: add a static label */
+#define AUDIT_MAC_UNLBL_STCDEL 1417/* NetLabel: del a static label */
 
 #define AUDIT_FIRST_KERN_ANOM_MSG   1700
 #define AUDIT_LAST_KERN_ANOM_MSG1799
diff --git a/net/netlabel/netlabel_unlabeled.c 
b/net/netlabel/netlabel_unlabeled.c
index d0c628c..42e81fd 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -147,6 +147,74 @@ static const struct nla_policy 
netlbl_unlabel_genl_policy[NLBL_UNLABEL_A_MAX + 1
 };
 
 /*
+ * Audit Helper Functions
+ */
+
+/**
+ * netlbl_unlabel_audit_addr4 - Audit an IPv4 address
+ * @audit_buf: audit buffer
+ * @dev: network interface
+ * @addr: IP address
+ * @mask: IP address mask
+ *
+ * Description:
+ * Write the IPv4 address and address mask, if necessary, to @audit_buf.
+ *
+ */
+static void netlbl_unlabel_audit_addr4(struct audit_buffer *audit_buf,
+const char *dev,
+__be32 addr, __be32 mask)
+{
+   u32 mask_val = ntohl(mask);
+
+   if (dev != NULL)
+   audit_log_format(audit_buf, " netif=%s", dev);
+   audit_log_format(audit_buf, " src=" NIPQUAD_FMT, NIPQUAD(addr));
+   if (mask_val != 0x) {
+   u32 mask_len = 0;
+   while (mask_val > 0) {
+   mask_val <<= 1;
+   mask_len++;
+   }
+   audit_log_format(audit_buf, " src_prefixlen=%d", mask_len);
+   }
+}
+
+/**
+ * netlbl_unlabel_audit_addr6 - Audit an IPv6 address
+ * @audit_buf: audit buffer
+ * @dev: network interface
+ * @addr: IP address
+ * @mask: IP address mask
+ *
+ * Description:
+ * Write the IPv6 address and address mask, if necessary, to @audit_buf.
+ *
+ */
+static void netlbl_unlabel_audit_addr6(struct audit_buffer *audit_buf,
+const char *dev,
+const struct in6_addr *addr,
+const struct in6_addr *mask)
+{
+   if (dev != NULL)
+   audit_log_format(audit_buf, " netif=%s", dev);
+   audit_log_format(audit_buf, " src=" NIP6_FMT, NIP6(*addr));
+   if (ntohl(mask->s6_addr32[3]) != 0x) {
+   u32 mask_len = 0;
+   u32 mask_val;
+   int iter = -1;
+   while (ntohl(mask->s6_addr32[++iter]) == 0x)
+   mask_len += 32;
+   mask_val = ntohl(mask->s6_addr32[iter]);
+   while (mask_val > 0) {
+   mask_val <<= 1;
+   mask_len++;
+   }
+   audit_log_format(audit_buf, " src_prefixlen=%d", mask_len);
+   }
+}
+
+/*
  * Unlabeled Connection Hash Table Functions
  */
 
@@ -530,6 +598,7 @@ add_iface_failure:
  * @mask: address mask in network byte order
  * @addr_len: length of address/mask (4 for IPv4, 16 for IPv6)
  * @secid: LSM secid value for the entry
+ * @audit_info: NetLabel audit information
  *
  * Description:
  * Adds a new entry to the unlabeled connection hash table.  Returns zero on
@@ -541,12 +610,18 @@ static int netlbl_unlhsh_add(struct net *net,
 const void *addr,
 const void *mask,
 u32 addr_len,
-u32 secid)
+u32 secid,
+struct netlbl_audit *audit_info)
 {
int ret_val;
int ifindex;
struct net_device *dev;
struct netlbl_unlhsh_iface *iface;
+   struct in_addr *addr4, *mask4;
+   struct in6_addr *addr6, *mask6;
+   struct audit_buffer *audit_buf = NULL;
+   char *secctx = NULL;
+   u32 secctx_len;
 
if (addr_len != sizeof(struct in_addr) &&
addr_len != sizeof(struct in6_addr))
@@ -573,13 +648,28 @@ static int netlbl_unlhsh_add(struct net *net,
goto unlhsh_add_return;
}
}
+   audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_STCADD,
+ audit_info);
switch (addr_len) {
case sizeof(struct in_addr):
-  

[RFC PATCH v9 16/18] NetLabel: Introduce static network labels for unlabeled connections

2007-12-21 Thread Paul Moore
Most trusted OSs, with the exception of Linux, have the ability to specify
static security labels for unlabeled networks.  This patch adds this ability to
the NetLabel packet labeling framework.

If the NetLabel subsystem is called to determine the security attributes of an
incoming packet it first checks to see if any recognized NetLabel packet
labeling protocols are in-use on the packet.  If none can be found then the
unlabled connection table is queried and based on the packets incoming
interface and address it is matched with a security label as configured by the
administrator using the netlabel_tools package.  The matching security label is
returned to the caller just as if the packet was explicitly labeled using a
labeling protocol.

Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
---

 include/net/netlabel.h|6 
 net/netlabel/netlabel_kapi.c  |   16 
 net/netlabel/netlabel_unlabeled.c | 1375 +
 net/netlabel/netlabel_unlabeled.h |  145 
 4 files changed, 1524 insertions(+), 18 deletions(-)

diff --git a/include/net/netlabel.h b/include/net/netlabel.h
index a3bffb4..b3213c7 100644
--- a/include/net/netlabel.h
+++ b/include/net/netlabel.h
@@ -67,7 +67,11 @@
  * NetLabel NETLINK protocol
  */
 
-#define NETLBL_PROTO_VERSION1
+/* NetLabel NETLINK protocol version
+ *  1: initial version
+ *  2: added static labels for unlabeled connections
+ */
+#define NETLBL_PROTO_VERSION2
 
 /* NetLabel NETLINK types/families */
 #define NETLBL_NLTYPE_NONE  0
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c
index 4914615..c69e3e1 100644
--- a/net/netlabel/netlabel_kapi.c
+++ b/net/netlabel/netlabel_kapi.c
@@ -312,7 +312,7 @@ socket_setattr_return:
  * @secattr: the security attributes
  *
  * Description:
- * Examines the given sock to see any NetLabel style labeling has been
+ * Examines the given sock to see if any NetLabel style labeling has been
  * applied to the sock, if so it parses the socket label and returns the
  * security attributes in @secattr.  Returns zero on success, negative values
  * on failure.
@@ -320,13 +320,7 @@ socket_setattr_return:
  */
 int netlbl_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr)
 {
-   int ret_val;
-
-   ret_val = cipso_v4_sock_getattr(sk, secattr);
-   if (ret_val == 0)
-   return 0;
-
-   return netlbl_unlabel_getattr(secattr);
+   return cipso_v4_sock_getattr(sk, secattr);
 }
 
 /**
@@ -350,7 +344,7 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
cipso_v4_skbuff_getattr(skb, secattr) == 0)
return 0;
 
-   return netlbl_unlabel_getattr(secattr);
+   return netlbl_unlabel_getattr(skb, family, secattr);
 }
 
 /**
@@ -434,6 +428,10 @@ static int __init netlbl_init(void)
if (ret_val != 0)
goto init_failure;
 
+   ret_val = netlbl_unlabel_init(NETLBL_UNLHSH_BITSIZE);
+   if (ret_val != 0)
+   goto init_failure;
+
ret_val = netlbl_netlink_init();
if (ret_val != 0)
goto init_failure;
diff --git a/net/netlabel/netlabel_unlabeled.c 
b/net/netlabel/netlabel_unlabeled.c
index 7f5df0c..d0c628c 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -10,7 +10,7 @@
  */
 
 /*
- * (c) Copyright Hewlett-Packard Development Company, L.P., 2006
+ * (c) Copyright Hewlett-Packard Development Company, L.P., 2006 - 2007
  *
  * This program is free software;  you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -29,27 +29,99 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
 #include 
 #include 
 #include 
-
+#include 
+#include 
+#include 
 #include 
 #include 
+#include 
 
 #include "netlabel_user.h"
 #include "netlabel_domainhash.h"
 #include "netlabel_unlabeled.h"
+#include "netlabel_mgmt.h"
+
+/* NOTE: at present we always use init's network namespace since we don't
+ *   presently support different namespaces even though the majority of
+ *   the functions in this file are "namespace safe" */
+
+/* The unlabeled connection hash table which we use to map network interfaces
+ * and addresses of unlabeled packets to a user specified secid value for the
+ * LSM.  The hash table is used to lookup the network interface entry
+ * (struct netlbl_unlhsh_iface) and then the interface entry is used to
+ * lookup an IP address match from an ordered list.  If a network interface
+ * match can not be found in the hash table then the default entry
+ * (netlbl_unlhsh_def) is used.  The IP address entry list
+ * (struct netlbl_unlhsh_addr) is ordered such that the entries with a
+ * larger netmask come first.
+ */
+struct n

Re: [RFC PATCH v9 12/18] SELinux: Add a new peer class and permissions to the Flask definitions

2007-12-21 Thread Paul Moore
On Friday 21 December 2007 12:36:15 pm Stephen Smalley wrote:
> On Fri, 2007-12-21 at 12:09 -0500, Paul Moore wrote:
> > Add additional Flask definitions to support the new "peer" object class
> > and additional permissions to the netif and node object classes.
> >
> > Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
>
> Not an obstacle to merging, but need to get this reserved in policy too.

Yep, I'm working on some policy patches now, although I'm not sure when I'll 
have those done.  I'll post the FLASK definition changes today either way, 
that way they are at least there even if the policy rules aren't ready yet.

> > ---
> >
> >  security/selinux/include/av_perm_to_string.h |5 +
> >  security/selinux/include/av_permissions.h|5 +
> >  security/selinux/include/class_to_string.h   |7 +++
> >  security/selinux/include/flask.h |1 +
> >  4 files changed, 18 insertions(+), 0 deletions(-)
> >
> > diff --git a/security/selinux/include/av_perm_to_string.h
> > b/security/selinux/include/av_perm_to_string.h index 049bf69..caa0634
> > 100644
> > --- a/security/selinux/include/av_perm_to_string.h
> > +++ b/security/selinux/include/av_perm_to_string.h
> > @@ -37,6 +37,8 @@
> > S_(SECCLASS_NODE, NODE__ENFORCE_DEST, "enforce_dest")
> > S_(SECCLASS_NODE, NODE__DCCP_RECV, "dccp_recv")
> > S_(SECCLASS_NODE, NODE__DCCP_SEND, "dccp_send")
> > +   S_(SECCLASS_NODE, NODE__RECVFROM, "recvfrom")
> > +   S_(SECCLASS_NODE, NODE__SENDTO, "sendto")
> > S_(SECCLASS_NETIF, NETIF__TCP_RECV, "tcp_recv")
> > S_(SECCLASS_NETIF, NETIF__TCP_SEND, "tcp_send")
> > S_(SECCLASS_NETIF, NETIF__UDP_RECV, "udp_recv")
> > @@ -45,6 +47,8 @@
> > S_(SECCLASS_NETIF, NETIF__RAWIP_SEND, "rawip_send")
> > S_(SECCLASS_NETIF, NETIF__DCCP_RECV, "dccp_recv")
> > S_(SECCLASS_NETIF, NETIF__DCCP_SEND, "dccp_send")
> > +   S_(SECCLASS_NETIF, NETIF__INGRESS, "ingress")
> > +   S_(SECCLASS_NETIF, NETIF__EGRESS, "egress")
> > S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__CONNECTTO,
> > "connectto") S_(SECCLASS_UNIX_STREAM_SOCKET, UNIX_STREAM_SOCKET__NEWCONN,
> > "newconn") S_(SECCLASS_UNIX_STREAM_SOCKET,
> > UNIX_STREAM_SOCKET__ACCEPTFROM, "acceptfrom") @@ -159,3 +163,4 @@
> > S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NODE_BIND, "node_bind")
> > S_(SECCLASS_DCCP_SOCKET, DCCP_SOCKET__NAME_CONNECT, "name_connect")
> > S_(SECCLASS_MEMPROTECT, MEMPROTECT__MMAP_ZERO, "mmap_zero")
> > +   S_(SECCLASS_PEER, PEER__RECV, "recv")
> > diff --git a/security/selinux/include/av_permissions.h
> > b/security/selinux/include/av_permissions.h index eda89a2..c2b5bb2 100644
> > --- a/security/selinux/include/av_permissions.h
> > +++ b/security/selinux/include/av_permissions.h
> > @@ -292,6 +292,8 @@
> >  #define NODE__ENFORCE_DEST0x0040UL
> >  #define NODE__DCCP_RECV   0x0080UL
> >  #define NODE__DCCP_SEND   0x0100UL
> > +#define NODE__RECVFROM0x0200UL
> > +#define NODE__SENDTO  0x0400UL
> >  #define NETIF__TCP_RECV   0x0001UL
> >  #define NETIF__TCP_SEND   0x0002UL
> >  #define NETIF__UDP_RECV   0x0004UL
> > @@ -300,6 +302,8 @@
> >  #define NETIF__RAWIP_SEND 0x0020UL
> >  #define NETIF__DCCP_RECV  0x0040UL
> >  #define NETIF__DCCP_SEND  0x0080UL
> > +#define NETIF__INGRESS0x0100UL
> > +#define NETIF__EGRESS 0x0200UL
> >  #define NETLINK_SOCKET__IOCTL 0x0001UL
> >  #define NETLINK_SOCKET__READ  0x0002UL
> >  #define NETLINK_SOCKET__WRITE 0x0004UL
> > @@ -824,3 +828,4 @@
> >  #define DCCP_SOCKET__NODE_BIND0x0040UL
> >  #define DCCP_SOCKET__NAME_CONNECT 0x0080UL
> >  #define MEMPROTECT__MMAP_ZERO 0x0001UL
> > +#define PEER__RECV0x0001UL
> > diff --git a/security/selinux/include/class_to_string.h
> > b/security/selinux/include/class_to_string.h index e77de0e..b1b0d1d

  1   2   3   >