Re: [PATCH 2/2] Version 11 (2.6.24-rc2) Smack: Simplified Mandatory Access Control Kernel

2007-11-09 Thread Eric Paris
[snip from fs/super.c:vfs_kern_mount() just for reference]
if (data) {
secdata = alloc_secdata();
if (!secdata)
goto out_mnt;

error = security_sb_copy_data(type, data, secdata);
if (error)
goto out_free_secdata;
}

error = type->get_sb(type, flags, name, data, mnt);
if (error < 0)
goto out_free_secdata;
BUG_ON(!mnt->mnt_sb);

error = security_sb_kern_mount(mnt->mnt_sb, secdata);
if (error)
goto out_sb;
[end snip]

> +/**
> + * smack_sb_copy_data - copy mount options data for processing
> + * @type: file system type
> + * @orig: where to start
> + * @smackopts
> + *
> + * Returns 0 on success or -ENOMEM on error.
> + *
> + * Copy the Smack specific mount options out of the mount
> + * options list.
> + */
> +static int smack_sb_copy_data(struct file_system_type *type, void *orig,
> + void *smackopts)
> +{
> +   char *cp, *commap, *otheropts, *dp;
> +
> +   /* Binary mount data: just copy */
> +   if (type->fs_flags & FS_BINARY_MOUNTDATA) {
> +   copy_page(smackopts, orig);
> +   return 0;
> +   }

So given NFS, which may have passed you a nfs_mount_data,
nfs_parsed_mount_data, or a nfs_clone_mount struct one page is going
to get coppied back out to the VFS.
> +
> +   otheropts = (char *)get_zeroed_page(GFP_KERNEL);
> +   if (otheropts == NULL)
> +   return -ENOMEM;
> +
> +   for (cp = orig, commap = orig; commap != NULL; cp = commap + 1) {
> +   if (strstr(cp, SMK_FSDEFAULT) == cp)
> +   dp = smackopts;
> +   else if (strstr(cp, SMK_FSFLOOR) == cp)
> +   dp = smackopts;
> +   else if (strstr(cp, SMK_FSHAT) == cp)
> +   dp = smackopts;
> +   else if (strstr(cp, SMK_FSROOT) == cp)
> +   dp = smackopts;
> +   else
> +   dp = otheropts;
> +
> +   commap = strchr(cp, ',');
> +   if (commap != NULL)
> +   *commap = '\0';
> +
> +   if (*dp != '\0')
> +   strcat(dp, ",");
> +   strcat(dp, cp);
> +   }
> +
> +   strcpy(orig, otheropts);
> +   free_page((unsigned long)otheropts);
> +
> +   return 0;
> +}
> +
> +/**
> + * smack_sb_kern_mount - Smack specific mount processing
> + * @sb: the file system superblock
> + * @data: the smack mount options
> + *
> + * Returns 0 on success, an error code on failure
> + */
> +static int smack_sb_kern_mount(struct super_block *sb, void *data)
> +{
> +   struct dentry *root = sb->s_root;
> +   struct inode *inode = root->d_inode;
> +   struct superblock_smack *sp = sb->s_security;
> +   struct inode_smack *isp;
> +   char *op;
> +   char *commap;
> +   char *nsp;
> +
> +   spin_lock(&sp->smk_sblock);
> +   if (sp->smk_initialized != 0) {
> +   spin_unlock(&sp->smk_sblock);
> +   return 0;
> +   }
> +   sp->smk_initialized = 1;
> +   spin_unlock(&sp->smk_sblock);
> +
> +   for (op = data; op != NULL; op = commap) {

Here you walk this page of binary NFS data looking for your stuff.
And while I assume its unlikely you find anything you like on this
page and go wrong, its not impossible.

SELinux tried to solve this problem right here in its equivalent
function years ago, but it has since been despised by the FS people
and now i'm trying to make everyone happy.  I'd love you comment on
how you plan to support NFS and other filesystems which use
FS_BINARY_MOUNTDATA)

> +   commap = strchr(op, ',');
> +   if (commap != NULL)
> +   *commap++ = '\0';
> +
> +   if (strncmp(op, SMK_FSHAT, strlen(SMK_FSHAT)) == 0) {
> +   op += strlen(SMK_FSHAT);
> +   nsp = smk_import(op, 0);
> +   if (nsp != NULL)
> +   sp->smk_hat = nsp;
> +   } else if (strncmp(op, SMK_FSFLOOR, strlen(SMK_FSFLOOR)) == 
> 0) {
> +   op += strlen(SMK_FSFLOOR);
> +   nsp = smk_import(op, 0);
> +   if (nsp != NULL)
> +   sp->smk_floor = nsp;
> +   } else if (strncmp(op, SMK_FSDEFAULT,
> +  strlen(SMK_FSDEFAULT)) == 0) {
> +   op += strlen(SMK_FSDEFAULT);
> +   nsp = smk_import(op, 0);
> +   if (nsp != NULL)
> +   sp->smk_default = nsp;
> +   } else if (strncmp(op, SMK_FSROOT, strlen(SMK_FSROOT)) == 0) {
> +   op += strlen(SMK_FSROOT);
> +   nsp = smk_import(op, 0);
> +  

Re: [PATCH -v3] SELinux: Add get, set, and cloning of superblock security information

2007-11-09 Thread Eric Paris

On Fri, 2007-11-09 at 14:46 -0800, Casey Schaufler wrote:
> --- Eric Paris <[EMAIL PROTECTED]> wrote:
> 
> > Adds security_get_sb_mnt_opts, security_set_sb_mnt_opts, and
> > security_clont_sb_mnt_opts to the LSM and to SELinux.  This will allow
> > filesystems to directly own and control all of their mount options if
> > they so choose.
> 
> I understand why you would want get_sb_mnt_opts(), but what
> is the value for set_sb_mnt_opts() and what is the purpose of
> clone_sb_mnt_opts()?

set is really the most important one.  NFS knows when it creates a
superblock (using SELinux as an example) that it wants to set
context=blah.  Thus it calls into set_sb_mnt_opts with the flag for
"context=" and "blah."   get_sb_mnt_opts will likely get used in the
future for /proc/mounts to be able to report the security options.
clone is really just to make it easy for the FS.  If they know "i want
the new one to look like this old one" they can just call into clone_
and don't have to worry about dealing freeing memory or anything like
that...
> 
> > This interface deals only with option identifiers and
> > strings so it should generic enough for any LSM which may come in the
> > future.  Filesystems which pass text mount data around in the kernel
> > (almost all of them) need not currently make use of this interface for
> > SELinux sake since it will still parse those strings as it always has.
> 
> If SELinux is still dealing with strings on it's own what is
> the point of these hooks?

The point is that not all filesystems use strings.  NFS is the real in
kernel kicker.  See things like fs/nfs/namespace.c:nfs_do_clone_mount()
where they pass a binary blob into the vfs which arrives to the LSM as a
binary blob which it cannot parse. (note NFS also uses
nfs_parsed_mount_data and nfs_mount_data)

Since the LSM can't (ok, "isn't allowed" according to previous
discussions with vfs/fs people) deal with those binary blobs to get its
options some method must be created for those filesystems to pass that
data in a usable way.
> 
> > An LSM would need to implement these functions only if they had mount
> > time options, such as selinux has context= or fscontext=.  If the LSM
> > has no mount time options they could simply not implement and let the
> > dummy ops take care of things.  
> 
> Smack and SELinux currently deal with options in sb_kern_mount(), with
> help from sb_copy_data(). Why change the implementation?

I don't plan to change anything for any FS that passes text options, but
we aren't allowed to parse binary blobs (nor can we actually even know
for sure what blobs we are dealing with currently in the LSM even if we
were 'allowed' to parse them and get the needed data directly)

