Re: [PATCH 2/2] Version 11 (2.6.24-rc2) Smack: Simplified Mandatory Access Control Kernel
[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
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
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
-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
-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
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
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
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
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?
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
--- 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
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
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
--- 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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
--- 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