> > A LSM other than SELinux would need to define new option numbers in
> > security.h
> 
> I don't think it is a good idea to require that LSM specific
> information be stored outside the scope of the LSM.

Its either that or FS specific knowledge inside the LSM.  See
security/selinux/hooks.c:try_context_mount() for an example of NFS
specific knowledge inside an LSM.  This current implementation has bugs
since we don't know if *data is any of the 3 above named structs.  This
patch doesn't fix those issues, but lays the groundwork for a fix...

> > (or could reuse if they have the same basic meaning I guess)
> > and any FS which decides to own there own security options would need to
> > be patched to use this new interface for every possible LSM.  This is
> > because it was stated to me very clearly that LSM's should not attempt
> > to understand FS mount data and the burdon to understand security should
> > be in the FS which owns the options.
> 
> Perhaps a mount option prefix then. "Smack.root", "SELinux.context",
> that sort of thing. An LSM writer shouldn't have to patch security.h
> every time she wants to add a mount option.

I did originally namespace these things such as SELINUX__CONTEXT_MNT but
later wondered what the point was.  If another LSM decided to somehow
make use of the same infrastructure in FS that have binary mount data
and they used context= they should be able to use a generic CONTEXT_MNT
rather than pretend that flag has some special meaning.  It actually
works nicely for other LSMs since once I get finished with NFS it should
support 3 mount options which although maybe not named nicely for non
SELinux LSMs will be usable without any FS changes...

And while I don't think its a great thing that every LSM is going to be
adding things to the generic security.h if they want things to work,
they are going to have to add things to the generic structures used by
filesystems which use binary mount data.

We have this tight coupling of information.  3 options.

1) make the LSM very FS knowledgeable (what SELinux currently does for
NFS and is maybe not a great idea and has already been strongly pooped
on on list before)
2) make the FS know what LSM is running and what options it is allowed
to send (obviously a terrible unsc

Re: [PATCH 1/2] NetLabel: Introduce a new kernel configuration API for NetLabel - Version 11 (2.6.24-rc2) Smack: Simplified Mandatory Access Control Kernel

2007-11-09 Thread James Morris
On Fri, 9 Nov 2007, Andrew Morton wrote:

> On Thu, 08 Nov 2007 20:48:35 -0800
> Casey Schaufler <[EMAIL PROTECTED]> wrote:
> 
> > From: Paul Moore <[EMAIL PROTECTED]>
> > 
> > Add a new set of configuration functions to the NetLabel/LSM API so that
> > LSMs can perform their own configuration of the NetLabel subsystem without
> > relying on assistance from userspace.
> > 
> > Signed-off-by: Paul Moore <[EMAIL PROTECTED]>
> 
> You sent it, so this patch needs a Signed-off-by:you, please.

Also add

Reviewed-by: James Morris <[EMAIL PROTECTED]>


-- 
James Morris
<[EMAIL PROTECTED]>
-
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] 64 bit capabilities

2007-11-09 Thread Andrew Morgan
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Serge,

I guess I'm not sure what to do about this.

In the caller there is an explicit check for negative rc in which case
the modifed function is not called.

The argument really is an unsigned quantity and I felt this change was
an improvement/fix.

Can you suggest a change that would satisfy you here?

Thanks

Andrew

Serge E. Hallyn wrote:

> Other than the one comment below,

> Acked-by: Serge Hallyn <[EMAIL PROTECTED]>


>>
- -static inline int cap_from_disk(__le32 *caps, struct linux_binprm *bprm,
- - int size)
+static inline int cap_from_disk(struct vfs_cap_data *caps,
+   struct linux_binprm *bprm, unsigned size)

> Note that you switched this to unsigned, but the caller is still sending
> in an int (rc).

[..]

@@ -219,7 +245,7 @@ static int get_file_caps(struct linux_binprm *bprm)
 {
struct dentry *dentry;
int rc = 0;
- - __le32 v1caps[XATTR_CAPS_SZ];
+   struct vfs_cap_data vcaps;
struct inode *inode;
>>
if (bprm->file->f_vfsmnt->mnt_flags & MNT_NOSUID) {
@@ -232,8 +258,8 @@ static int get_file_caps(struct linux_binprm *bprm)
if (!inode->i_op || !inode->i_op->getxattr)
goto out;
>>
- - rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, &v1caps,
- - XATTR_CAPS_SZ);
+   rc = inode->i_op->getxattr(dentry, XATTR_NAME_CAPS, &vcaps,
+  XATTR_CAPS_SZ);
if (rc == -ENODATA || rc == -EOPNOTSUPP) {
/* no data, that's ok */
rc = 0;
@@ -242,7 +268,7 @@ static int get_file_caps(struct linux_binprm *bprm)
if (rc < 0)
goto out;
>>
- - rc = cap_from_disk(v1caps, bprm, rc);
+   rc = cap_from_disk(&vcaps, bprm, rc);
if (rc)
printk(KERN_NOTICE "%s: cap_from_disk returned %d for %s\n",
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.7 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFHNTXnmwytjiwfWMwRAl+SAKCWzzeTd/5/gRA3wqE+cb9yfPS9cwCfVjC0
w4D0isaFXnOCW77WcG+1d7o=
=kRqk
-END PGP SIGNATURE-
-
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] 64 bit capabilities

2007-11-09 Thread Andrew Morgan
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Serge E. Hallyn wrote:
>>> Note: to apply this patch against Linus' upstream kernel, you will first
>>> have to undo this other patch from Serge:
>>>
>>>  From b68680e4731abbd78863063aaa0dca2a6d8cc723 Mon Sep 17 00:00:00 2001
>>>  From: Serge E. Hallyn <[EMAIL PROTECTED]>
>>>  Date: Sun, 21 Oct 2007 16:41:38 -0700
>>>  Subject: [PATCH] capabilities: clean up file capability reading
>>>
>>> It seems that this patch has made it into 2.6.24-rc1, but it is not
>> Well I did that reversion, but I don't understand why.  Was that patch
>> wrong, or did it make this new patch impractical, or...?
> 
> Andrew wanted to keep the vfs_cap_data.data[] structure, using two
> 'data's for 64-bit caps (and later three for 96-bit caps), whereas
> my patch had gotten rid of the 'data' struct made its members inline.
> 
> His 64-bit caps patch keeps the stack abuse fix at get_file_caps(),
> which was the more important part of that patch.

Serge and I had diverged in what we considered a cleanup. I took his
important stack abuse fix, but did not follow the path he was taking
with the capability.h file changes.

So the higher order bit is "yes" to the "impractical" part of your
question above.

Cheers

Andrew
-BEGIN PGP SIGNATURE-
Version: GnuPG v1.4.7 (Darwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFHNTBZmwytjiwfWMwRAp9xAJ9Ys7jGTKlnRoeIH6EeijhNoeBfuACeIEUF
E3LC7BCk/zk4Ae/RlTgHMTE=
=9tu/
-END PGP SIGNATURE-
-
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 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: [PATCH 1/2] NetLabel: Introduce a new kernel configuration API for NetLabel - Version 11 (2.6.24-rc2) Smack: Simplified Mandatory Access Control Kernel

2007-11-09 Thread Andrew Morton
On Thu, 08 Nov 2007 20:48:35 -0800
Casey Schaufler <[EMAIL PROTECTED]> wrote:

> From: Paul Moore <[EMAIL PROTECTED]>
> 
> Add a new set of configuration functions to the NetLabel/LSM API so that
> LSMs can perform their own configuration of the NetLabel subsystem without
> relying on assistance from userspace.
> 
> Signed-off-by: Paul Moore <[EMAIL PROTECTED]>

You sent it, so this patch needs a Signed-off-by:you, please.
-
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] 64 bit capabilities

2007-11-09 Thread Serge E. Hallyn
Quoting Andrew Morgan ([EMAIL PROTECTED]):
> -BEGIN PGP SIGNED MESSAGE-
> Hash: SHA1
> 
> Andrew, Serge
> 
> The attached patch (e3d27bcb07485a6c8927c8e4f5483d35a99680c3) adds
> 64-bit capability support to the kernel. This version of the patch is
> designed to apply against the 2.6.23-mm1 tree.
> 
> FWIW libcap-2.00 supports this change (and earlier capability formats)
> 
>  http://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/
> 
> Cheers
> 
> Andrew
> 
> Note: to apply this patch against Linus' upstream kernel, you will first
> have to undo this other patch from Serge:
> 
>  From b68680e4731abbd78863063aaa0dca2a6d8cc723 Mon Sep 17 00:00:00 2001
>  From: Serge E. Hallyn <[EMAIL PROTECTED]>
>  Date: Sun, 21 Oct 2007 16:41:38 -0700
>  Subject: [PATCH] capabilities: clean up file capability reading
> 
> It seems that this patch has made it into 2.6.24-rc1, but it is not
> present in 2.6.23-mm1.
> 
> -BEGIN PGP SIGNATURE-
> Version: GnuPG v1.2.6 (GNU/Linux)
> 
> iD8DBQFHMr5rQheEq9QabfIRAkWuAJ9vQBefhA31KWobFGkIugMnPiS7TwCgkeNg
> DXC3U5OPNO/w9ERJBltxMKo=
> =SjLL
> -END PGP SIGNATURE-

> >From e3d27bcb07485a6c8927c8e4f5483d35a99680c3 Mon Sep 17 00:00:00 2001
> From: Andrew G. Morgan <[EMAIL PROTECTED]>
> Date: Wed, 7 Nov 2007 23:17:06 -0800
> Subject: [PATCH] Add 64-bit capability support to the kernel.
> 
> The patch has supports legacy (32-bit) capability userspace, and where
> possible translates 32-bit capabilities to/from userspace and the VFS
> to 64-bit kernel space capabilities. If a capability set cannot be
> compressed into 32-bits for consumption by user space, the system call
> fails, with -ERANGE.
> 
> FWIW libcap-2.00 supports this change (and earlier capability formats)
> 
>  http://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/
> 
> Signed-off-by: Andrew G. Morgan <[EMAIL PROTECTED]>

Other than the one comment below,

Acked-by: Serge Hallyn <[EMAIL PROTECTED]>

> ---
>  fs/nfsd/auth.c |   10 +-
>  fs/proc/array.c|   21 +++-
>  include/linux/capability.h |  222 
> +++-
>  kernel/capability.c|   89 --
>  mm/oom_kill.c  |5 +-
>  security/commoncap.c   |   93 +--
>  security/dummy.c   |   17 ++-
>  7 files changed, 332 insertions(+), 125 deletions(-)
> 
[...]
> diff --git a/security/commoncap.c b/security/commoncap.c
> index 43f9027..dd63129 100644
> --- a/security/commoncap.c
> +++ b/security/commoncap.c
> @@ -1,4 +1,4 @@
> -/* Common capabilities, needed by capability.o and root_plug.o 
> +/* Common capabilities, needed by capability.o and root_plug.o
>   *
>   *   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
> @@ -87,9 +87,9 @@ int cap_capget (struct task_struct *target, kernel_cap_t 
> *effective,
>   kernel_cap_t *inheritable, kernel_cap_t *permitted)
>  {
>   /* Derived from kernel/capability.c:sys_capget. */
> - *effective = cap_t (target->cap_effective);
> - *inheritable = cap_t (target->cap_inheritable);
> - *permitted = cap_t (target->cap_permitted);
> + *effective = target->cap_effective;
> + *inheritable = target->cap_inheritable;
> + *permitted = target->cap_permitted;
>   return 0;
>  }
> 
> @@ -190,28 +190,54 @@ int cap_inode_killpriv(struct dentry *dentry)
>   return inode->i_op->removexattr(dentry, XATTR_NAME_CAPS);
>  }
> 
> -static inline int cap_from_disk(__le32 *caps, struct linux_binprm *bprm,
> - int size)
> +static inline int cap_from_disk(struct vfs_cap_data *caps,
> + struct linux_binprm *bprm, unsigned size)

Note that you switched this to unsigned, but the caller is still sending
in an int (rc).

>  {
>   __u32 magic_etc;
> + unsigned tocopy, i;
> 
> - if (size != XATTR_CAPS_SZ)
> + if (size < sizeof(magic_etc)) {
>   return -EINVAL;
> + }
> 
> - magic_etc = le32_to_cpu(caps[0]);
> + magic_etc = le32_to_cpu(caps->magic_etc);
> 
>   switch ((magic_etc & VFS_CAP_REVISION_MASK)) {
> - case VFS_CAP_REVISION:
> - if (magic_etc & VFS_CAP_FLAGS_EFFECTIVE)
> - bprm->cap_effective = true;
> - else
> - bprm->cap_effective = false;
> - bprm->cap_permitted = to_cap_t( le32_to_cpu(caps[1]) );
> - bprm->cap_inheritable = to_cap_t( le32_to_cpu(caps[2]) );
> - return 0;
> + case VFS_CAP_REVISION_1:
> + if (size != XATTR_CAPS_SZ_1) {
> + return -EINVAL;
> + }
> + tocopy = VFS_CAP_U32_1;
> + break;
> + case VFS_CAP_REVISION_2:
> + if (size != XATTR_CAPS_SZ_2) {
> + return -EINVAL;
> + }
> + tocopy = VFS_CAP_U32_2;
> +   

Re: [PATCH] 64 bit capabilities

2007-11-09 Thread Serge E. Hallyn
Quoting Andrew Morton ([EMAIL PROTECTED]):
> On Wed, 07 Nov 2007 23:44:49 -0800
> Andrew Morgan <[EMAIL PROTECTED]> wrote:
> 
> > The attached patch (e3d27bcb07485a6c8927c8e4f5483d35a99680c3) adds
> > 64-bit capability support to the kernel. This version of the patch is
> > designed to apply against the 2.6.23-mm1 tree.
> > 
> > FWIW libcap-2.00 supports this change (and earlier capability formats)
> > 
> >  http://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/
> > 
> > Cheers
> > 
> > Andrew
> > 
> > Note: to apply this patch against Linus' upstream kernel, you will first
> > have to undo this other patch from Serge:
> > 
> >  From b68680e4731abbd78863063aaa0dca2a6d8cc723 Mon Sep 17 00:00:00 2001
> >  From: Serge E. Hallyn <[EMAIL PROTECTED]>
> >  Date: Sun, 21 Oct 2007 16:41:38 -0700
> >  Subject: [PATCH] capabilities: clean up file capability reading
> > 
> > It seems that this patch has made it into 2.6.24-rc1, but it is not
> 
> Well I did that reversion, but I don't understand why.  Was that patch
> wrong, or did it make this new patch impractical, or...?

Andrew wanted to keep the vfs_cap_data.data[] structure, using two
'data's for 64-bit caps (and later three for 96-bit caps), whereas
my patch had gotten rid of the 'data' struct made its members inline.

His 64-bit caps patch keeps the stack abuse fix at get_file_caps(),
which was the more important part of that patch.

thanks,
-serge
-
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: File descriptor object capability LSM module. Feasability?

2007-11-09 Thread Crispin Cowan
Added apparmor-devel because Rob proposes something that could be an
enhancement to AppArmor.

Rob Meijer wrote:
> A while ago I asked some questions on the subject of at* system calls
> on the list and got rather dismissive responses.
> After having given up on the whole concept for a while, the recent
> discussions on this list have made me put some more efford into trying
> to define more clearly what I would like to try to achieve.
>
> http://polacanthus.net/fdoc.html
>
> I am interested to learn if from this short document it is clear what I
> would like to accomplish with an FdOC LSM module, and if this is clear,
> if the things that would be required as patches to the LSM base code would
> potentialy be acceptable to achieve the goal of making an LSM module that
> more or less confirms to the object capability model.
>   
The goals are reasonably clear.

I really like the idea of striving for POLA/object capabilities with
respect to open file descriptors rather than files, as it will fit
better with the traditional UNIX DAC model.

Your document talks about LSM having a security syscall. I think this
was removed long ago, and if you want to have a syscall, you are
supposed to implement it as a user-level library on top of a file
system. AppArmor does this for the change_hat() API for an example.

> Further I would like to hear (if the abouve are feasable), if I should build
> an LSM module for just this purpose, or if I should try to put the sugested
> functionality in a patch set proposal for an existing LSM implementation
> that could be complementary (AppArmor would seem like a good complementary
> functionality).
>   
AppArmor has traditionally been a purely ambient capability system (none
of the privileges can be delegated). More recently, JJ and I have been
discussing hybrid models, where some things can be delegated, especially
with respect to network access controls. In particular, consider the
case of xinetd, which accepts connections, then passes the open network
connection to a child for processing.

The reason I prefer an ambient capability system for AppArmor is that
ambient capabilities are superior for confining legacy applications that
are oblivious to capabilities, and thus unable to sensibly delegate
them. File descriptors and network connections make an interesting
exception, precisely because UNIX applications already know how to
delegate file descriptors, so there is a sound reason to consider using
an object capability model for file descriptors.

The other issue with the object capability model is analyzability.
Stephen Smalley complained about this in some public setting a while ago
when someone basically asked for an object capability enhancement to
SELinux. Stephen is correct, in that with a pure ambient capability
model, you can analyze the text of the complete system policy, and
readily determine the maximum permissions that any given entity will
have under that policy. With an object capability model, the scope of
access of a given program is determined by what gets passed into it, and
so you would have to resort to tools to compute the transitive closure
of all capabilities that *could* be delegated to it.

Tractability of global policy is already a strength of SELinux vs.
AppArmor, and so this also argues that it would be a good idea to tend
toward object capabilities to enhance the difference between SELinux and
AppArmor.

I have two design philosophies that would tend to limit how far we go
into object capabilities:

* Keep it simple: a lot of why it is so nice to use AppArmor is
  because it is simple. Therefore, for any proposed new feature I
  apply this litmus test:
  o Show a use case of a real program (not a straw man) such
that with the current features, your choice is to either
provide a dangerously permissive security policy, or the
policy breaks the program.
* Be learnable: Most of the current AppArmor policy features are
  generated in policy by the automated learning tools. There are a
  few features that are not "learnable" (use of variables) and to
  this day they are not used much. This is not an absolute rule, but
  the case for including a feature that cannot be utilized by
  automatic learning had better be compelling.

Crispin

-- 
Crispin Cowan, Ph.D.   http://crispincowan.com/~crispin
CEO, Mercenary Linux   http://mercenarylinux.com/
   Itanium. Vista. GPLv3. Complexity at work

-
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 -v3] SELinux: Add get, set, and cloning of superblock security information

2007-11-09 Thread Casey Schaufler

--- Eric Paris <[EMAIL PROTECTED]> wrote:

> Adds security_get_sb_mnt_opts, security_set_sb_mnt_opts, and
> security_clont_sb_mnt_opts to the LSM and to SELinux.  This will allow
> filesystems to directly own and control all of their mount options if
> they so choose.

I understand why you would want get_sb_mnt_opts(), but what
is the value for set_sb_mnt_opts() and what is the purpose of
clone_sb_mnt_opts()?

> This interface deals only with option identifiers and
> strings so it should generic enough for any LSM which may come in the
> future.  Filesystems which pass text mount data around in the kernel
> (almost all of them) need not currently make use of this interface for
> SELinux sake since it will still parse those strings as it always has.

If SELinux is still dealing with strings on it's own what is
the point of these hooks?

> An LSM would need to implement these functions only if they had mount
> time options, such as selinux has context= or fscontext=.  If the LSM
> has no mount time options they could simply not implement and let the
> dummy ops take care of things.  

Smack and SELinux currently deal with options in sb_kern_mount(), with
help from sb_copy_data(). Why change the implementation?

> A LSM other than SELinux would need to define new option numbers in
> security.h

I don't think it is a good idea to require that LSM specific
information be stored outside the scope of the LSM.

> (or could reuse if they have the same basic meaning I guess)
> and any FS which decides to own there own security options would need to
> be patched to use this new interface for every possible LSM.  This is
> because it was stated to me very clearly that LSM's should not attempt
> to understand FS mount data and the burdon to understand security should
> be in the FS which owns the options.

Perhaps a mount option prefix then. "Smack.root", "SELinux.context",
that sort of thing. An LSM writer shouldn't have to patch security.h
every time she wants to add a mount option.

> Signed-off-by: Eric Paris <[EMAIL PROTECTED]>
> 
> ---
> 
> For now the only forseen user of this interface is NFS.  NFS uses a
> binary blob in kernel for mount data (it uses this blob irrespective of
> the binary vs. text mount options it can get from userspace.)  NFS must
> then set its own mount options explicitly so we need some interface for
> it to do so.
> 
> 
>  include/linux/security.h  |   36 ++
>  security/dummy.c  |   26 ++
>  security/security.c   |   20 +
>  security/selinux/hooks.c  |  749
> -
>  security/selinux/include/objsec.h |1 +
>  5 files changed, 578 insertions(+), 254 deletions(-)
> 
> diff --git a/include/linux/security.h b/include/linux/security.h
> index ac05083..dcbb792 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -34,6 +34,12 @@
>  #include 
>  #include 
>  
> +/* only a char in selinux superblock security struct flags */
> +#define FSCONTEXT_MNT0x01
> +#define CONTEXT_MNT  0x02
> +#define ROOTCONTEXT_MNT  0x04
> +#define DEFCONTEXT_MNT   0x08
> +
>  /*
>   * Bounding set
>   */
> @@ -261,6 +267,22 @@ struct request_sock;
>   *   Update module state after a successful pivot.
>   *   @old_nd contains the nameidata structure for the old root.
>   *  @new_nd contains the nameidata structure for the new root.
> + * @sb_get_mnt_opts:
> + *  Get the security relevant mount options used for a superblock
> + *  @sb the superblock to get security mount options from
> + *  @mount_options array for pointers to mount options
> + *  @mount_flags array of ints specifying what each mount options is
> + *  @num_opts number of options in the arrays
> + * @sb_set_mnt_opts:
> + *  Set the security relevant mount options used for a superblock
> + *  @sb the superblock to set security mount options for
> + *  @mount_options array for pointers to mount options
> + *  @mount_flags array of ints specifying what each mount options is
> + *  @num_opts number of options in the arrays
> + * @sb_clone_mnt_opts:
> + *   Copy all security options from a given superblock to another
> + *   @oldsb old superblock which contain information to clone
> + *   @newsb new superblock which needs filled in
>   *
>   * Security hooks for inode operations.
>   *
> @@ -1242,6 +1264,13 @@ struct security_operations {
>struct nameidata * new_nd);
>   void (*sb_post_pivotroot) (struct nameidata * old_nd,
>  struct nameidata * new_nd);
> + int (*sb_get_mnt_opts) (const struct super_block *sb,
> + char ***mount_options, int **flags,
> + int *num_opts);
> + int (*sb_set_mnt_opts) (struct super_block *sb, char **mount_options,
> + int *flags, int num_opts);
> + void (*sb_clone_mnt_opts) (const 

Re: [PATCH] 64 bit capabilities

2007-11-09 Thread Andrew Morton
On Wed, 07 Nov 2007 23:44:49 -0800
Andrew Morgan <[EMAIL PROTECTED]> wrote:

> The attached patch (e3d27bcb07485a6c8927c8e4f5483d35a99680c3) adds
> 64-bit capability support to the kernel. This version of the patch is
> designed to apply against the 2.6.23-mm1 tree.
> 
> FWIW libcap-2.00 supports this change (and earlier capability formats)
> 
>  http://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.6/
> 
> Cheers
> 
> Andrew
> 
> Note: to apply this patch against Linus' upstream kernel, you will first
> have to undo this other patch from Serge:
> 
>  From b68680e4731abbd78863063aaa0dca2a6d8cc723 Mon Sep 17 00:00:00 2001
>  From: Serge E. Hallyn <[EMAIL PROTECTED]>
>  Date: Sun, 21 Oct 2007 16:41:38 -0700
>  Subject: [PATCH] capabilities: clean up file capability reading
> 
> It seems that this patch has made it into 2.6.24-rc1, but it is not

Well I did that reversion, but I don't understand why.  Was that patch
wrong, or did it make this new patch impractical, or...?
-
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


[PATCH -v3] SELinux: Add get, set, and cloning of superblock security information

2007-11-09 Thread Eric Paris
Adds security_get_sb_mnt_opts, security_set_sb_mnt_opts, and
security_clont_sb_mnt_opts to the LSM and to SELinux.  This will allow
filesystems to directly own and control all of their mount options if
they so choose.  This interface deals only with option identifiers and
strings so it should generic enough for any LSM which may come in the
future.  Filesystems which pass text mount data around in the kernel
(almost all of them) need not currently make use of this interface for
SELinux sake since it will still parse those strings as it always has.

An LSM would need to implement these functions only if they had mount
time options, such as selinux has context= or fscontext=.  If the LSM
has no mount time options they could simply not implement and let the
dummy ops take care of things.  

A LSM other than SELinux would need to define new option numbers in
security.h (or could reuse if they have the same basic meaning I guess)
and any FS which decides to own there own security options would need to
be patched to use this new interface for every possible LSM.  This is
because it was stated to me very clearly that LSM's should not attempt
to understand FS mount data and the burdon to understand security should
be in the FS which owns the options.

Signed-off-by: Eric Paris <[EMAIL PROTECTED]>

---

For now the only forseen user of this interface is NFS.  NFS uses a
binary blob in kernel for mount data (it uses this blob irrespective of
the binary vs. text mount options it can get from userspace.)  NFS must
then set its own mount options explicitly so we need some interface for
it to do so.


 include/linux/security.h  |   36 ++
 security/dummy.c  |   26 ++
 security/security.c   |   20 +
 security/selinux/hooks.c  |  749 -
 security/selinux/include/objsec.h |1 +
 5 files changed, 578 insertions(+), 254 deletions(-)

diff --git a/include/linux/security.h b/include/linux/security.h
index ac05083..dcbb792 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -34,6 +34,12 @@
 #include 
 #include 
 
+/* only a char in selinux superblock security struct flags */
+#define FSCONTEXT_MNT  0x01
+#define CONTEXT_MNT0x02
+#define ROOTCONTEXT_MNT0x04
+#define DEFCONTEXT_MNT 0x08
+
 /*
  * Bounding set
  */
@@ -261,6 +267,22 @@ struct request_sock;
  * Update module state after a successful pivot.
  * @old_nd contains the nameidata structure for the old root.
  *  @new_nd contains the nameidata structure for the new root.
+ * @sb_get_mnt_opts:
+ *  Get the security relevant mount options used for a superblock
+ *  @sb the superblock to get security mount options from
+ *  @mount_options array for pointers to mount options
+ *  @mount_flags array of ints specifying what each mount options is
+ *  @num_opts number of options in the arrays
+ * @sb_set_mnt_opts:
+ *  Set the security relevant mount options used for a superblock
+ *  @sb the superblock to set security mount options for
+ *  @mount_options array for pointers to mount options
+ *  @mount_flags array of ints specifying what each mount options is
+ *  @num_opts number of options in the arrays
+ * @sb_clone_mnt_opts:
+ * Copy all security options from a given superblock to another
+ * @oldsb old superblock which contain information to clone
+ * @newsb new superblock which needs filled in
  *
  * Security hooks for inode operations.
  *
@@ -1242,6 +1264,13 @@ struct security_operations {
 struct nameidata * new_nd);
void (*sb_post_pivotroot) (struct nameidata * old_nd,
   struct nameidata * new_nd);
+   int (*sb_get_mnt_opts) (const struct super_block *sb,
+   char ***mount_options, int **flags,
+   int *num_opts);
+   int (*sb_set_mnt_opts) (struct super_block *sb, char **mount_options,
+   int *flags, int num_opts);
+   void (*sb_clone_mnt_opts) (const struct super_block *oldsb,
+  struct super_block *newsb);
 
int (*inode_alloc_security) (struct inode *inode);  
void (*inode_free_security) (struct inode *inode);
@@ -1499,6 +1528,13 @@ void security_sb_post_mountroot(void);
 void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata 
*mountpoint_nd);
 int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata *new_nd);
 void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata 
*new_nd);
+int security_sb_get_mnt_opts(const struct super_block *sb, char 
***mount_options,
+int **flags, int *num_opts);
+int security_sb_set_mnt_opts(struct super_block *sb, char **mount_options,
+int *flags, int num_opts);
+void security_sb_clone_mnt_opts(const struct super_blo

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

2007-11-09 Thread Casey Schaufler

--- 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?

There are already places in the networking and audit code where
a secid is gotten and saved for the sole purpose of getting a secctx
at some later time. My favorite example:

> static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
> {
> char *secdata;
> u32 seclen, secid;
> int err;

In the Smack case what's in skb is the secctx.

> err = security_socket_getpeersec_dgram(NULL, skb, &secid);
> if (err)
> return;

Smack pulls the secctx off the packet and finds a secid for it.

> err = security_secid_to_secctx(secid, &secdata, &seclen);
> if (err)
> return;

Just so that it can turn around and look up the secctx it had in the
first place.

> put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata);
> security_release_secctx(secdata, seclen);

Fortunatly, this is no-op.

> }

I expect that the purpose of the proposed secctx_to_secid() is to
make it easier to implement more of these cases, where the only
reason to do the conversion is to have something to convert back
later. With SELinux as the only consumer of the LSM, and with the
SELinux secid mindset I suppose this could make sense. It would
also be perfectly reasonable if there was anything to do with a
secid except convert it to a secctx, but there isn't.

There. I got the righteous indignation off my chest. I say to
go ahead with adding this to the LSM because I need it to for
dealing with the aformentioned audit code, which I have looked
into fixing to use secctx instead of secid, and determined that
there are a couple cases where you end up with the secid in any
case.

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


Casey Schaufler
[EMAIL PROTECTED]
-
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

[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 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 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 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 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 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 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 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 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 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


Re: [PATCH -v3] SELinux: Add get, set, and cloning of superblock security information

2007-11-09 Thread Eric Paris

On Fri, 2007-11-09 at 08:29 -0800, Casey Schaufler wrote:
> --- Stephen Smalley <[EMAIL PROTECTED]> wrote:
> 
> > On Thu, 2007-11-08 at 16:37 -0500, Eric Paris wrote:
> > > Adds security_get_sb_mnt_opts, security_set_sb_mnt_opts, and
> > > security_clont_sb_mnt_opts to the LSM and to SELinux.  This will allow
> > > filesystems to directly own and control all of their mount options if
> > > they so choose.
> > > 
> > > Signed-off-by: Eric Paris <[EMAIL PROTECTED]>
> > 
> > Acked-by:  Stephen D. Smalley <[EMAIL PROTECTED]>
> 
> Shouldn't this get cross posted to the LSM list?

Yes, I was reminded of that yesterday and will do so today.
>  
> > > 
> > > ---
> > > 
> > >  include/linux/security.h  |   36 ++
> > >  security/dummy.c  |   26 ++
> > >  security/security.c   |   20 +
> > >  security/selinux/hooks.c  |  749
> > -
> > >  security/selinux/include/objsec.h |1 +
> > >  5 files changed, 578 insertions(+), 254 deletions(-)
> > > 
> > > diff --git a/include/linux/security.h b/include/linux/security.h
> > > index ac05083..dcbb792 100644
> > > --- a/include/linux/security.h
> > > +++ b/include/linux/security.h
> > > @@ -34,6 +34,12 @@
> > >  #include 
> > >  #include 
> > >  
> > > +/* only a char in selinux superblock security struct flags */
> > > +#define FSCONTEXT_MNT0x01
> > > +#define CONTEXT_MNT  0x02
> > > +#define ROOTCONTEXT_MNT  0x04
> > > +#define DEFCONTEXT_MNT   0x08
> > > +
> > >  /*
> > >   * Bounding set
> > >   */
> > > @@ -261,6 +267,22 @@ struct request_sock;
> > >   *   Update module state after a successful pivot.
> > >   *   @old_nd contains the nameidata structure for the old root.
> > >   *  @new_nd contains the nameidata structure for the new root.
> > > + * @sb_get_mnt_opts:
> > > + *  Get the security relevant mount options used for a superblock
> > > + *  @sb the superblock to get security mount options from
> > > + *  @mount_options array for pointers to mount options
> > > + *  @mount_flags array of ints specifying what each mount options is
> > > + *  @num_opts number of options in the arrays
> > > + * @sb_set_mnt_opts:
> > > + *  Set the security relevant mount options used for a superblock
> > > + *  @sb the superblock to set security mount options for
> > > + *  @mount_options array for pointers to mount options
> > > + *  @mount_flags array of ints specifying what each mount options is
> > > + *  @num_opts number of options in the arrays
> > > + * @sb_clone_mnt_opts:
> > > + *   Copy all security options from a given superblock to another
> > > + *   @oldsb old superblock which contain information to clone
> > > + *   @newsb new superblock which needs filled in
> > >   *
> > >   * Security hooks for inode operations.
> > >   *
> > > @@ -1242,6 +1264,13 @@ struct security_operations {
> > >struct nameidata * new_nd);
> > >   void (*sb_post_pivotroot) (struct nameidata * old_nd,
> > >  struct nameidata * new_nd);
> > > + int (*sb_get_mnt_opts) (const struct super_block *sb,
> > > + char ***mount_options, int **flags,
> > > + int *num_opts);
> > > + int (*sb_set_mnt_opts) (struct super_block *sb, char **mount_options,
> > > + int *flags, int num_opts);
> > > + void (*sb_clone_mnt_opts) (const struct super_block *oldsb,
> > > +struct super_block *newsb);
> > >  
> > >   int (*inode_alloc_security) (struct inode *inode);  
> > >   void (*inode_free_security) (struct inode *inode);
> > > @@ -1499,6 +1528,13 @@ void security_sb_post_mountroot(void);
> > >  void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata
> > *mountpoint_nd);
> > >  int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata
> > *new_nd);
> > >  void security_sb_post_pivotroot(struct nameidata *old_nd, struct 
> > > nameidata
> > *new_nd);
> > > +int security_sb_get_mnt_opts(const struct super_block *sb, char
> > ***mount_options,
> > > +  int **flags, int *num_opts);
> > > +int security_sb_set_mnt_opts(struct super_block *sb, char 
> > > **mount_options,
> > > +  int *flags, int num_opts);
> > > +void security_sb_clone_mnt_opts(const struct super_block *oldsb,
> > > + struct super_block *newsb);
> > > +
> > >  int security_inode_alloc(struct inode *inode);
> > >  void security_inode_free(struct inode *inode);
> > >  int security_inode_init_security(struct inode *inode, struct inode *dir,
> > > diff --git a/security/dummy.c b/security/dummy.c
> > > index 6d895ad..22d9663 100644
> > > --- a/security/dummy.c
> > > +++ b/security/dummy.c
> > > @@ -245,6 +245,29 @@ static void dummy_sb_post_pivotroot (struct nameidata
> > *old_nd, struct nameidata
> > >   return;
> > >  }
> > >  
> > > +

Re: Missing security_file_permission() check from sys_splice()

2007-11-09 Thread Stephen Smalley
On Thu, 2007-11-08 at 23:20 -0600, Lin Tan wrote:
> Seems that an unauthorized user can send file through sockets due to  
> the following missing check errors.
> 
> There is not security_file_permission() check from sys_splice(),  
> which can invoke sock_sendpage(). The call chain is as follows.
> sys_splice -> do_splice -> do_splice_from -> generic_splice_sendpage  
> (via function pointer out->f_op->splice_write, which is set up in net/ 
> socket.c) -> pipe_to_sendpage -> sock_sendpage ( via file->f_op- 
>  >sendpage, in net/socket.c)
> 
> I believe sock_sendpage() needs to be protected by  
> security_file_permission() for two reasons. First,  in the following  
> path it is protected.
> 
> sys_sendfile -> do_sendfile -> file_send_actor -> sock_sendpage
> 
> Second, if it is not protected, then unauthorized user can send file  
> through sockets.  Adding the check in do_splice_from() should solve  
> the problem.
> 
> Similar problems exit in do_splice_to() and probably in sys_vmspliace 
> () too.

What kernel version are you looking at?

Current kernel has security_file_permission() calls in do_splice_from()
and do_splice_to().

BTW, one might argue that for the socket case, these should be mediated
by the socket hooks, which does happen if the sendpage operation falls
back to sock_no_sendpage() -> kernel_sendmsg() -> sock_sendmsg().  But
that doesn't happen when the protocol implementation implements its own
sendpage operations, of course.  So possibly there should be a socket
security hook call in sock_sendpage().

-- 
Stephen Smalley
National Security Agency

-
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 -v3] SELinux: Add get, set, and cloning of superblock security information

2007-11-09 Thread Casey Schaufler

--- Stephen Smalley <[EMAIL PROTECTED]> wrote:

> On Thu, 2007-11-08 at 16:37 -0500, Eric Paris wrote:
> > Adds security_get_sb_mnt_opts, security_set_sb_mnt_opts, and
> > security_clont_sb_mnt_opts to the LSM and to SELinux.  This will allow
> > filesystems to directly own and control all of their mount options if
> > they so choose.
> > 
> > Signed-off-by: Eric Paris <[EMAIL PROTECTED]>
> 
> Acked-by:  Stephen D. Smalley <[EMAIL PROTECTED]>

Shouldn't this get cross posted to the LSM list?
 
> > 
> > ---
> > 
> >  include/linux/security.h  |   36 ++
> >  security/dummy.c  |   26 ++
> >  security/security.c   |   20 +
> >  security/selinux/hooks.c  |  749
> -
> >  security/selinux/include/objsec.h |1 +
> >  5 files changed, 578 insertions(+), 254 deletions(-)
> > 
> > diff --git a/include/linux/security.h b/include/linux/security.h
> > index ac05083..dcbb792 100644
> > --- a/include/linux/security.h
> > +++ b/include/linux/security.h
> > @@ -34,6 +34,12 @@
> >  #include 
> >  #include 
> >  
> > +/* only a char in selinux superblock security struct flags */
> > +#define FSCONTEXT_MNT  0x01
> > +#define CONTEXT_MNT0x02
> > +#define ROOTCONTEXT_MNT0x04
> > +#define DEFCONTEXT_MNT 0x08
> > +
> >  /*
> >   * Bounding set
> >   */
> > @@ -261,6 +267,22 @@ struct request_sock;
> >   * Update module state after a successful pivot.
> >   * @old_nd contains the nameidata structure for the old root.
> >   *  @new_nd contains the nameidata structure for the new root.
> > + * @sb_get_mnt_opts:
> > + *  Get the security relevant mount options used for a superblock
> > + *  @sb the superblock to get security mount options from
> > + *  @mount_options array for pointers to mount options
> > + *  @mount_flags array of ints specifying what each mount options is
> > + *  @num_opts number of options in the arrays
> > + * @sb_set_mnt_opts:
> > + *  Set the security relevant mount options used for a superblock
> > + *  @sb the superblock to set security mount options for
> > + *  @mount_options array for pointers to mount options
> > + *  @mount_flags array of ints specifying what each mount options is
> > + *  @num_opts number of options in the arrays
> > + * @sb_clone_mnt_opts:
> > + * Copy all security options from a given superblock to another
> > + * @oldsb old superblock which contain information to clone
> > + * @newsb new superblock which needs filled in
> >   *
> >   * Security hooks for inode operations.
> >   *
> > @@ -1242,6 +1264,13 @@ struct security_operations {
> >  struct nameidata * new_nd);
> > void (*sb_post_pivotroot) (struct nameidata * old_nd,
> >struct nameidata * new_nd);
> > +   int (*sb_get_mnt_opts) (const struct super_block *sb,
> > +   char ***mount_options, int **flags,
> > +   int *num_opts);
> > +   int (*sb_set_mnt_opts) (struct super_block *sb, char **mount_options,
> > +   int *flags, int num_opts);
> > +   void (*sb_clone_mnt_opts) (const struct super_block *oldsb,
> > +  struct super_block *newsb);
> >  
> > int (*inode_alloc_security) (struct inode *inode);  
> > void (*inode_free_security) (struct inode *inode);
> > @@ -1499,6 +1528,13 @@ void security_sb_post_mountroot(void);
> >  void security_sb_post_addmount(struct vfsmount *mnt, struct nameidata
> *mountpoint_nd);
> >  int security_sb_pivotroot(struct nameidata *old_nd, struct nameidata
> *new_nd);
> >  void security_sb_post_pivotroot(struct nameidata *old_nd, struct nameidata
> *new_nd);
> > +int security_sb_get_mnt_opts(const struct super_block *sb, char
> ***mount_options,
> > +int **flags, int *num_opts);
> > +int security_sb_set_mnt_opts(struct super_block *sb, char **mount_options,
> > +int *flags, int num_opts);
> > +void security_sb_clone_mnt_opts(const struct super_block *oldsb,
> > +   struct super_block *newsb);
> > +
> >  int security_inode_alloc(struct inode *inode);
> >  void security_inode_free(struct inode *inode);
> >  int security_inode_init_security(struct inode *inode, struct inode *dir,
> > diff --git a/security/dummy.c b/security/dummy.c
> > index 6d895ad..22d9663 100644
> > --- a/security/dummy.c
> > +++ b/security/dummy.c
> > @@ -245,6 +245,29 @@ static void dummy_sb_post_pivotroot (struct nameidata
> *old_nd, struct nameidata
> > return;
> >  }
> >  
> > +static int dummy_sb_get_mnt_opts(const struct super_block *sb, char
> ***mount_options,
> > +int **flags, int *num_opts)
> > +{
> > +   *mount_options = NULL;
> > +   *flags = NULL;
> > +   *num_opts = 0;
> > +   return 0;
> > +}
> > +
> > +static int dummy_sb_set_mnt_opts(struct super_block *sb, char
> **mo