Re: [RFC PATCH] selinux: add a fallback to defcontext for native labeling
On Fri, Sep 21, 2018 at 10:39 AM Stephen Smalley wrote: > On 09/20/2018 06:59 PM, Taras Kondratiuk wrote: > > Quoting Stephen Smalley (2018-09-20 07:49:12) > >> On 09/19/2018 10:41 PM, Taras Kondratiuk wrote: > >>> Quoting Stephen Smalley (2018-09-19 12:00:33) > On 09/19/2018 12:52 PM, Taras Kondratiuk wrote: ... > > IMO it would be more consistent if defcontext cover all "unlabeled" > > groups. It seems unlikely to me that somebody who currently uses > > defcontext can somehow rely on mapping invalid labels to unlabeled > > instead of default context. > > Yes, and that seems more consistent with the current documentation in > the mount man page for defcontext=. > > I'd be inclined to change selinux_inode_notifysecctx() to call > security_context_to_sid_default() directly instead of using > selinux_inode_setsecurity() and change security_context_to_sid_core() > and sidtab_search_core() as suggested above to save and use the def_sid > instead of SECINITSID_UNLABELED always (initializing the context def_sid > to SECINITSID_UNLABELED as the default). selinux_inode_setsecurity() we > should leave unchanged, or if we change it at all, it should be more > like the handling in selinux_inode_setxattr(). The notifysecctx hook is > invoked by the filesystem to notify the security module of the file's > existing security context, so in that case we always want the _default > behavior, whereas the setsecurity hook is invoked by the vfs or the > filesystem to set the security context of a file to a new value, so in > that case we would only use the _force interface if the caller had > CAP_MAC_ADMIN. > > Paul, what say you? NB This would be a user-visible behavior change for > mounts specifying defcontext= on xattr filesystems; files with invalid > contexts will then show up with the defcontext value instead of the > unlabeled context. If that's too risky, then we'd need a flag or > something to security_context_to_sid_default() to distinguish the > behaviors and only set it when called from selinux_inode_notifysecctx(). Visible changes like this are always worrisome, even though I think it is safe to assume that the defcontext option is not widely used. I'd feel much better if this change was opt-in. Which brings about it's own problems. We have the policy capability functionality, but that is likely a poor fit for this as the policy capabilities are usually controlled by the Linux distribution while the mount options are set by the system's administrator when the filesystem is mounted. We could add a toggle somewhere in selinuxfs, but I really dislike that idea, and would prefer to find a different solution if possible. I'm not sure how much flak we would get for introducing a new mount option, but perhaps that is the best way to handle this: defcontext would continue to behave as it does now, but new option X would behave as mentioned in this thread. Thoughts? -- paul moore www.paul-moore.com ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: autorelabel loops in system executed 'semodule -d unconfined'
Hi, SELinux. I captured a picture saying this. rm: cannot remove '/.autorelabel' : Permission denied /.autorelabel could not be removed, so going into the loop, I guess. How can I autorelabel properly even if I delete unconfined module? Thanks. 2018年9月25日(火) 6:55 Shintaro Fujiwara : > > Hello, SELinux. > > I was playing with my F28 latest with 'semodle -d unconfined'. > I executed this and relabeling starts even after finished relebeling > and looks like going into the loop. > # touch /.autorelabel > # shtudown -r now > > I have attached a picure. > > Thanks. -- Help analyzing sar file https://github.com/intrajp/sar-analyzer LFS Scripts will make Linux From Scratch easy https://github.com/intrajp/LFS-scripts-systemd SHIRASAGI-hardening Project https://github.com/intrajp/shirasagi-hardening Linux Distribution Project http://sourceforge.net/projects/pinkrabbitlinux/ Introducing hardrock and heavymetal http://heavymetalhardrock.no-ip.info/ Open Source Software to manage SELinux at ease http://sourceforge.net/projects/segatex/ Help SELinux administration https://github.com/intrajp/segatex-ng network-magic ( Useful tool for network-administrators ) https://github.com/intrajp/network-magic CMS(with PHP & PostgreSQL) http://sourceforge.net/projects/webon/ https://github.com/intrajp/irforum_jp ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
autorelabel loops in system executed 'semodule -d unconfined'
Hello, SELinux. I was playing with my F28 latest with 'semodle -d unconfined'. I executed this and relabeling starts even after finished relebeling and looks like going into the loop. # touch /.autorelabel # shtudown -r now I have attached a picure. Thanks. ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH 2/2] secilc: better error handling
ack On Mon, Sep 24, 2018 at 11:12 AM Nick Kralevich via Selinux < selinux@tycho.nsa.gov> wrote: > Fix a situation where the secilc command line tool could return success > even though the compilation failed. > > $ secilc /dev/null -o /dev/null -f /dev/null > Failure reading file: /dev/null > $ echo $? > 0 > > Signed-off-by: Nick Kralevich > --- > secilc/secilc.c | 4 > 1 file changed, 4 insertions(+) > > diff --git a/secilc/secilc.c b/secilc/secilc.c > index e1347205..ad6862ba 100644 > --- a/secilc/secilc.c > +++ b/secilc/secilc.c > @@ -257,6 +257,7 @@ int main(int argc, char *argv[]) > rc = stat(argv[i], ); > if (rc == -1) { > fprintf(stderr, "Could not stat file: %s\n", > argv[i]); > + rc = SEPOL_ERR; > goto exit; > } > file_size = filedata.st_size; > @@ -265,6 +266,7 @@ int main(int argc, char *argv[]) > rc = fread(buffer, file_size, 1, file); > if (rc != 1) { > fprintf(stderr, "Failure reading file: %s\n", > argv[i]); > + rc = SEPOL_ERR; > goto exit; > } > fclose(file); > @@ -345,11 +347,13 @@ int main(int argc, char *argv[]) > > if (file_contexts == NULL) { > fprintf(stderr, "Failed to open file_contexts file\n"); > + rc = SEPOL_ERR; > goto exit; > } > > if (fwrite(fc_buf, sizeof(char), fc_size, file_contexts) != > fc_size) { > fprintf(stderr, "Failed to write file_contexts file\n"); > + rc = SEPOL_ERR; > goto exit; > } > > -- > 2.19.0.444.g18242da7ef-goog > > ___ > Selinux mailing list > Selinux@tycho.nsa.gov > To unsubscribe, send email to selinux-le...@tycho.nsa.gov. > To get help, send an email containing "help" to > selinux-requ...@tycho.nsa.gov. > ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH 1/2] whitespace and spelling cleanup
ack On Mon, Sep 24, 2018 at 11:12 AM Nick Kralevich via Selinux < selinux@tycho.nsa.gov> wrote: > Signed-off-by: Nick Kralevich > --- > libsepol/include/sepol/errcodes.h | 2 +- > secilc/secilc.c | 14 +++--- > 2 files changed, 8 insertions(+), 8 deletions(-) > > diff --git a/libsepol/include/sepol/errcodes.h > b/libsepol/include/sepol/errcodes.h > index 0136564a..6e9ff316 100644 > --- a/libsepol/include/sepol/errcodes.h > +++ b/libsepol/include/sepol/errcodes.h > @@ -12,7 +12,7 @@ extern "C" { > #define SEPOL_OK 0 > > /* These first error codes are defined for compatibility with > - * previous version of libsepol. In the future, custome error > + * previous version of libsepol. In the future, custom error > * codes that don't map to system error codes should be defined > * outside of the range of system error codes. > */ > diff --git a/secilc/secilc.c b/secilc/secilc.c > index 0be6975b..e1347205 100644 > --- a/secilc/secilc.c > +++ b/secilc/secilc.c > @@ -1,16 +1,16 @@ > /* > * Copyright 2011 Tresys Technology, LLC. All rights reserved. > - * > + * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions are > met: > - * > + * > *1. Redistributions of source code must retain the above copyright > notice, > * this list of conditions and the following disclaimer. > - * > + * > *2. Redistributions in binary form must reproduce the above > copyright notice, > * this list of conditions and the following disclaimer in the > documentation > * and/or other materials provided with the distribution. > - * > + * > * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY > EXPRESS > * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED > WARRANTIES OF > * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. > IN NO > @@ -21,7 +21,7 @@ > * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING > NEGLIGENCE > * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN > IF > * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > - * > + * > * The views and conclusions contained in the software and documentation > are those > * of the authors and should not be interpreted as representing official > policies, > * either expressed or implied, of Tresys Technology, LLC. > @@ -259,7 +259,7 @@ int main(int argc, char *argv[]) > fprintf(stderr, "Could not stat file: %s\n", > argv[i]); > goto exit; > } > - file_size = filedata.st_size; > + file_size = filedata.st_size; > > buffer = malloc(file_size); > rc = fread(buffer, file_size, 1, file); > @@ -347,7 +347,7 @@ int main(int argc, char *argv[]) > fprintf(stderr, "Failed to open file_contexts file\n"); > goto exit; > } > - > + > if (fwrite(fc_buf, sizeof(char), fc_size, file_contexts) != > fc_size) { > fprintf(stderr, "Failed to write file_contexts file\n"); > goto exit; > -- > 2.19.0.444.g18242da7ef-goog > > ___ > Selinux mailing list > Selinux@tycho.nsa.gov > To unsubscribe, send email to selinux-le...@tycho.nsa.gov. > To get help, send an email containing "help" to > selinux-requ...@tycho.nsa.gov. > ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: file context not being set on el7
Ted Toth writes: On Fri, Sep 21, 2018 at 7:21 AM Ted Toth wrote: On Fri, Sep 21, 2018 at 3:58 AM Petr Lautrbach wrote: Ted Toth writes: > I have something very much like the following in an fc file: > /usr/lib64/python2\.(6|7)/site-packages/xyz/paste -- > gen_context(system_u:object_r:jxyz_exec_t,s0) > > and I use the same file on el6 and el7. On el6 the file is > labeled as > specified in the python2.6 directory. However on el7 where > the > file gets > installed into python2.7 the file is not labeled correctly. > On > el7 > `semanage fcontext -l | grep xyz` shows the file context > expected but > `matchpathcon /usr/lib64/python2.7/site-packages/xyz/paste` > does > not return > the expected context and `restorecon -RFv > /usr/lib64/python2.7/site-packages/xyz` has no affect. The > type > xyz_exec_t > exists on both systems. It's probably something stupid I'm > doing > but I'm > just not seeing it. Has anyone else experienced similar > issues? > There's equivalency rule /usr/lib64 -> /usr/lib on el7: # semanage fcontext -a -t tmp_t '/usr/lib64/python2\.(6|7)/site-packages/xyz/paste' ValueError: File spec /usr/lib64/python2\.(6|7)/site-packages/xyz/paste conflicts with equivalency rule '/usr/lib64 /usr/lib'; Try adding '/usr/lib/python2\.(6|7)/site-packages/xyz/paste' instead # semanage fcontext -a -t tmp_t '/usr/lib/python2\.(6|7)/site-packages/xyz/paste' # matchpathcon /usr/lib64/python2.7/site-packages/xyz/paste /usr/lib64/python2.7/site-packages/xyz/paste system_u:object_r:tmp_t:s0 Petr Thanks, where is this equivalency rule defined/documented? You can see them at the end of 'semanage fcontext -l' output: SELinux Distribution fcontext Equivalence /usr/local/lib64 = /usr/lib /etc/systemd/system = /usr/lib/systemd/system /run/systemd/system = /usr/lib/systemd/system /run/systemd/generator = /usr/lib/systemd/system /var/home = /home /sbin = /usr/sbin /var/roothome = /root /usr/lib64 = /usr/lib /var/lib/xguest/home = /home /var/named/chroot/lib64 = /usr/lib /var/named/chroot/usr/lib64 = /usr/lib /run = /var/run /usr/local/lib32 = /usr/lib /lib64 = /usr/lib /lib = /usr/lib /run/lock = /var/lock /usr/lib(64)?/python... doesn't work either how can I make it backward compatible? '/usr/lib(64)?/python2\.(6|7)/site-packages/xyz/paste' works for me on both el6 and el7. Petr ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH 1/2] whitespace and spelling cleanup
Signed-off-by: Nick Kralevich --- libsepol/include/sepol/errcodes.h | 2 +- secilc/secilc.c | 14 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/libsepol/include/sepol/errcodes.h b/libsepol/include/sepol/errcodes.h index 0136564a..6e9ff316 100644 --- a/libsepol/include/sepol/errcodes.h +++ b/libsepol/include/sepol/errcodes.h @@ -12,7 +12,7 @@ extern "C" { #define SEPOL_OK 0 /* These first error codes are defined for compatibility with - * previous version of libsepol. In the future, custome error + * previous version of libsepol. In the future, custom error * codes that don't map to system error codes should be defined * outside of the range of system error codes. */ diff --git a/secilc/secilc.c b/secilc/secilc.c index 0be6975b..e1347205 100644 --- a/secilc/secilc.c +++ b/secilc/secilc.c @@ -1,16 +1,16 @@ /* * Copyright 2011 Tresys Technology, LLC. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: - * + * *1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. - * + * *2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * + * * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO @@ -21,7 +21,7 @@ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * The views and conclusions contained in the software and documentation are those * of the authors and should not be interpreted as representing official policies, * either expressed or implied, of Tresys Technology, LLC. @@ -259,7 +259,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "Could not stat file: %s\n", argv[i]); goto exit; } - file_size = filedata.st_size; + file_size = filedata.st_size; buffer = malloc(file_size); rc = fread(buffer, file_size, 1, file); @@ -347,7 +347,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "Failed to open file_contexts file\n"); goto exit; } - + if (fwrite(fc_buf, sizeof(char), fc_size, file_contexts) != fc_size) { fprintf(stderr, "Failed to write file_contexts file\n"); goto exit; -- 2.19.0.444.g18242da7ef-goog ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 00/19] LSM: Module stacking for SARA and Landlock
On 2018/09/25 2:16, Casey Schaufler wrote: >> Not all of LKM-based LSMs use security blobs. And some of LKM-based LSMs >> might use security blobs for only a few objects. For example, AKARI uses >> inode security blob for remembering whether source address/port of an >> accept()ed socket was already checked, only during accept() operation and >> first socket operation on the accept()ed socket. Thus, there is no need >> to waste memory by assigning blobs for all inode objects. > > The first question is why use an inode blob? Shouldn't you > be using a socket blob for this socket based information? Indeed. AKARI can as well use security_sk_free() using address of "struct sock" as a key. > > If you only want information part of the time you can declare > a pointer sized blob and manage what hangs off that as you will. > I personally think that the added complexity of conditional > blob management is more pain than it's worth, but if you want > a really big blob, but only on occasion, I could see doing it. LKM based LSMs are too late for updating blob_sizes.* fields. Even if they could, they after all have to somehow check whether corresponding init hook was called. That's checking for NULL. >> @@ -1202,11 +1183,11 @@ void security_file_free(struct file *file) { void *blob; + call_void_hook(file_free_security, file); + if (!lsm_file_cache) return; - call_void_hook(file_free_security, file); - >>> Why does this make sense? If the lsm_file_cache isn't >>> initialized you can't have allocated any file blobs, >>> no module can have initialized a file blob, hence there >>> can be nothing for the module to do. >>> >> For modules (not limited to LKM-based LSMs) which want to use >> file blobs for only a few objects and avoid wasting memory by >> allocating file blobs to all file objects. >> >> Infrastructure based blob management fits well for LSM modules >> which want to assign blobs to all objects (like SELinux). But >> forcing infrastructure based blob management can become a huge >> waste of memory for LSM modules which want to assign blobs to >> only a few objects. Unconditionally calling file_free_security >> hook (as with other hooks) preserves a room for allowing the >> latter type of LSM modules without using infrastructure based >> blob management. > > There is a hypothetical issue here, but that would require abuse > of the infrastructure. Having a file_free_security hook that doesn't > free a security blob allocated by file_alloc_security may coincidentaly > be useful, but that's not the intent of the hook. > The free hook might be used for freeing resources which were not allocated by alloc hook. Yama is using task_free hook without task_alloc hook. Someone might want to use file_free hook without file_alloc hook. ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 00/19] LSM: Module stacking for SARA and Landlock
On 2018/09/25 1:15, Casey Schaufler wrote: Since all free hooks are called when one of init hooks failed, each free hook needs to check whether init hook was called. An example is inode_free_security() in security/selinux/hooks.c (but not addressed in this patch). >>> >>> I *think* that selinux_inode_free_security() is safe in this >>> case because the blob will be zeroed, hence isec->list will >>> be NULL. >> >> That's not safe - look more closely at what list_empty_careful() tests, and >> then think about what happens when list_del_init() gets called on that >> isec->list. selinux_inode_free_security() presumes that >> selinux_inode_alloc_security() has been called already. If you are breaking >> that assumption, you have to fix it. > > Yup. I misread the macro my first time around. Easy fix. Oh, I didn't notice that it is doing !list_empty_careful() than list_empty_careful(). Unsafe indeed. But easy to fix. > >> Is there a reason you can't make inode_alloc_security() return void since >> you moved the allocation to the framework? > > No reason with any of the existing modules, But I could see someone > doing unnatural things during allocation that might result in a > failure. Currently upstreamed LSM modules and AKARI would be OK. But I can't guarantee it for future / not-yet-upstreamed LSM modules. ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 00/19] LSM: Module stacking for SARA and Landlock
On 9/23/2018 6:53 PM, Tetsuo Handa wrote: > On 2018/09/24 2:09, Casey Schaufler wrote: >>> Since all free hooks are called when one of init hooks failed, each >>> free hook needs to check whether init hook was called. An example is >>> inode_free_security() in security/selinux/hooks.c (but not addressed in >>> this patch). >> I *think* that selinux_inode_free_security() is safe in this >> case because the blob will be zeroed, hence isec->list will >> be NULL. >> > OK. > >>> This patchset might fatally prevent LKM-based LSM modules, for LKM-based >>> LSMs cannot count on lsm_*_alloc() because size for lsm_*_alloc() cannot >>> be updated upon loading LKM-based LSMs. >> LKM based security modules will require dynamically sized blobs. >> These can be added to the scheme used here. Each blob would get a >> header identifying the modules for which it contains data. When an >> LKM is registered if has to declare it's blob space requirements >> and gets back the offsets. All alloc operations have to put their >> marks in the header. All LKM blob users have to check that the blob >> they are looking at has the required data. >> >> module_cred(struct cred *cred) { >> return cred->security + module_blob_sizes.lbs_cred; >> } >> >> becomes >> >> module_cred(struct cred *cred) { >> if (blob_includes(module_id)) >> return cred->security + module_blob_sizes.lbs_cred; >> return NULL; >> } >> >> and the calling code needs to accept a NULL return. > Not all of LKM-based LSMs use security blobs. And some of LKM-based LSMs > might use security blobs for only a few objects. For example, AKARI uses > inode security blob for remembering whether source address/port of an > accept()ed socket was already checked, only during accept() operation and > first socket operation on the accept()ed socket. Thus, there is no need > to waste memory by assigning blobs for all inode objects. The first question is why use an inode blob? Shouldn't you be using a socket blob for this socket based information? If you only want information part of the time you can declare a pointer sized blob and manage what hangs off that as you will. I personally think that the added complexity of conditional blob management is more pain than it's worth, but if you want a really big blob, but only on occasion, I could see doing it. >> Blobs can never get smaller because readjusting the offsets >> isn't going to work, so unloading an LKM security module isn't >> going to be as complete as you might like. There may be a way >> around this if you unload all the LKM modules, but that's a >> special case and there may be dragon lurking in the mist. > If LKM-based LSMs who want to use security blobs have to check for > NULL return, they might choose "not using infrastructure managed > security blobs" and "using locally hashed blobs associated with > object's address" (like AKARI does). I can't see how a check for NULL could possibly be a bigger hassle than doing your own locally hashed blobs. > >>> If security_file_free() is called >>> regardless of whether lsm_file_cache is defined, LKM-based LSMs can be >>> loaded using current behavior (apart from the fact that legitimate >>> interface for appending to security_hook_heads is currently missing). >>> How do you plan to handle LKM-based LSMs? >> My position all along has been that I don't plan to handle LKM >> based LSMs, but that I won't do anything to prevent someone else >> from adding them later. I believe that I've done that. Several >> designs, including a separate list for dynamically loaded modules >> have been proposed. I think some of those would work. > Though AKARI is not using security_file_free(), some of LKM-based LSMs > might want to use it. If file_free_security hook is called unconditionally, > such LKM-based LSMs can be registered/unregistered, without worrying about > inability to shrink sizes for blobs. The infrastructure wouldn't call unregistered hooks, so any module that allocates additional memory attached to a blob is going to have to deal with freeing that when it unregisters. Aside from that unregistration should be a (not so) small matter of locking. > >>> @@ -1202,11 +1183,11 @@ void security_file_free(struct file *file) >>> { >>> void *blob; >>> >>> + call_void_hook(file_free_security, file); >>> + >>> if (!lsm_file_cache) >>> return; >>> >>> - call_void_hook(file_free_security, file); >>> - >> Why does this make sense? If the lsm_file_cache isn't >> initialized you can't have allocated any file blobs, >> no module can have initialized a file blob, hence there >> can be nothing for the module to do. >> > For modules (not limited to LKM-based LSMs) which want to use > file blobs for only a few objects and avoid wasting memory by > allocating file blobs to all file objects. > > Infrastructure based blob management fits well for LSM modules > which want to assign blobs to all objects (like SELinux). But >
Re: [PATCH v4 00/19] LSM: Module stacking for SARA and Landlock
On 9/24/2018 8:01 AM, Stephen Smalley wrote: > On 09/23/2018 01:09 PM, Casey Schaufler wrote: >> On 9/23/2018 8:59 AM, Tetsuo Handa wrote: >>> On 2018/09/23 11:43, Kees Cook wrote: >> I'm excited about getting this landed! > Soon. Real soon. I hope. I would very much like for > someone from the SELinux camp to chime in, especially on > the selinux_is_enabled() removal. Agreed. >>> This patchset from Casey lands before the patchset from Kees, doesn't it? >> >> That is up for negotiation. We may end up combining them. >> >>> OK, a few comments (if I didn't overlook something). >>> >>> lsm_early_cred()/lsm_early_task() are called from only __init functions. >> >> True. >> >>> lsm_cred_alloc()/lsm_file_alloc() are called from only >>> security/security.c . >> >> Also true. >> >>> lsm_early_inode() should be avoided because it is not appropriate to >>> call panic() when lsm_early_inode() is called after __init phase. >> >> You're correct. In fact, lsm_early_inode() isn't needed at all >> until multiple inode using modules are supported. >> >>> Since all free hooks are called when one of init hooks failed, each >>> free hook needs to check whether init hook was called. An example is >>> inode_free_security() in security/selinux/hooks.c (but not addressed in >>> this patch). >> >> I *think* that selinux_inode_free_security() is safe in this >> case because the blob will be zeroed, hence isec->list will >> be NULL. > > That's not safe - look more closely at what list_empty_careful() tests, and > then think about what happens when list_del_init() gets called on that > isec->list. selinux_inode_free_security() presumes that > selinux_inode_alloc_security() has been called already. If you are breaking > that assumption, you have to fix it. Yup. I misread the macro my first time around. Easy fix. > Is there a reason you can't make inode_alloc_security() return void since you > moved the allocation to the framework? No reason with any of the existing modules, But I could see someone doing unnatural things during allocation that might result in a failure. > Unfortunate that inode_init_security name is already in use for another > purpose since essentially you have reduced these hooks to initialization only. I considered that but decided that it makes more sense for the module hook names to match the infrastructure name. Having security_inode_alloc() call selinux_inode_setup_security() starts to get confusing. ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 00/19] LSM: Module stacking for SARA and Landlock
On 09/23/2018 01:09 PM, Casey Schaufler wrote: On 9/23/2018 8:59 AM, Tetsuo Handa wrote: On 2018/09/23 11:43, Kees Cook wrote: I'm excited about getting this landed! Soon. Real soon. I hope. I would very much like for someone from the SELinux camp to chime in, especially on the selinux_is_enabled() removal. Agreed. This patchset from Casey lands before the patchset from Kees, doesn't it? That is up for negotiation. We may end up combining them. OK, a few comments (if I didn't overlook something). lsm_early_cred()/lsm_early_task() are called from only __init functions. True. lsm_cred_alloc()/lsm_file_alloc() are called from only security/security.c . Also true. lsm_early_inode() should be avoided because it is not appropriate to call panic() when lsm_early_inode() is called after __init phase. You're correct. In fact, lsm_early_inode() isn't needed at all until multiple inode using modules are supported. Since all free hooks are called when one of init hooks failed, each free hook needs to check whether init hook was called. An example is inode_free_security() in security/selinux/hooks.c (but not addressed in this patch). I *think* that selinux_inode_free_security() is safe in this case because the blob will be zeroed, hence isec->list will be NULL. That's not safe - look more closely at what list_empty_careful() tests, and then think about what happens when list_del_init() gets called on that isec->list. selinux_inode_free_security() presumes that selinux_inode_alloc_security() has been called already. If you are breaking that assumption, you have to fix it. Is there a reason you can't make inode_alloc_security() return void since you moved the allocation to the framework? Unfortunate that inode_init_security name is already in use for another purpose since essentially you have reduced these hooks to initialization only. This patchset might fatally prevent LKM-based LSM modules, for LKM-based LSMs cannot count on lsm_*_alloc() because size for lsm_*_alloc() cannot be updated upon loading LKM-based LSMs. LKM based security modules will require dynamically sized blobs. These can be added to the scheme used here. Each blob would get a header identifying the modules for which it contains data. When an LKM is registered if has to declare it's blob space requirements and gets back the offsets. All alloc operations have to put their marks in the header. All LKM blob users have to check that the blob they are looking at has the required data. module_cred(struct cred *cred) { return cred->security + module_blob_sizes.lbs_cred; } becomes module_cred(struct cred *cred) { if (blob_includes(module_id)) return cred->security + module_blob_sizes.lbs_cred; return NULL; } and the calling code needs to accept a NULL return. Blobs can never get smaller because readjusting the offsets isn't going to work, so unloading an LKM security module isn't going to be as complete as you might like. There may be a way around this if you unload all the LKM modules, but that's a special case and there may be dragon lurking in the mist. If security_file_free() is called regardless of whether lsm_file_cache is defined, LKM-based LSMs can be loaded using current behavior (apart from the fact that legitimate interface for appending to security_hook_heads is currently missing). How do you plan to handle LKM-based LSMs? My position all along has been that I don't plan to handle LKM based LSMs, but that I won't do anything to prevent someone else from adding them later. I believe that I've done that. Several designs, including a separate list for dynamically loaded modules have been proposed. I think some of those would work. include/linux/lsm_hooks.h |6 ++ security/security.c| 31 ++- security/smack/smack_lsm.c |8 +++- 3 files changed, 15 insertions(+), 30 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 7e8b32f..8014614 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2095,13 +2095,11 @@ static inline void __init yama_add_hooks(void) { } static inline void loadpin_add_hooks(void) { }; #endif -extern int lsm_cred_alloc(struct cred *cred, gfp_t gfp); extern int lsm_inode_alloc(struct inode *inode); #ifdef CONFIG_SECURITY -void lsm_early_cred(struct cred *cred); -void lsm_early_inode(struct inode *inode); -void lsm_early_task(struct task_struct *task); +void __init lsm_early_cred(struct cred *cred); +void __init lsm_early_task(struct task_struct *task); #endif #endif /* ! __LINUX_LSM_HOOKS_H */ diff --git a/security/security.c b/security/security.c index e7c85060..341e8df 100644 --- a/security/security.c +++ b/security/security.c @@ -267,7 +267,7 @@ int unregister_lsm_notifier(struct notifier_block *nb) * * Returns 0, or -ENOMEM if memory can't be
Re: [PATCH 2/2] netfilter: nf_tables: add requirements for connsecmark support
Hi Christian, Thank you for the patch! Yet something to improve: [auto build test ERROR on nf-next/master] [also build test ERROR on v4.19-rc5 next-20180921] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Christian-G-ttsche/netfilter-nf_tables-add-SECMARK-support/20180923-213820 base: https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git master config: x86_64-randconfig-s3-09241007 (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): net//netfilter/nft_ct.c: In function 'nft_ct_set_eval': >> net//netfilter/nft_ct.c:303:22: error: 'value' undeclared (first use in this >> function); did you mean 'false'? if (ct->secmark != value) { ^ false net//netfilter/nft_ct.c:303:22: note: each undeclared identifier is reported only once for each function it appears in vim +303 net//netfilter/nft_ct.c 275 276 static void nft_ct_set_eval(const struct nft_expr *expr, 277 struct nft_regs *regs, 278 const struct nft_pktinfo *pkt) 279 { 280 const struct nft_ct *priv = nft_expr_priv(expr); 281 struct sk_buff *skb = pkt->skb; 282 #ifdef CONFIG_NF_CONNTRACK_MARK 283 u32 value = regs->data[priv->sreg]; 284 #endif 285 enum ip_conntrack_info ctinfo; 286 struct nf_conn *ct; 287 288 ct = nf_ct_get(skb, ); 289 if (ct == NULL || nf_ct_is_template(ct)) 290 return; 291 292 switch (priv->key) { 293 #ifdef CONFIG_NF_CONNTRACK_MARK 294 case NFT_CT_MARK: 295 if (ct->mark != value) { 296 ct->mark = value; 297 nf_conntrack_event_cache(IPCT_MARK, ct); 298 } 299 break; 300 #endif 301 #ifdef CONFIG_NF_CONNTRACK_SECMARK 302 case NFT_CT_SECMARK: > 303 if (ct->secmark != value) { 304 ct->secmark = value; 305 nf_conntrack_event_cache(IPCT_SECMARK, ct); 306 } 307 break; 308 #endif 309 #ifdef CONFIG_NF_CONNTRACK_LABELS 310 case NFT_CT_LABELS: 311 nf_connlabels_replace(ct, 312>data[priv->sreg], 313>data[priv->sreg], 314NF_CT_LABELS_MAX_SIZE / sizeof(u32)); 315 break; 316 #endif 317 #ifdef CONFIG_NF_CONNTRACK_EVENTS 318 case NFT_CT_EVENTMASK: { 319 struct nf_conntrack_ecache *e = nf_ct_ecache_find(ct); 320 u32 ctmask = regs->data[priv->sreg]; 321 322 if (e) { 323 if (e->ctmask != ctmask) 324 e->ctmask = ctmask; 325 break; 326 } 327 328 if (ctmask && !nf_ct_is_confirmed(ct)) 329 nf_ct_ecache_ext_add(ct, ctmask, 0, GFP_ATOMIC); 330 break; 331 } 332 #endif 333 default: 334 break; 335 } 336 } 337 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH v3 2/2] netfilter: nf_tables: add requirements for connsecmark support
Add ability to set the connection tracking secmark value. Add ability to set the meta secmark value. Signed-off-by: Christian Göttsche --- v3: fix compile error when CONFIG_NF_CONNTRACK_MARK not defined Based on nf-next Tested with v4.18.8 net/netfilter/nft_ct.c | 17 - net/netfilter/nft_meta.c | 8 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index d74afa707..586627c36 100644 --- a/net/netfilter/nft_ct.c +++ b/net/netfilter/nft_ct.c @@ -279,7 +279,7 @@ static void nft_ct_set_eval(const struct nft_expr *expr, { const struct nft_ct *priv = nft_expr_priv(expr); struct sk_buff *skb = pkt->skb; -#ifdef CONFIG_NF_CONNTRACK_MARK +#if defined(CONFIG_NF_CONNTRACK_MARK) || defined(CONFIG_NF_CONNTRACK_SECMARK) u32 value = regs->data[priv->sreg]; #endif enum ip_conntrack_info ctinfo; @@ -298,6 +298,14 @@ static void nft_ct_set_eval(const struct nft_expr *expr, } break; #endif +#ifdef CONFIG_NF_CONNTRACK_SECMARK + case NFT_CT_SECMARK: + if (ct->secmark != value) { + ct->secmark = value; + nf_conntrack_event_cache(IPCT_SECMARK, ct); + } + break; +#endif #ifdef CONFIG_NF_CONNTRACK_LABELS case NFT_CT_LABELS: nf_connlabels_replace(ct, @@ -564,6 +572,13 @@ static int nft_ct_set_init(const struct nft_ctx *ctx, return -EINVAL; len = sizeof(u32); break; +#endif +#ifdef CONFIG_NF_CONNTRACK_SECMARK + case NFT_CT_SECMARK: + if (tb[NFTA_CT_DIRECTION]) + return -EINVAL; + len = sizeof(u32); + break; #endif default: return -EOPNOTSUPP; diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index c8ac0ef4b..a6715c816 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -284,6 +284,11 @@ static void nft_meta_set_eval(const struct nft_expr *expr, skb->nf_trace = !!value8; break; +#ifdef CONFIG_NETWORK_SECMARK + case NFT_META_SECMARK: + skb->secmark = value; + break; +#endif default: WARN_ON(1); } @@ -436,6 +441,9 @@ static int nft_meta_set_init(const struct nft_ctx *ctx, switch (priv->key) { case NFT_META_MARK: case NFT_META_PRIORITY: +#ifdef CONFIG_NETWORK_SECMARK + case NFT_META_SECMARK: +#endif len = sizeof(u32); break; case NFT_META_NFTRACE: -- 2.19.0 ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 00/19] LSM: Module stacking for SARA and Landlock
On 2018/09/23 11:43, Kees Cook wrote: >>> I'm excited about getting this landed! >> >> Soon. Real soon. I hope. I would very much like for >> someone from the SELinux camp to chime in, especially on >> the selinux_is_enabled() removal. > > Agreed. > This patchset from Casey lands before the patchset from Kees, doesn't it? OK, a few comments (if I didn't overlook something). lsm_early_cred()/lsm_early_task() are called from only __init functions. lsm_cred_alloc()/lsm_file_alloc() are called from only security/security.c . lsm_early_inode() should be avoided because it is not appropriate to call panic() when lsm_early_inode() is called after __init phase. Since all free hooks are called when one of init hooks failed, each free hook needs to check whether init hook was called. An example is inode_free_security() in security/selinux/hooks.c (but not addressed in this patch). This patchset might fatally prevent LKM-based LSM modules, for LKM-based LSMs cannot count on lsm_*_alloc() because size for lsm_*_alloc() cannot be updated upon loading LKM-based LSMs. If security_file_free() is called regardless of whether lsm_file_cache is defined, LKM-based LSMs can be loaded using current behavior (apart from the fact that legitimate interface for appending to security_hook_heads is currently missing). How do you plan to handle LKM-based LSMs? include/linux/lsm_hooks.h |6 ++ security/security.c| 31 ++- security/smack/smack_lsm.c |8 +++- 3 files changed, 15 insertions(+), 30 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 7e8b32f..8014614 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2095,13 +2095,11 @@ static inline void __init yama_add_hooks(void) { } static inline void loadpin_add_hooks(void) { }; #endif -extern int lsm_cred_alloc(struct cred *cred, gfp_t gfp); extern int lsm_inode_alloc(struct inode *inode); #ifdef CONFIG_SECURITY -void lsm_early_cred(struct cred *cred); -void lsm_early_inode(struct inode *inode); -void lsm_early_task(struct task_struct *task); +void __init lsm_early_cred(struct cred *cred); +void __init lsm_early_task(struct task_struct *task); #endif #endif /* ! __LINUX_LSM_HOOKS_H */ diff --git a/security/security.c b/security/security.c index e7c85060..341e8df 100644 --- a/security/security.c +++ b/security/security.c @@ -267,7 +267,7 @@ int unregister_lsm_notifier(struct notifier_block *nb) * * Returns 0, or -ENOMEM if memory can't be allocated. */ -int lsm_cred_alloc(struct cred *cred, gfp_t gfp) +static int lsm_cred_alloc(struct cred *cred, gfp_t gfp) { if (blob_sizes.lbs_cred == 0) { cred->security = NULL; @@ -286,7 +286,7 @@ int lsm_cred_alloc(struct cred *cred, gfp_t gfp) * * Allocate the cred blob for all the modules if it's not already there */ -void lsm_early_cred(struct cred *cred) +void __init lsm_early_cred(struct cred *cred) { int rc; @@ -344,7 +344,7 @@ void __init security_add_blobs(struct lsm_blob_sizes *needed) * * Returns 0, or -ENOMEM if memory can't be allocated. */ -int lsm_file_alloc(struct file *file) +static int lsm_file_alloc(struct file *file) { if (!lsm_file_cache) { file->f_security = NULL; @@ -379,25 +379,6 @@ int lsm_inode_alloc(struct inode *inode) } /** - * lsm_early_inode - during initialization allocate a composite inode blob - * @inode: the inode that needs a blob - * - * Allocate the inode blob for all the modules if it's not already there - */ -void lsm_early_inode(struct inode *inode) -{ - int rc; - - if (inode == NULL) - panic("%s: NULL inode.\n", __func__); - if (inode->i_security != NULL) - return; - rc = lsm_inode_alloc(inode); - if (rc) - panic("%s: Early inode alloc failed.\n", __func__); -} - -/** * lsm_task_alloc - allocate a composite task blob * @task: the task that needs a blob * @@ -466,7 +447,7 @@ int lsm_msg_msg_alloc(struct msg_msg *mp) * * Allocate the task blob for all the modules if it's not already there */ -void lsm_early_task(struct task_struct *task) +void __init lsm_early_task(struct task_struct *task) { int rc; @@ -1202,11 +1183,11 @@ void security_file_free(struct file *file) { void *blob; + call_void_hook(file_free_security, file); + if (!lsm_file_cache) return; - call_void_hook(file_free_security, file); - blob = file->f_security; file->f_security = NULL; kmem_cache_free(lsm_file_cache, blob); diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 7843004..b0b4045 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -750,6 +750,13 @@ static int smack_set_mnt_opts(struct super_block *sb, if (sp->smk_flags & SMK_SB_INITIALIZED) return 0; +
[PATCH v3 1/2] netfilter: nf_tables: add SECMARK support
Add the ability to set the security context of packets within the nf_tables framework. Add a nft_object for holding security contexts in the kernel and manipulating packets on the wire. Convert the security context strings at rule addition time to security identifiers. This is the same behavior like in xt_SECMARK and offers better performance than computing it per packet. Set the maximum security context length to 256. Signed-off-by: Christian Göttsche --- v3: switch context string from char[] to char * rename function to nft_secmark_compute_secid() v2: convert security context strings to ids on rule addition time Based on nf-next Tested with v4.18.8 include/net/netfilter/nf_tables_core.h | 4 + include/uapi/linux/netfilter/nf_tables.h | 18 +++- net/netfilter/nf_tables_core.c | 28 +- net/netfilter/nft_meta.c | 107 +++ 4 files changed, 152 insertions(+), 5 deletions(-) diff --git a/include/net/netfilter/nf_tables_core.h b/include/net/netfilter/nf_tables_core.h index 8da837d2a..2046d104f 100644 --- a/include/net/netfilter/nf_tables_core.h +++ b/include/net/netfilter/nf_tables_core.h @@ -16,6 +16,10 @@ extern struct nft_expr_type nft_meta_type; extern struct nft_expr_type nft_rt_type; extern struct nft_expr_type nft_exthdr_type; +#ifdef CONFIG_NETWORK_SECMARK +extern struct nft_object_type nft_secmark_obj_type; +#endif + int nf_tables_core_module_init(void); void nf_tables_core_module_exit(void); diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index 702e4f0be..5444e7687 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -1176,6 +1176,21 @@ enum nft_quota_attributes { }; #define NFTA_QUOTA_MAX (__NFTA_QUOTA_MAX - 1) +/** + * enum nft_secmark_attributes - nf_tables secmark object netlink attributes + * + * @NFTA_SECMARK_CTX: security context (NLA_STRING) + */ +enum nft_secmark_attributes { + NFTA_SECMARK_UNSPEC, + NFTA_SECMARK_CTX, + __NFTA_SECMARK_MAX, +}; +#define NFTA_SECMARK_MAX (__NFTA_SECMARK_MAX - 1) + +/* Max security context length */ +#define NFT_SECMARK_CTX_MAXLEN 256 + /** * enum nft_reject_types - nf_tables reject expression reject types * @@ -1432,7 +1447,8 @@ enum nft_ct_timeout_timeout_attributes { #define NFT_OBJECT_CONNLIMIT 5 #define NFT_OBJECT_TUNNEL 6 #define NFT_OBJECT_CT_TIMEOUT 7 -#define __NFT_OBJECT_MAX 8 +#define NFT_OBJECT_SECMARK 8 +#define __NFT_OBJECT_MAX 9 #define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1) /** diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index ffd5c0f94..3fbce3b9c 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c @@ -249,12 +249,24 @@ static struct nft_expr_type *nft_basic_types[] = { _exthdr_type, }; +static struct nft_object_type *nft_basic_objects[] = { +#ifdef CONFIG_NETWORK_SECMARK + _secmark_obj_type, +#endif +}; + int __init nf_tables_core_module_init(void) { - int err, i; + int err, i, j = 0; + + for (i = 0; i < ARRAY_SIZE(nft_basic_objects); i++) { + err = nft_register_obj(nft_basic_objects[i]); + if (err) + goto err; + } - for (i = 0; i < ARRAY_SIZE(nft_basic_types); i++) { - err = nft_register_expr(nft_basic_types[i]); + for (j = 0; j < ARRAY_SIZE(nft_basic_types); j++) { + err = nft_register_expr(nft_basic_types[j]); if (err) goto err; } @@ -262,8 +274,12 @@ int __init nf_tables_core_module_init(void) return 0; err: + while (j-- > 0) + nft_unregister_expr(nft_basic_types[j]); + while (i-- > 0) - nft_unregister_expr(nft_basic_types[i]); + nft_unregister_obj(nft_basic_objects[i]); + return err; } @@ -274,4 +290,8 @@ void nf_tables_core_module_exit(void) i = ARRAY_SIZE(nft_basic_types); while (i-- > 0) nft_unregister_expr(nft_basic_types[i]); + + i = ARRAY_SIZE(nft_basic_objects); + while (i-- > 0) + nft_unregister_obj(nft_basic_objects[i]); } diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index 297fe7d97..c8ac0ef4b 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -543,3 +543,110 @@ struct nft_expr_type nft_meta_type __read_mostly = { .maxattr= NFTA_META_MAX, .owner = THIS_MODULE, }; + +#ifdef CONFIG_NETWORK_SECMARK + +struct nft_secmark { + u32 secid; + char *ctx; +}; + +static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = { + [NFTA_SECMARK_CTX] = { .type = NLA_STRING, .len = NFT_SECMARK_CTX_MAXLEN }, +}; + +static int nft_secmark_compute_secid(struct nft_secmark *priv) +{ + int err; +
Re: [PATCH v4 00/19] LSM: Module stacking for SARA and Landlock
On 2018/09/24 2:09, Casey Schaufler wrote: >> Since all free hooks are called when one of init hooks failed, each >> free hook needs to check whether init hook was called. An example is >> inode_free_security() in security/selinux/hooks.c (but not addressed in >> this patch). > > I *think* that selinux_inode_free_security() is safe in this > case because the blob will be zeroed, hence isec->list will > be NULL. > OK. >> This patchset might fatally prevent LKM-based LSM modules, for LKM-based >> LSMs cannot count on lsm_*_alloc() because size for lsm_*_alloc() cannot >> be updated upon loading LKM-based LSMs. > > LKM based security modules will require dynamically sized blobs. > These can be added to the scheme used here. Each blob would get a > header identifying the modules for which it contains data. When an > LKM is registered if has to declare it's blob space requirements > and gets back the offsets. All alloc operations have to put their > marks in the header. All LKM blob users have to check that the blob > they are looking at has the required data. > > module_cred(struct cred *cred) { > return cred->security + module_blob_sizes.lbs_cred; > } > > becomes > > module_cred(struct cred *cred) { > if (blob_includes(module_id)) > return cred->security + module_blob_sizes.lbs_cred; > return NULL; > } > > and the calling code needs to accept a NULL return. Not all of LKM-based LSMs use security blobs. And some of LKM-based LSMs might use security blobs for only a few objects. For example, AKARI uses inode security blob for remembering whether source address/port of an accept()ed socket was already checked, only during accept() operation and first socket operation on the accept()ed socket. Thus, there is no need to waste memory by assigning blobs for all inode objects. > Blobs can never get smaller because readjusting the offsets > isn't going to work, so unloading an LKM security module isn't > going to be as complete as you might like. There may be a way > around this if you unload all the LKM modules, but that's a > special case and there may be dragon lurking in the mist. If LKM-based LSMs who want to use security blobs have to check for NULL return, they might choose "not using infrastructure managed security blobs" and "using locally hashed blobs associated with object's address" (like AKARI does). > >> If security_file_free() is called >> regardless of whether lsm_file_cache is defined, LKM-based LSMs can be >> loaded using current behavior (apart from the fact that legitimate >> interface for appending to security_hook_heads is currently missing). >> How do you plan to handle LKM-based LSMs? > > My position all along has been that I don't plan to handle LKM > based LSMs, but that I won't do anything to prevent someone else > from adding them later. I believe that I've done that. Several > designs, including a separate list for dynamically loaded modules > have been proposed. I think some of those would work. Though AKARI is not using security_file_free(), some of LKM-based LSMs might want to use it. If file_free_security hook is called unconditionally, such LKM-based LSMs can be registered/unregistered, without worrying about inability to shrink sizes for blobs. >> @@ -1202,11 +1183,11 @@ void security_file_free(struct file *file) >> { >> void *blob; >> >> +call_void_hook(file_free_security, file); >> + >> if (!lsm_file_cache) >> return; >> >> -call_void_hook(file_free_security, file); >> - > > Why does this make sense? If the lsm_file_cache isn't > initialized you can't have allocated any file blobs, > no module can have initialized a file blob, hence there > can be nothing for the module to do. > For modules (not limited to LKM-based LSMs) which want to use file blobs for only a few objects and avoid wasting memory by allocating file blobs to all file objects. Infrastructure based blob management fits well for LSM modules which want to assign blobs to all objects (like SELinux). But forcing infrastructure based blob management can become a huge waste of memory for LSM modules which want to assign blobs to only a few objects. Unconditionally calling file_free_security hook (as with other hooks) preserves a room for allowing the latter type of LSM modules without using infrastructure based blob management. ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH 2/2] netfilter: nf_tables: add requirements for connsecmark support
Hi Christian, Thank you for the patch! Yet something to improve: [auto build test ERROR on nf-next/master] [also build test ERROR on v4.19-rc4 next-20180921] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Christian-G-ttsche/netfilter-nf_tables-add-SECMARK-support/20180923-213820 base: https://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git master config: x86_64-randconfig-s2-09240020 (attached as .config) compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): net/netfilter/nft_ct.c: In function 'nft_ct_set_eval': >> net/netfilter/nft_ct.c:303:22: error: 'value' undeclared (first use in this >> function) if (ct->secmark != value) { ^ net/netfilter/nft_ct.c:303:22: note: each undeclared identifier is reported only once for each function it appears in vim +/value +303 net/netfilter/nft_ct.c 275 276 static void nft_ct_set_eval(const struct nft_expr *expr, 277 struct nft_regs *regs, 278 const struct nft_pktinfo *pkt) 279 { 280 const struct nft_ct *priv = nft_expr_priv(expr); 281 struct sk_buff *skb = pkt->skb; 282 #ifdef CONFIG_NF_CONNTRACK_MARK 283 u32 value = regs->data[priv->sreg]; 284 #endif 285 enum ip_conntrack_info ctinfo; 286 struct nf_conn *ct; 287 288 ct = nf_ct_get(skb, ); 289 if (ct == NULL || nf_ct_is_template(ct)) 290 return; 291 292 switch (priv->key) { 293 #ifdef CONFIG_NF_CONNTRACK_MARK 294 case NFT_CT_MARK: 295 if (ct->mark != value) { 296 ct->mark = value; 297 nf_conntrack_event_cache(IPCT_MARK, ct); 298 } 299 break; 300 #endif 301 #ifdef CONFIG_NF_CONNTRACK_SECMARK 302 case NFT_CT_SECMARK: > 303 if (ct->secmark != value) { 304 ct->secmark = value; 305 nf_conntrack_event_cache(IPCT_SECMARK, ct); 306 } 307 break; 308 #endif 309 #ifdef CONFIG_NF_CONNTRACK_LABELS 310 case NFT_CT_LABELS: 311 nf_connlabels_replace(ct, 312>data[priv->sreg], 313>data[priv->sreg], 314NF_CT_LABELS_MAX_SIZE / sizeof(u32)); 315 break; 316 #endif 317 #ifdef CONFIG_NF_CONNTRACK_EVENTS 318 case NFT_CT_EVENTMASK: { 319 struct nf_conntrack_ecache *e = nf_ct_ecache_find(ct); 320 u32 ctmask = regs->data[priv->sreg]; 321 322 if (e) { 323 if (e->ctmask != ctmask) 324 e->ctmask = ctmask; 325 break; 326 } 327 328 if (ctmask && !nf_ct_is_confirmed(ct)) 329 nf_ct_ecache_ext_add(ct, ctmask, 0, GFP_ATOMIC); 330 break; 331 } 332 #endif 333 default: 334 break; 335 } 336 } 337 --- 0-DAY kernel test infrastructureOpen Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation .config.gz Description: application/gzip ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v2 1/2] netfilter: nf_tables: add SECMARK support
Christian Göttsche wrote: > > Can you change this to: > > > > struct nft_secmark { > > u32 secid; > > char *ctx; > > }; > > Does the nla_policy struct needs an update too? (regarding then .len member) > > +static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = { > +[NFTA_SECMARK_CTX] = { .type = NLA_STRING, .len = > NFT_SECMARK_CTX_MAXLEN }, > +} > > NFT_SECMARK_CTX_MAXLEN might be dropped then.. Better keep it, we can always increase this later it if needed. Given the length matches what xtables uses it should be fine. ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 00/19] LSM: Module stacking for SARA and Landlock
On 9/23/2018 8:59 AM, Tetsuo Handa wrote: > On 2018/09/23 11:43, Kees Cook wrote: I'm excited about getting this landed! >>> Soon. Real soon. I hope. I would very much like for >>> someone from the SELinux camp to chime in, especially on >>> the selinux_is_enabled() removal. >> Agreed. >> > This patchset from Casey lands before the patchset from Kees, doesn't it? That is up for negotiation. We may end up combining them. > OK, a few comments (if I didn't overlook something). > > lsm_early_cred()/lsm_early_task() are called from only __init functions. True. > lsm_cred_alloc()/lsm_file_alloc() are called from only security/security.c . Also true. > lsm_early_inode() should be avoided because it is not appropriate to > call panic() when lsm_early_inode() is called after __init phase. You're correct. In fact, lsm_early_inode() isn't needed at all until multiple inode using modules are supported. > Since all free hooks are called when one of init hooks failed, each > free hook needs to check whether init hook was called. An example is > inode_free_security() in security/selinux/hooks.c (but not addressed in > this patch). I *think* that selinux_inode_free_security() is safe in this case because the blob will be zeroed, hence isec->list will be NULL. > This patchset might fatally prevent LKM-based LSM modules, for LKM-based > LSMs cannot count on lsm_*_alloc() because size for lsm_*_alloc() cannot > be updated upon loading LKM-based LSMs. LKM based security modules will require dynamically sized blobs. These can be added to the scheme used here. Each blob would get a header identifying the modules for which it contains data. When an LKM is registered if has to declare it's blob space requirements and gets back the offsets. All alloc operations have to put their marks in the header. All LKM blob users have to check that the blob they are looking at has the required data. module_cred(struct cred *cred) { return cred->security + module_blob_sizes.lbs_cred; } becomes module_cred(struct cred *cred) { if (blob_includes(module_id)) return cred->security + module_blob_sizes.lbs_cred; return NULL; } and the calling code needs to accept a NULL return. Blobs can never get smaller because readjusting the offsets isn't going to work, so unloading an LKM security module isn't going to be as complete as you might like. There may be a way around this if you unload all the LKM modules, but that's a special case and there may be dragon lurking in the mist. > If security_file_free() is called > regardless of whether lsm_file_cache is defined, LKM-based LSMs can be > loaded using current behavior (apart from the fact that legitimate > interface for appending to security_hook_heads is currently missing). > How do you plan to handle LKM-based LSMs? My position all along has been that I don't plan to handle LKM based LSMs, but that I won't do anything to prevent someone else from adding them later. I believe that I've done that. Several designs, including a separate list for dynamically loaded modules have been proposed. I think some of those would work. > include/linux/lsm_hooks.h |6 ++ > security/security.c| 31 ++- > security/smack/smack_lsm.c |8 +++- > 3 files changed, 15 insertions(+), 30 deletions(-) > > diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h > index 7e8b32f..8014614 100644 > --- a/include/linux/lsm_hooks.h > +++ b/include/linux/lsm_hooks.h > @@ -2095,13 +2095,11 @@ static inline void __init yama_add_hooks(void) { } > static inline void loadpin_add_hooks(void) { }; > #endif > > -extern int lsm_cred_alloc(struct cred *cred, gfp_t gfp); > extern int lsm_inode_alloc(struct inode *inode); > > #ifdef CONFIG_SECURITY > -void lsm_early_cred(struct cred *cred); > -void lsm_early_inode(struct inode *inode); > -void lsm_early_task(struct task_struct *task); > +void __init lsm_early_cred(struct cred *cred); > +void __init lsm_early_task(struct task_struct *task); > #endif > > #endif /* ! __LINUX_LSM_HOOKS_H */ > diff --git a/security/security.c b/security/security.c > index e7c85060..341e8df 100644 > --- a/security/security.c > +++ b/security/security.c > @@ -267,7 +267,7 @@ int unregister_lsm_notifier(struct notifier_block *nb) > * > * Returns 0, or -ENOMEM if memory can't be allocated. > */ > -int lsm_cred_alloc(struct cred *cred, gfp_t gfp) > +static int lsm_cred_alloc(struct cred *cred, gfp_t gfp) > { > if (blob_sizes.lbs_cred == 0) { > cred->security = NULL; > @@ -286,7 +286,7 @@ int lsm_cred_alloc(struct cred *cred, gfp_t gfp) > * > * Allocate the cred blob for all the modules if it's not already there > */ > -void lsm_early_cred(struct cred *cred) > +void __init lsm_early_cred(struct cred *cred) > { > int rc; > > @@ -344,7 +344,7 @@ void __init security_add_blobs(struct lsm_blob_sizes > *needed) > *
Re: [PATCH v2 1/2] netfilter: nf_tables: add SECMARK support
> > +struct nft_secmark { > > + char ctx[NFT_SECMARK_CTX_MAXLEN]; > > + int len; > > + u32 secid; > > +}; > > Can you change this to: > > struct nft_secmark { > u32 secid; > char *ctx; > }; Does the nla_policy struct needs an update too? (regarding then .len member) +static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = { +[NFTA_SECMARK_CTX] = { .type = NLA_STRING, .len = NFT_SECMARK_CTX_MAXLEN }, +} NFT_SECMARK_CTX_MAXLEN might be dropped then.. ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH 2/2] netfilter: nf_tables: add requirements for connsecmark support
Christian Göttsche wrote: > Add ability to set the connection tracking secmark value. > Add ability to set the meta secmark value. Looks good to me. Acked-by: Florian Westphal ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v2 1/2] netfilter: nf_tables: add SECMARK support
Christian Göttsche wrote: > Add the ability to set the security context of packets within the nf_tables > framework. > Add a nft_object for holding security contexts in the kernel and manipulating > packets on the wire. > > Convert the security context strings at rule addition time to security > identifiers. > This is the same behavior like in xt_SECMARK and offers better performance > than computing it per packet. > > Set the maximum security context length to 256. Looks good, one minor suggestion. > +#ifdef CONFIG_NETWORK_SECMARK > + > +struct nft_secmark { > + char ctx[NFT_SECMARK_CTX_MAXLEN]; > + int len; > + u32 secid; > +}; Can you change this to: struct nft_secmark { u32 secid; char *ctx; }; ? We don't need ctx in the packetpath, so better to keep the struct size small. > + nla_strlcpy(priv->ctx, tb[NFTA_SECMARK_CTX], NFT_SECMARK_CTX_MAXLEN); You can change this to priv->ctx = nla_strdup(tb[NFTA_SECMARK_CTX], GFP_KERNEL); if (!priv->ctx) return -ENOMEM; > + err = nft_secmark_secconversion(priv); > + if (err) { kfree(priv->ctx); > +static void nft_secmark_obj_destroy(const struct nft_ctx *ctx, struct > nft_object *obj) > +{ kfree(priv->ctx); But other than this i think this is ready to be applied, thanks a lot for making this happen. ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH v2 1/2] netfilter: nf_tables: add SECMARK support
Add the ability to set the security context of packets within the nf_tables framework. Add a nft_object for holding security contexts in the kernel and manipulating packets on the wire. Convert the security context strings at rule addition time to security identifiers. This is the same behavior like in xt_SECMARK and offers better performance than computing it per packet. Set the maximum security context length to 256. Signed-off-by: Christian Göttsche --- v2: convert security context strings to ids on rule addition time Based on nf-next Tested with v4.18.8 include/net/netfilter/nf_tables_core.h | 4 + include/uapi/linux/netfilter/nf_tables.h | 18 +++- net/netfilter/nf_tables_core.c | 28 ++- net/netfilter/nft_meta.c | 101 +++ 4 files changed, 146 insertions(+), 5 deletions(-) diff --git a/include/net/netfilter/nf_tables_core.h b/include/net/netfilter/nf_tables_core.h index 8da837d2a..2046d104f 100644 --- a/include/net/netfilter/nf_tables_core.h +++ b/include/net/netfilter/nf_tables_core.h @@ -16,6 +16,10 @@ extern struct nft_expr_type nft_meta_type; extern struct nft_expr_type nft_rt_type; extern struct nft_expr_type nft_exthdr_type; +#ifdef CONFIG_NETWORK_SECMARK +extern struct nft_object_type nft_secmark_obj_type; +#endif + int nf_tables_core_module_init(void); void nf_tables_core_module_exit(void); diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index 702e4f0be..5444e7687 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -1176,6 +1176,21 @@ enum nft_quota_attributes { }; #define NFTA_QUOTA_MAX (__NFTA_QUOTA_MAX - 1) +/** + * enum nft_secmark_attributes - nf_tables secmark object netlink attributes + * + * @NFTA_SECMARK_CTX: security context (NLA_STRING) + */ +enum nft_secmark_attributes { + NFTA_SECMARK_UNSPEC, + NFTA_SECMARK_CTX, + __NFTA_SECMARK_MAX, +}; +#define NFTA_SECMARK_MAX (__NFTA_SECMARK_MAX - 1) + +/* Max security context length */ +#define NFT_SECMARK_CTX_MAXLEN 256 + /** * enum nft_reject_types - nf_tables reject expression reject types * @@ -1432,7 +1447,8 @@ enum nft_ct_timeout_timeout_attributes { #define NFT_OBJECT_CONNLIMIT 5 #define NFT_OBJECT_TUNNEL 6 #define NFT_OBJECT_CT_TIMEOUT 7 -#define __NFT_OBJECT_MAX 8 +#define NFT_OBJECT_SECMARK 8 +#define __NFT_OBJECT_MAX 9 #define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1) /** diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index ffd5c0f94..3fbce3b9c 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c @@ -249,12 +249,24 @@ static struct nft_expr_type *nft_basic_types[] = { _exthdr_type, }; +static struct nft_object_type *nft_basic_objects[] = { +#ifdef CONFIG_NETWORK_SECMARK + _secmark_obj_type, +#endif +}; + int __init nf_tables_core_module_init(void) { - int err, i; + int err, i, j = 0; + + for (i = 0; i < ARRAY_SIZE(nft_basic_objects); i++) { + err = nft_register_obj(nft_basic_objects[i]); + if (err) + goto err; + } - for (i = 0; i < ARRAY_SIZE(nft_basic_types); i++) { - err = nft_register_expr(nft_basic_types[i]); + for (j = 0; j < ARRAY_SIZE(nft_basic_types); j++) { + err = nft_register_expr(nft_basic_types[j]); if (err) goto err; } @@ -262,8 +274,12 @@ int __init nf_tables_core_module_init(void) return 0; err: + while (j-- > 0) + nft_unregister_expr(nft_basic_types[j]); + while (i-- > 0) - nft_unregister_expr(nft_basic_types[i]); + nft_unregister_obj(nft_basic_objects[i]); + return err; } @@ -274,4 +290,8 @@ void nf_tables_core_module_exit(void) i = ARRAY_SIZE(nft_basic_types); while (i-- > 0) nft_unregister_expr(nft_basic_types[i]); + + i = ARRAY_SIZE(nft_basic_objects); + while (i-- > 0) + nft_unregister_obj(nft_basic_objects[i]); } diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index 297fe7d97..ac5df9508 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -543,3 +543,104 @@ struct nft_expr_type nft_meta_type __read_mostly = { .maxattr= NFTA_META_MAX, .owner = THIS_MODULE, }; + +#ifdef CONFIG_NETWORK_SECMARK + +struct nft_secmark { + char ctx[NFT_SECMARK_CTX_MAXLEN]; + int len; + u32 secid; +}; + +static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = { + [NFTA_SECMARK_CTX] = { .type = NLA_STRING, .len = NFT_SECMARK_CTX_MAXLEN }, +}; + +static int nft_secmark_secconversion(struct nft_secmark *priv) +{ + int err; + u32 tmp_secid = 0; + + err =
Re: [PATCH v4 00/19] LSM: Module stacking for SARA and Landlock
On Sat, Sep 22, 2018 at 9:38 AM, Casey Schaufler wrote: > On 9/21/2018 8:02 PM, Kees Cook wrote: >> On Fri, Sep 21, 2018 at 4:59 PM, Casey Schaufler >> wrote: >>> v4: Finer granularity in the patches and other >>> cleanups suggested by Kees Cook. >>> Removed dead code created by the removal of SELinux >>> credential blob poisoning. >> Thanks for the splitting, this really does make it easier to review >> (at least for me). I think this looks really good, though obviously >> I'd like to refactor it slightly on top of my series. :) > > Whichever goes on top is fine with me. What's one > more patch set merge, after all? > >> One additional thought I had was about the blobs allocations: some are >> separate kmem caches, and some are kmalloc. I'm thinking it might make >> sense to use separate kmem caches for two reasons: > > I had seriously considered doing that. I can't see any reason > not to. It's something that could be done at any time, and with > all the other things that had to change it just didn't get in. Yup; that is an easy future change. Not needed now! > >> - they're going to always be the same size and are regularly >> allocated/freed, so it may offer a performance benefit. >> >> - they're explicitly not supposed to be exposed to userspace, so >> hardened usercopy would protect them if they were not kmalloc()ed. >> >> I'm excited about getting this landed! > > Soon. Real soon. I hope. I would very much like for > someone from the SELinux camp to chime in, especially on > the selinux_is_enabled() removal. Agreed. > On a somewhat related note, I will be out for the first three > weeks of October, returning just in time for the Linux Security > Summit in Edinburgh. My connectivity will be severely limited. > I don't expect to accomplish anything while I'm out. If you're okay with it, I can help with changes while you're out -- I want to try to rebase it on my tree and see how it looks anyway. :) -Kees -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH 2/2] netfilter: nf_tables: add requirements for connsecmark support
Add ability to set the connection tracking secmark value. Add ability to set the meta secmark value. Signed-off-by: Christian Göttsche --- Based on nf-next Tested with v4.18.8 net/netfilter/nft_ct.c | 15 +++ net/netfilter/nft_meta.c | 8 2 files changed, 23 insertions(+) diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index d74afa707..dcc451c20 100644 --- a/net/netfilter/nft_ct.c +++ b/net/netfilter/nft_ct.c @@ -298,6 +298,14 @@ static void nft_ct_set_eval(const struct nft_expr *expr, } break; #endif +#ifdef CONFIG_NF_CONNTRACK_SECMARK + case NFT_CT_SECMARK: + if (ct->secmark != value) { + ct->secmark = value; + nf_conntrack_event_cache(IPCT_SECMARK, ct); + } + break; +#endif #ifdef CONFIG_NF_CONNTRACK_LABELS case NFT_CT_LABELS: nf_connlabels_replace(ct, @@ -564,6 +572,13 @@ static int nft_ct_set_init(const struct nft_ctx *ctx, return -EINVAL; len = sizeof(u32); break; +#endif +#ifdef CONFIG_NF_CONNTRACK_SECMARK + case NFT_CT_SECMARK: + if (tb[NFTA_CT_DIRECTION]) + return -EINVAL; + len = sizeof(u32); + break; #endif default: return -EOPNOTSUPP; diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index ac5df9508..555fcd66b 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c @@ -284,6 +284,11 @@ static void nft_meta_set_eval(const struct nft_expr *expr, skb->nf_trace = !!value8; break; +#ifdef CONFIG_NETWORK_SECMARK + case NFT_META_SECMARK: + skb->secmark = value; + break; +#endif default: WARN_ON(1); } @@ -436,6 +441,9 @@ static int nft_meta_set_init(const struct nft_ctx *ctx, switch (priv->key) { case NFT_META_MARK: case NFT_META_PRIORITY: +#ifdef CONFIG_NETWORK_SECMARK + case NFT_META_SECMARK: +#endif len = sizeof(u32); break; case NFT_META_NFTRACE: -- 2.19.0 ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 00/19] LSM: Module stacking for SARA and Landlock
On 9/21/2018 8:02 PM, Kees Cook wrote: > On Fri, Sep 21, 2018 at 4:59 PM, Casey Schaufler > wrote: >> v4: Finer granularity in the patches and other >> cleanups suggested by Kees Cook. >> Removed dead code created by the removal of SELinux >> credential blob poisoning. > Thanks for the splitting, this really does make it easier to review > (at least for me). I think this looks really good, though obviously > I'd like to refactor it slightly on top of my series. :) Whichever goes on top is fine with me. What's one more patch set merge, after all? > One additional thought I had was about the blobs allocations: some are > separate kmem caches, and some are kmalloc. I'm thinking it might make > sense to use separate kmem caches for two reasons: I had seriously considered doing that. I can't see any reason not to. It's something that could be done at any time, and with all the other things that had to change it just didn't get in. > - they're going to always be the same size and are regularly > allocated/freed, so it may offer a performance benefit. > > - they're explicitly not supposed to be exposed to userspace, so > hardened usercopy would protect them if they were not kmalloc()ed. > > I'm excited about getting this landed! Soon. Real soon. I hope. I would very much like for someone from the SELinux camp to chime in, especially on the selinux_is_enabled() removal. On a somewhat related note, I will be out for the first three weeks of October, returning just in time for the Linux Security Summit in Edinburgh. My connectivity will be severely limited. I don't expect to accomplish anything while I'm out. ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 00/19] LSM: Module stacking for SARA and Landlock
On Fri, Sep 21, 2018 at 4:59 PM, Casey Schaufler wrote: > v4: Finer granularity in the patches and other > cleanups suggested by Kees Cook. > Removed dead code created by the removal of SELinux > credential blob poisoning. Thanks for the splitting, this really does make it easier to review (at least for me). I think this looks really good, though obviously I'd like to refactor it slightly on top of my series. :) One additional thought I had was about the blobs allocations: some are separate kmem caches, and some are kmalloc. I'm thinking it might make sense to use separate kmem caches for two reasons: - they're going to always be the same size and are regularly allocated/freed, so it may offer a performance benefit. - they're explicitly not supposed to be exposed to userspace, so hardened usercopy would protect them if they were not kmalloc()ed. I'm excited about getting this landed! -Kees -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 17/19] Smack: Abstract use of ipc security blobs
On Fri, Sep 21, 2018 at 5:19 PM, Casey Schaufler wrote: > Don't use the ipc->security pointer directly. > Don't use the msg_msg->security pointer directly. > Provide helper functions that provides the security blob pointers. > > Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook -Kees -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 10/19] Smack: Abstract use of file security blob
On Fri, Sep 21, 2018 at 5:18 PM, Casey Schaufler wrote: > Don't use the file->f_security pointer directly. > Provide a helper function that provides the security blob pointer. > > Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook -Kees -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 08/19] Infrastructure management of the cred security blob
On Fri, Sep 21, 2018 at 5:18 PM, Casey Schaufler wrote: > Move management of the cred security blob out of the > security modules and into the security infrastructre. > Instead of allocating and freeing space the security > modules tell the infrastructure how much space they > require. > > Signed-off-by: Casey Schaufler When combined with my series, this gets slightly simpler: - the double init call and the "finished" stuff goes away - debugging output is controlled by "lsm.debug" param instead of a CONFIG Regardless, for the overall logic, calculating the sizes, etc: Reviewed-by: Kees Cook -Kees -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 07/19] TOMOYO: Abstract use of cred security blob
On Fri, Sep 21, 2018 at 5:18 PM, Casey Schaufler wrote: > Don't use the cred->security pointer directly. > Provide helper functions that provide the security blob pointer. > > Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook -Kees -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 18/19] LSM: Infrastructure management of the ipc security blob
On Fri, Sep 21, 2018 at 5:20 PM, Casey Schaufler wrote: > Move management of the kern_ipc_perm->security and > msg_msg->security blobs out of the individual security > modules and into the security infrastructure. Instead > of allocating the blobs from within the modules the modules > tell the infrastructure how much space is required, and > the space is allocated there. > > Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook -Kees -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 16/19] SELinux: Abstract use of ipc security blobs
On Fri, Sep 21, 2018 at 5:19 PM, Casey Schaufler wrote: > Don't use the ipc->security pointer directly. > Don't use the msg_msg->security pointer directly. > Provide helper functions that provides the security blob pointers. > > Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook -Kees -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 11/19] LSM: Infrastructure management of the file security
On Fri, Sep 21, 2018 at 5:19 PM, Casey Schaufler wrote: > Move management of the file->f_security blob out of the > individual security modules and into the infrastructure. > The modules no longer allocate or free the data, instead > they tell the infrastructure how much space they require. > > Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook -Kees -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 14/19] LSM: Infrastructure management of the inode security
On Fri, Sep 21, 2018 at 5:19 PM, Casey Schaufler wrote: > Move management of the inode->i_security blob out > of the individual security modules and into the security > infrastructure. Instead of allocating the blobs from within > the modules the modules tell the infrastructure how much > space is required, and the space is allocated there. > > Signed-off-by: Casey Schaufler > --- > include/linux/lsm_hooks.h | 3 ++ > security/security.c | 83 ++- > security/selinux/hooks.c | 32 +--- > security/selinux/include/objsec.h | 5 +- > security/smack/smack_lsm.c| 70 -- > 5 files changed, 98 insertions(+), 95 deletions(-) > > diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h > index 167ffbd4d0c0..416b20c3795b 100644 > --- a/include/linux/lsm_hooks.h > +++ b/include/linux/lsm_hooks.h > @@ -2030,6 +2030,7 @@ struct security_hook_list { > struct lsm_blob_sizes { > int lbs_cred; > int lbs_file; > + int lbs_inode; > }; > > /* > @@ -2092,9 +2093,11 @@ static inline void loadpin_add_hooks(void) { }; > #endif > > extern int lsm_cred_alloc(struct cred *cred, gfp_t gfp); > +extern int lsm_inode_alloc(struct inode *inode); > > #ifdef CONFIG_SECURITY > void lsm_early_cred(struct cred *cred); > +void lsm_early_inode(struct inode *inode); > #endif > > #endif /* ! __LINUX_LSM_HOOKS_H */ > diff --git a/security/security.c b/security/security.c > index 5430cae73cf6..a8f00fdff4d8 100644 > --- a/security/security.c > +++ b/security/security.c > @@ -41,6 +41,7 @@ struct security_hook_heads security_hook_heads > __lsm_ro_after_init; > static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain); > > static struct kmem_cache *lsm_file_cache; > +static struct kmem_cache *lsm_inode_cache; > > char *lsm_names; > static struct lsm_blob_sizes blob_sizes; > @@ -101,6 +102,10 @@ int __init security_init(void) > lsm_file_cache = kmem_cache_create("lsm_file_cache", >blob_sizes.lbs_file, 0, >SLAB_PANIC, NULL); > + if (blob_sizes.lbs_inode) > + lsm_inode_cache = kmem_cache_create("lsm_inode_cache", > + blob_sizes.lbs_inode, 0, > + SLAB_PANIC, NULL); > /* > * The second call to a module specific init function > * adds hooks to the hook lists and does any other early > @@ -111,6 +116,7 @@ int __init security_init(void) > #ifdef CONFIG_SECURITY_LSM_DEBUG > pr_info("LSM: cred blob size = %d\n", blob_sizes.lbs_cred); > pr_info("LSM: file blob size = %d\n", blob_sizes.lbs_file); > + pr_info("LSM: inode blob size = %d\n", blob_sizes.lbs_inode); > #endif > > return 0; > @@ -288,6 +294,13 @@ void __init security_add_blobs(struct lsm_blob_sizes > *needed) > { > lsm_set_size(>lbs_cred, _sizes.lbs_cred); > lsm_set_size(>lbs_file, _sizes.lbs_file); > + /* > +* The inode blob gets an rcu_head in addition to > +* what the modules might need. > +*/ > + if (needed->lbs_inode && blob_sizes.lbs_inode == 0) > + blob_sizes.lbs_inode = sizeof(struct rcu_head); > + lsm_set_size(>lbs_inode, _sizes.lbs_inode); > } > > /** > @@ -311,6 +324,46 @@ int lsm_file_alloc(struct file *file) > return 0; > } > > +/** > + * lsm_inode_alloc - allocate a composite inode blob > + * @inode: the inode that needs a blob > + * > + * Allocate the inode blob for all the modules > + * > + * Returns 0, or -ENOMEM if memory can't be allocated. > + */ > +int lsm_inode_alloc(struct inode *inode) > +{ > + if (!lsm_inode_cache) { > + inode->i_security = NULL; > + return 0; > + } > + > + inode->i_security = kmem_cache_zalloc(lsm_inode_cache, GFP_NOFS); > + if (inode->i_security == NULL) > + return -ENOMEM; > + return 0; > +} > + > +/** > + * lsm_early_inode - during initialization allocate a composite inode blob > + * @inode: the inode that needs a blob > + * > + * Allocate the inode blob for all the modules if it's not already there > + */ > +void lsm_early_inode(struct inode *inode) > +{ > + int rc; > + > + if (inode == NULL) > + panic("%s: NULL inode.\n", __func__); > + if (inode->i_security != NULL) > + return; > + rc = lsm_inode_alloc(inode); > + if (rc) > + panic("%s: Early inode alloc failed.\n", __func__); > +} I'm still advising against using panic(), but I'll leave it up to James. For everything else here: Reviewed-by: Kees Cook -Kees -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to
Re: [PATCH v4 15/19] LSM: Infrastructure management of the task security
On Fri, Sep 21, 2018 at 5:19 PM, Casey Schaufler wrote: > Move management of the task_struct->security blob out > of the individual security modules and into the security > infrastructure. Instead of allocating the blobs from within > the modules the modules tell the infrastructure how much > space is required, and the space is allocated there. > The only user of this blob is AppArmor. The AppArmor use > is abstracted to avoid future conflict. > > Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook -Kees -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH v4 15/19] LSM: Infrastructure management of the task security
Move management of the task_struct->security blob out of the individual security modules and into the security infrastructure. Instead of allocating the blobs from within the modules the modules tell the infrastructure how much space is required, and the space is allocated there. The only user of this blob is AppArmor. The AppArmor use is abstracted to avoid future conflict. Signed-off-by: Casey Schaufler --- include/linux/lsm_hooks.h| 2 ++ security/apparmor/include/task.h | 18 +++ security/apparmor/lsm.c | 15 ++--- security/security.c | 54 +++- 4 files changed, 62 insertions(+), 27 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 416b20c3795b..6057c603b979 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2031,6 +2031,7 @@ struct lsm_blob_sizes { int lbs_cred; int lbs_file; int lbs_inode; + int lbs_task; }; /* @@ -2098,6 +2099,7 @@ extern int lsm_inode_alloc(struct inode *inode); #ifdef CONFIG_SECURITY void lsm_early_cred(struct cred *cred); void lsm_early_inode(struct inode *inode); +void lsm_early_task(struct task_struct *task); #endif #endif /* ! __LINUX_LSM_HOOKS_H */ diff --git a/security/apparmor/include/task.h b/security/apparmor/include/task.h index 55edaa1d83f8..039c1e60887a 100644 --- a/security/apparmor/include/task.h +++ b/security/apparmor/include/task.h @@ -14,7 +14,10 @@ #ifndef __AA_TASK_H #define __AA_TASK_H -#define task_ctx(X) ((X)->security) +static inline struct aa_task_ctx *task_ctx(struct task_struct *task) +{ + return task->security; +} /* * struct aa_task_ctx - information for current task label change @@ -36,17 +39,6 @@ int aa_set_current_hat(struct aa_label *label, u64 token); int aa_restore_previous_label(u64 cookie); struct aa_label *aa_get_task_label(struct task_struct *task); -/** - * aa_alloc_task_ctx - allocate a new task_ctx - * @flags: gfp flags for allocation - * - * Returns: allocated buffer or NULL on failure - */ -static inline struct aa_task_ctx *aa_alloc_task_ctx(gfp_t flags) -{ - return kzalloc(sizeof(struct aa_task_ctx), flags); -} - /** * aa_free_task_ctx - free a task_ctx * @ctx: task_ctx to free (MAYBE NULL) @@ -57,8 +49,6 @@ static inline void aa_free_task_ctx(struct aa_task_ctx *ctx) aa_put_label(ctx->nnp); aa_put_label(ctx->previous); aa_put_label(ctx->onexec); - - kzfree(ctx); } } diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 15716b6ff860..c97dc3dbb515 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -91,19 +91,14 @@ static void apparmor_task_free(struct task_struct *task) { aa_free_task_ctx(task_ctx(task)); - task_ctx(task) = NULL; } static int apparmor_task_alloc(struct task_struct *task, unsigned long clone_flags) { - struct aa_task_ctx *new = aa_alloc_task_ctx(GFP_KERNEL); - - if (!new) - return -ENOMEM; + struct aa_task_ctx *new = task_ctx(task); aa_dup_task_ctx(new, task_ctx(current)); - task_ctx(task) = new; return 0; } @@ -1132,6 +1127,7 @@ static void apparmor_sock_graft(struct sock *sk, struct socket *parent) struct lsm_blob_sizes apparmor_blob_sizes = { .lbs_cred = sizeof(struct aa_task_ctx *), .lbs_file = sizeof(struct aa_file_ctx), + .lbs_task = sizeof(struct aa_task_ctx), }; static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { @@ -1457,15 +1453,10 @@ static int param_set_mode(const char *val, const struct kernel_param *kp) static int __init set_init_ctx(void) { struct cred *cred = (struct cred *)current->real_cred; - struct aa_task_ctx *ctx; - - ctx = aa_alloc_task_ctx(GFP_KERNEL); - if (!ctx) - return -ENOMEM; lsm_early_cred(cred); + lsm_early_task(current); set_cred_label(cred, aa_get_label(ns_unconfined(root_ns))); - task_ctx(current) = ctx; return 0; } diff --git a/security/security.c b/security/security.c index a8f00fdff4d8..7e11de7eec21 100644 --- a/security/security.c +++ b/security/security.c @@ -117,6 +117,7 @@ int __init security_init(void) pr_info("LSM: cred blob size = %d\n", blob_sizes.lbs_cred); pr_info("LSM: file blob size = %d\n", blob_sizes.lbs_file); pr_info("LSM: inode blob size = %d\n", blob_sizes.lbs_inode); + pr_info("LSM: task blob size = %d\n", blob_sizes.lbs_task); #endif return 0; @@ -301,6 +302,7 @@ void __init security_add_blobs(struct lsm_blob_sizes *needed) if (needed->lbs_inode && blob_sizes.lbs_inode == 0) blob_sizes.lbs_inode = sizeof(struct rcu_head); lsm_set_size(>lbs_inode, _sizes.lbs_inode); + lsm_set_size(>lbs_task,
[PATCH v4 19/19] LSM: Blob sharing support for S.A.R.A and LandLock
Two proposed security modules require the ability to share security blobs with existing "major" security modules. These modules, S.A.R.A and LandLock, provide significantly different services than SELinux, Smack or AppArmor. Using either in conjunction with the existing modules is quite reasonable. S.A.R.A requires access to the cred, inode and task blobs, while LandLock uses the cred, file, inode and ipc blobs. The use of the cred, file, inode, ipc and task blobs has been abstracted in preceding patches in the series. This patch teaches the affected security modules how to access the part of the blob set aside for their use in the case where blobs are shared. The configuration option CONFIG_SECURITY_STACKING identifies systems where the blobs may be shared. The mechanism for selecting which security modules are active has been changed to allow non-conflicting "major" security modules to be used together. At this time the TOMOYO module can safely be used with any of the others. The two new modules would be non-conflicting as well. Signed-off-by: Casey Schaufler --- Documentation/admin-guide/LSM/index.rst | 14 +++-- include/linux/lsm_hooks.h | 2 +- security/Kconfig| 81 + security/apparmor/include/cred.h| 8 +++ security/apparmor/include/file.h| 9 ++- security/apparmor/include/lib.h | 4 ++ security/apparmor/lsm.c | 8 ++- security/security.c | 30 - security/selinux/hooks.c| 3 +- security/selinux/include/objsec.h | 12 security/smack/smack.h | 13 security/smack/smack_lsm.c | 3 +- security/tomoyo/common.h| 5 ++ security/tomoyo/tomoyo.c| 3 +- 14 files changed, 182 insertions(+), 13 deletions(-) diff --git a/Documentation/admin-guide/LSM/index.rst b/Documentation/admin-guide/LSM/index.rst index 9842e21afd4a..d3d8af174042 100644 --- a/Documentation/admin-guide/LSM/index.rst +++ b/Documentation/admin-guide/LSM/index.rst @@ -17,10 +17,16 @@ MAC extensions, other extensions can be built using the LSM to provide specific changes to system operation when these tweaks are not available in the core functionality of Linux itself. -The Linux capabilities modules will always be included. This may be -followed by any number of "minor" modules and at most one "major" module. -For more details on capabilities, see ``capabilities(7)`` in the Linux -man-pages project. +The Linux capabilities modules will always be included. For more details +on capabilities, see ``capabilities(7)`` in the Linux man-pages project. + +Security modules that do not use the security data blobs maintained +by the LSM infrastructure are considered "minor" modules. These may be +included at compile time and stacked explicitly. Security modules that +use the LSM maintained security blobs are considered "major" modules. +These may only be stacked if the CONFIG_LSM_STACKED configuration +option is used. If this is chosen all of the security modules selected +will be used. A list of the active security modules can be found by reading ``/sys/kernel/security/lsm``. This is a comma separated list, and diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index f6dbde28833a..7e8b32fdf576 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2082,7 +2082,7 @@ static inline void security_delete_hooks(struct security_hook_list *hooks, #define __lsm_ro_after_init__ro_after_init #endif /* CONFIG_SECURITY_WRITABLE_HOOKS */ -extern int __init security_module_enable(const char *module); +extern bool __init security_module_enable(const char *lsm, const bool stacked); extern void __init capability_add_hooks(void); #ifdef CONFIG_SECURITY_YAMA extern void __init yama_add_hooks(void); diff --git a/security/Kconfig b/security/Kconfig index 22f7664c4977..ed48025ae9e0 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -36,6 +36,28 @@ config SECURITY_WRITABLE_HOOKS bool default n +config SECURITY_STACKING + bool "Security module stacking" + depends on SECURITY + help + Allows multiple major security modules to be stacked. + Modules are invoked in the order registered with a + "bail on fail" policy, in which the infrastructure + will stop processing once a denial is detected. Not + all modules can be stacked. SELinux, Smack and AppArmor are + known to be incompatible. User space components may + have trouble identifying the security module providing + data in some cases. + + If you select this option you will have to select which + of the stackable modules you wish to be active. The + "Default security module" will be ignored. The boot line + "security=" option can be used to specify that one of + the modules identifed for stacking
[PATCH v4 16/19] SELinux: Abstract use of ipc security blobs
Don't use the ipc->security pointer directly. Don't use the msg_msg->security pointer directly. Provide helper functions that provides the security blob pointers. Signed-off-by: Casey Schaufler --- security/selinux/hooks.c | 18 +- security/selinux/include/objsec.h | 13 + 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 389e51ef48a5..e6cb5fce5437 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -5884,7 +5884,7 @@ static int ipc_has_perm(struct kern_ipc_perm *ipc_perms, struct common_audit_data ad; u32 sid = current_sid(); - isec = ipc_perms->security; + isec = selinux_ipc(ipc_perms); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = ipc_perms->key; @@ -5941,7 +5941,7 @@ static int selinux_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) struct common_audit_data ad; u32 sid = current_sid(); - isec = msq->security; + isec = selinux_ipc(msq); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = msq->key; @@ -5990,8 +5990,8 @@ static int selinux_msg_queue_msgsnd(struct kern_ipc_perm *msq, struct msg_msg *m u32 sid = current_sid(); int rc; - isec = msq->security; - msec = msg->security; + isec = selinux_ipc(msq); + msec = selinux_msg_msg(msg); /* * First time through, need to assign label to the message @@ -6038,8 +6038,8 @@ static int selinux_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *m u32 sid = task_sid(target); int rc; - isec = msq->security; - msec = msg->security; + isec = selinux_ipc(msq); + msec = selinux_msg_msg(msg); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = msq->key; @@ -6092,7 +6092,7 @@ static int selinux_shm_associate(struct kern_ipc_perm *shp, int shmflg) struct common_audit_data ad; u32 sid = current_sid(); - isec = shp->security; + isec = selinux_ipc(shp); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = shp->key; @@ -6189,7 +6189,7 @@ static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg) struct common_audit_data ad; u32 sid = current_sid(); - isec = sma->security; + isec = selinux_ipc(sma); ad.type = LSM_AUDIT_DATA_IPC; ad.u.ipc_id = sma->key; @@ -6275,7 +6275,7 @@ static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag) static void selinux_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) { - struct ipc_security_struct *isec = ipcp->security; + struct ipc_security_struct *isec = selinux_ipc(ipcp); *secid = isec->sid; } diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index 591adb374d69..5bf9f280e9b2 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "flask.h" #include "avc.h" @@ -173,4 +174,16 @@ static inline struct inode_security_struct *selinux_inode( return inode->i_security; } +static inline struct msg_security_struct *selinux_msg_msg( + const struct msg_msg *msg_msg) +{ + return msg_msg->security; +} + +static inline struct ipc_security_struct *selinux_ipc( + const struct kern_ipc_perm *ipc) +{ + return ipc->security; +} + #endif /* _SELINUX_OBJSEC_H_ */ -- 2.17.1 ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 02/19] Smack: Abstract use of cred security blob
On Fri, Sep 21, 2018 at 5:17 PM, Casey Schaufler wrote: > Don't use the cred->security pointer directly. > Provide a helper function that provides the security blob pointer. > > Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook -Kees -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 06/19] AppArmor: Abstract use of cred security blob
On Fri, Sep 21, 2018 at 5:17 PM, Casey Schaufler wrote: > Don't use the cred->security pointer directly. > Provide a helper function that provides the security blob pointer. > > Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook -Kees -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH v4 09/19] SELinux: Abstract use of file security blob
Don't use the file->f_security pointer directly. Provide a helper function that provides the security blob pointer. Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook --- security/selinux/hooks.c | 18 +- security/selinux/include/objsec.h | 5 + 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b629cc302088..641a8ce726ff 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -396,7 +396,7 @@ static int file_alloc_security(struct file *file) static void file_free_security(struct file *file) { - struct file_security_struct *fsec = file->f_security; + struct file_security_struct *fsec = selinux_file(file); file->f_security = NULL; kmem_cache_free(file_security_cache, fsec); } @@ -1879,7 +1879,7 @@ static int file_has_perm(const struct cred *cred, struct file *file, u32 av) { - struct file_security_struct *fsec = file->f_security; + struct file_security_struct *fsec = selinux_file(file); struct inode *inode = file_inode(file); struct common_audit_data ad; u32 sid = cred_sid(cred); @@ -2223,7 +2223,7 @@ static int selinux_binder_transfer_file(struct task_struct *from, struct file *file) { u32 sid = task_sid(to); - struct file_security_struct *fsec = file->f_security; + struct file_security_struct *fsec = selinux_file(file); struct dentry *dentry = file->f_path.dentry; struct inode_security_struct *isec; struct common_audit_data ad; @@ -3535,7 +3535,7 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) static int selinux_file_permission(struct file *file, int mask) { struct inode *inode = file_inode(file); - struct file_security_struct *fsec = file->f_security; + struct file_security_struct *fsec = selinux_file(file); struct inode_security_struct *isec; u32 sid = current_sid(); @@ -3570,7 +3570,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file, u32 requested, u16 cmd) { struct common_audit_data ad; - struct file_security_struct *fsec = file->f_security; + struct file_security_struct *fsec = selinux_file(file); struct inode *inode = file_inode(file); struct inode_security_struct *isec; struct lsm_ioctlop_audit ioctl; @@ -3822,7 +3822,7 @@ static void selinux_file_set_fowner(struct file *file) { struct file_security_struct *fsec; - fsec = file->f_security; + fsec = selinux_file(file); fsec->fown_sid = current_sid(); } @@ -3837,7 +3837,7 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk, /* struct fown_struct is never outside the context of a struct file */ file = container_of(fown, struct file, f_owner); - fsec = file->f_security; + fsec = selinux_file(file); if (!signum) perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */ @@ -3861,7 +3861,7 @@ static int selinux_file_open(struct file *file) struct file_security_struct *fsec; struct inode_security_struct *isec; - fsec = file->f_security; + fsec = selinux_file(file); isec = inode_security(file_inode(file)); /* * Save inode label and policy sequence number @@ -4000,7 +4000,7 @@ static int selinux_kernel_module_from_file(struct file *file) ad.type = LSM_AUDIT_DATA_FILE; ad.u.file = file; - fsec = file->f_security; + fsec = selinux_file(file); if (sid != fsec->sid) { rc = avc_has_perm(_state, sid, fsec->sid, SECCLASS_FD, FD__USE, ); diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index ad511c3d2eb7..cad8b765f6dd 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -165,4 +165,9 @@ static inline struct task_security_struct *selinux_cred(const struct cred *cred) return cred->security; } +static inline struct file_security_struct *selinux_file(const struct file *file) +{ + return file->f_security; +} + #endif /* _SELINUX_OBJSEC_H_ */ -- 2.17.1 ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH v4 13/19] Smack: Abstract use of inode security blob
Don't use the inode->i_security pointer directly. Provide a helper function that provides the security blob pointer. Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook --- security/smack/smack.h | 9 +++-- security/smack/smack_lsm.c | 32 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/security/smack/smack.h b/security/smack/smack.h index 62a22ad8ce92..add19b7efc96 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -366,12 +366,17 @@ static inline struct smack_known **smack_file(const struct file *file) return file->f_security; } +static inline struct inode_smack *smack_inode(const struct inode *inode) +{ + return inode->i_security; +} + /* * Is the directory transmuting? */ static inline int smk_inode_transmutable(const struct inode *isp) { - struct inode_smack *sip = isp->i_security; + struct inode_smack *sip = smack_inode(isp); return (sip->smk_flags & SMK_INODE_TRANSMUTE) != 0; } @@ -380,7 +385,7 @@ static inline int smk_inode_transmutable(const struct inode *isp) */ static inline struct smack_known *smk_of_inode(const struct inode *isp) { - struct inode_smack *sip = isp->i_security; + struct inode_smack *sip = smack_inode(isp); return sip->smk_inode; } diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index d1430341798f..364699ad55b9 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -166,7 +166,7 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc) static int smk_bu_inode(struct inode *inode, int mode, int rc) { struct task_smack *tsp = smack_cred(current_cred()); - struct inode_smack *isp = inode->i_security; + struct inode_smack *isp = smack_inode(inode); char acc[SMK_NUM_ACCESS_TYPE + 1]; if (isp->smk_flags & SMK_INODE_IMPURE) @@ -198,7 +198,7 @@ static int smk_bu_file(struct file *file, int mode, int rc) struct task_smack *tsp = smack_cred(current_cred()); struct smack_known *sskp = tsp->smk_task; struct inode *inode = file_inode(file); - struct inode_smack *isp = inode->i_security; + struct inode_smack *isp = smack_inode(inode); char acc[SMK_NUM_ACCESS_TYPE + 1]; if (isp->smk_flags & SMK_INODE_IMPURE) @@ -228,7 +228,7 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file, struct task_smack *tsp = smack_cred(cred); struct smack_known *sskp = tsp->smk_task; struct inode *inode = file_inode(file); - struct inode_smack *isp = inode->i_security; + struct inode_smack *isp = smack_inode(inode); char acc[SMK_NUM_ACCESS_TYPE + 1]; if (isp->smk_flags & SMK_INODE_IMPURE) @@ -824,7 +824,7 @@ static int smack_set_mnt_opts(struct super_block *sb, /* * Initialize the root inode. */ - isp = inode->i_security; + isp = smack_inode(inode); if (isp == NULL) { isp = new_inode_smack(sp->smk_root); if (isp == NULL) @@ -912,7 +912,7 @@ static int smack_bprm_set_creds(struct linux_binprm *bprm) if (bprm->called_set_creds) return 0; - isp = inode->i_security; + isp = smack_inode(inode); if (isp->smk_task == NULL || isp->smk_task == bsp->smk_task) return 0; @@ -992,7 +992,7 @@ static void smack_inode_free_rcu(struct rcu_head *head) */ static void smack_inode_free_security(struct inode *inode) { - struct inode_smack *issp = inode->i_security; + struct inode_smack *issp = smack_inode(inode); /* * The inode may still be referenced in a path walk and @@ -1020,7 +1020,7 @@ static int smack_inode_init_security(struct inode *inode, struct inode *dir, const struct qstr *qstr, const char **name, void **value, size_t *len) { - struct inode_smack *issp = inode->i_security; + struct inode_smack *issp = smack_inode(inode); struct smack_known *skp = smk_of_current(); struct smack_known *isp = smk_of_inode(inode); struct smack_known *dsp = smk_of_inode(dir); @@ -1358,7 +1358,7 @@ static void smack_inode_post_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { struct smack_known *skp; - struct inode_smack *isp = d_backing_inode(dentry)->i_security; + struct inode_smack *isp = smack_inode(d_backing_inode(dentry)); if (strcmp(name, XATTR_NAME_SMACKTRANSMUTE) == 0) { isp->smk_flags |= SMK_INODE_TRANSMUTE; @@ -1439,7 +1439,7 @@ static int smack_inode_removexattr(struct dentry *dentry, const char *name) if (rc != 0) return rc; - isp = d_backing_inode(dentry)->i_security; + isp =
Re: [PATCH v4 04/19] SELinux: Remove cred security blob poisoning
On Fri, Sep 21, 2018 at 5:17 PM, Casey Schaufler wrote: > The SELinux specific credential poisioning only makes sense > if SELinux is managing the credentials. As the intent of this > patch set is to move the blob management out of the modules > and into the infrastructure, the SELinux specific code has > to go. The poisioning could be introduced into the infrastructure > at some later date. > > Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook -Kees > --- > kernel/cred.c| 13 - > security/selinux/hooks.c | 6 -- > 2 files changed, 19 deletions(-) > > diff --git a/kernel/cred.c b/kernel/cred.c > index ecf03657e71c..fa2061ee4955 100644 > --- a/kernel/cred.c > +++ b/kernel/cred.c > @@ -704,19 +704,6 @@ bool creds_are_invalid(const struct cred *cred) > { > if (cred->magic != CRED_MAGIC) > return true; > -#ifdef CONFIG_SECURITY_SELINUX > - /* > -* cred->security == NULL if security_cred_alloc_blank() or > -* security_prepare_creds() returned an error. > -*/ > - if (selinux_is_enabled() && cred->security) { > - if ((unsigned long) cred->security < PAGE_SIZE) > - return true; > - if ((*(u32 *)cred->security & 0xff00) == > - (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << > 8)) > - return true; > - } > -#endif > return false; > } > EXPORT_SYMBOL(creds_are_invalid); > diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c > index 9d6cdd21acb6..80614ca25a2b 100644 > --- a/security/selinux/hooks.c > +++ b/security/selinux/hooks.c > @@ -3920,12 +3920,6 @@ static void selinux_cred_free(struct cred *cred) > { > struct task_security_struct *tsec = selinux_cred(cred); > > - /* > -* cred->security == NULL if security_cred_alloc_blank() or > -* security_prepare_creds() returned an error. > -*/ > - BUG_ON(cred->security && (unsigned long) cred->security < PAGE_SIZE); > - cred->security = (void *) 0x7UL; > kfree(tsec); > } > > -- > 2.17.1 > > -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH v4 11/19] LSM: Infrastructure management of the file security
Move management of the file->f_security blob out of the individual security modules and into the infrastructure. The modules no longer allocate or free the data, instead they tell the infrastructure how much space they require. Signed-off-by: Casey Schaufler --- include/linux/lsm_hooks.h | 1 + security/apparmor/lsm.c| 19 +++--- security/security.c| 54 +++--- security/selinux/hooks.c | 25 ++ security/smack/smack.h | 2 +- security/smack/smack_lsm.c | 14 +- 6 files changed, 66 insertions(+), 49 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 0bef312efd45..167ffbd4d0c0 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2029,6 +2029,7 @@ struct security_hook_list { */ struct lsm_blob_sizes { int lbs_cred; + int lbs_file; }; /* diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index c2566aaa138e..15716b6ff860 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -431,21 +431,21 @@ static int apparmor_file_open(struct file *file) static int apparmor_file_alloc_security(struct file *file) { - int error = 0; - - /* freed by apparmor_file_free_security */ + struct aa_file_ctx *ctx = file_ctx(file); struct aa_label *label = begin_current_label_crit_section(); - file->f_security = aa_alloc_file_ctx(label, GFP_KERNEL); - if (!file_ctx(file)) - error = -ENOMEM; - end_current_label_crit_section(label); - return error; + spin_lock_init(>lock); + rcu_assign_pointer(ctx->label, aa_get_label(label)); + end_current_label_crit_section(label); + return 0; } static void apparmor_file_free_security(struct file *file) { - aa_free_file_ctx(file_ctx(file)); + struct aa_file_ctx *ctx = file_ctx(file); + + if (ctx) + aa_put_label(rcu_access_pointer(ctx->label)); } static int common_file_perm(const char *op, struct file *file, u32 mask) @@ -1131,6 +1131,7 @@ static void apparmor_sock_graft(struct sock *sk, struct socket *parent) */ struct lsm_blob_sizes apparmor_blob_sizes = { .lbs_cred = sizeof(struct aa_task_ctx *), + .lbs_file = sizeof(struct aa_file_ctx), }; static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { diff --git a/security/security.c b/security/security.c index ff7df14f6db1..5430cae73cf6 100644 --- a/security/security.c +++ b/security/security.c @@ -40,6 +40,8 @@ struct security_hook_heads security_hook_heads __lsm_ro_after_init; static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain); +static struct kmem_cache *lsm_file_cache; + char *lsm_names; static struct lsm_blob_sizes blob_sizes; @@ -92,6 +94,13 @@ int __init security_init(void) */ do_security_initcalls(); + /* +* Create any kmem_caches needed for blobs +*/ + if (blob_sizes.lbs_file) + lsm_file_cache = kmem_cache_create("lsm_file_cache", + blob_sizes.lbs_file, 0, + SLAB_PANIC, NULL); /* * The second call to a module specific init function * adds hooks to the hook lists and does any other early @@ -101,6 +110,7 @@ int __init security_init(void) #ifdef CONFIG_SECURITY_LSM_DEBUG pr_info("LSM: cred blob size = %d\n", blob_sizes.lbs_cred); + pr_info("LSM: file blob size = %d\n", blob_sizes.lbs_file); #endif return 0; @@ -277,6 +287,28 @@ static void __init lsm_set_size(int *need, int *lbs) void __init security_add_blobs(struct lsm_blob_sizes *needed) { lsm_set_size(>lbs_cred, _sizes.lbs_cred); + lsm_set_size(>lbs_file, _sizes.lbs_file); +} + +/** + * lsm_file_alloc - allocate a composite file blob + * @file: the file that needs a blob + * + * Allocate the file blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_file_alloc(struct file *file) +{ + if (!lsm_file_cache) { + file->f_security = NULL; + return 0; + } + + file->f_security = kmem_cache_zalloc(lsm_file_cache, GFP_KERNEL); + if (file->f_security == NULL) + return -ENOMEM; + return 0; } /* @@ -962,12 +994,28 @@ int security_file_permission(struct file *file, int mask) int security_file_alloc(struct file *file) { - return call_int_hook(file_alloc_security, 0, file); + int rc = lsm_file_alloc(file); + + if (rc) + return rc; + rc = call_int_hook(file_alloc_security, 0, file); + if (unlikely(rc)) + security_file_free(file); + return rc; } void security_file_free(struct file *file) { + void *blob; + + if (!lsm_file_cache) + return; + call_void_hook(file_free_security,
[PATCH v4 18/19] LSM: Infrastructure management of the ipc security blob
Move management of the kern_ipc_perm->security and msg_msg->security blobs out of the individual security modules and into the security infrastructure. Instead of allocating the blobs from within the modules the modules tell the infrastructure how much space is required, and the space is allocated there. Signed-off-by: Casey Schaufler --- include/linux/lsm_hooks.h | 2 + security/security.c| 91 +-- security/selinux/hooks.c | 98 +- security/smack/smack.h | 4 +- security/smack/smack_lsm.c | 32 ++--- 5 files changed, 108 insertions(+), 119 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 6057c603b979..f6dbde28833a 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2031,6 +2031,8 @@ struct lsm_blob_sizes { int lbs_cred; int lbs_file; int lbs_inode; + int lbs_ipc; + int lbs_msg_msg; int lbs_task; }; diff --git a/security/security.c b/security/security.c index 7e11de7eec21..a151d728aed2 100644 --- a/security/security.c +++ b/security/security.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -117,6 +118,8 @@ int __init security_init(void) pr_info("LSM: cred blob size = %d\n", blob_sizes.lbs_cred); pr_info("LSM: file blob size = %d\n", blob_sizes.lbs_file); pr_info("LSM: inode blob size = %d\n", blob_sizes.lbs_inode); + pr_info("LSM: ipc blob size= %d\n", blob_sizes.lbs_ipc); + pr_info("LSM: msg_msg blob size= %d\n", blob_sizes.lbs_msg_msg); pr_info("LSM: task blob size = %d\n", blob_sizes.lbs_task); #endif @@ -302,6 +305,8 @@ void __init security_add_blobs(struct lsm_blob_sizes *needed) if (needed->lbs_inode && blob_sizes.lbs_inode == 0) blob_sizes.lbs_inode = sizeof(struct rcu_head); lsm_set_size(>lbs_inode, _sizes.lbs_inode); + lsm_set_size(>lbs_ipc, _sizes.lbs_ipc); + lsm_set_size(>lbs_msg_msg, _sizes.lbs_msg_msg); lsm_set_size(>lbs_task, _sizes.lbs_task); } @@ -387,6 +392,48 @@ int lsm_task_alloc(struct task_struct *task) return 0; } +/** + * lsm_ipc_alloc - allocate a composite ipc blob + * @kip: the ipc that needs a blob + * + * Allocate the ipc blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_ipc_alloc(struct kern_ipc_perm *kip) +{ + if (blob_sizes.lbs_ipc == 0) { + kip->security = NULL; + return 0; + } + + kip->security = kzalloc(blob_sizes.lbs_ipc, GFP_KERNEL); + if (kip->security == NULL) + return -ENOMEM; + return 0; +} + +/** + * lsm_msg_msg_alloc - allocate a composite msg_msg blob + * @mp: the msg_msg that needs a blob + * + * Allocate the ipc blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_msg_msg_alloc(struct msg_msg *mp) +{ + if (blob_sizes.lbs_msg_msg == 0) { + mp->security = NULL; + return 0; + } + + mp->security = kzalloc(blob_sizes.lbs_msg_msg, GFP_KERNEL); + if (mp->security == NULL) + return -ENOMEM; + return 0; +} + /** * lsm_early_task - during initialization allocate a composite task blob * @task: the task that needs a blob @@ -1468,22 +1515,40 @@ void security_ipc_getsecid(struct kern_ipc_perm *ipcp, u32 *secid) int security_msg_msg_alloc(struct msg_msg *msg) { - return call_int_hook(msg_msg_alloc_security, 0, msg); + int rc = lsm_msg_msg_alloc(msg); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(msg_msg_alloc_security, 0, msg); + if (unlikely(rc)) + security_msg_msg_free(msg); + return rc; } void security_msg_msg_free(struct msg_msg *msg) { call_void_hook(msg_msg_free_security, msg); + kfree(msg->security); + msg->security = NULL; } int security_msg_queue_alloc(struct kern_ipc_perm *msq) { - return call_int_hook(msg_queue_alloc_security, 0, msq); + int rc = lsm_ipc_alloc(msq); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(msg_queue_alloc_security, 0, msq); + if (unlikely(rc)) + security_msg_queue_free(msq); + return rc; } void security_msg_queue_free(struct kern_ipc_perm *msq) { call_void_hook(msg_queue_free_security, msq); + kfree(msq->security); + msq->security = NULL; } int security_msg_queue_associate(struct kern_ipc_perm *msq, int msqflg) @@ -1510,12 +1575,21 @@ int security_msg_queue_msgrcv(struct kern_ipc_perm *msq, struct msg_msg *msg, int security_shm_alloc(struct kern_ipc_perm *shp) { - return call_int_hook(shm_alloc_security, 0, shp); + int rc = lsm_ipc_alloc(shp); + + if
[PATCH v4 14/19] LSM: Infrastructure management of the inode security
Move management of the inode->i_security blob out of the individual security modules and into the security infrastructure. Instead of allocating the blobs from within the modules the modules tell the infrastructure how much space is required, and the space is allocated there. Signed-off-by: Casey Schaufler --- include/linux/lsm_hooks.h | 3 ++ security/security.c | 83 ++- security/selinux/hooks.c | 32 +--- security/selinux/include/objsec.h | 5 +- security/smack/smack_lsm.c| 70 -- 5 files changed, 98 insertions(+), 95 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 167ffbd4d0c0..416b20c3795b 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2030,6 +2030,7 @@ struct security_hook_list { struct lsm_blob_sizes { int lbs_cred; int lbs_file; + int lbs_inode; }; /* @@ -2092,9 +2093,11 @@ static inline void loadpin_add_hooks(void) { }; #endif extern int lsm_cred_alloc(struct cred *cred, gfp_t gfp); +extern int lsm_inode_alloc(struct inode *inode); #ifdef CONFIG_SECURITY void lsm_early_cred(struct cred *cred); +void lsm_early_inode(struct inode *inode); #endif #endif /* ! __LINUX_LSM_HOOKS_H */ diff --git a/security/security.c b/security/security.c index 5430cae73cf6..a8f00fdff4d8 100644 --- a/security/security.c +++ b/security/security.c @@ -41,6 +41,7 @@ struct security_hook_heads security_hook_heads __lsm_ro_after_init; static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain); static struct kmem_cache *lsm_file_cache; +static struct kmem_cache *lsm_inode_cache; char *lsm_names; static struct lsm_blob_sizes blob_sizes; @@ -101,6 +102,10 @@ int __init security_init(void) lsm_file_cache = kmem_cache_create("lsm_file_cache", blob_sizes.lbs_file, 0, SLAB_PANIC, NULL); + if (blob_sizes.lbs_inode) + lsm_inode_cache = kmem_cache_create("lsm_inode_cache", + blob_sizes.lbs_inode, 0, + SLAB_PANIC, NULL); /* * The second call to a module specific init function * adds hooks to the hook lists and does any other early @@ -111,6 +116,7 @@ int __init security_init(void) #ifdef CONFIG_SECURITY_LSM_DEBUG pr_info("LSM: cred blob size = %d\n", blob_sizes.lbs_cred); pr_info("LSM: file blob size = %d\n", blob_sizes.lbs_file); + pr_info("LSM: inode blob size = %d\n", blob_sizes.lbs_inode); #endif return 0; @@ -288,6 +294,13 @@ void __init security_add_blobs(struct lsm_blob_sizes *needed) { lsm_set_size(>lbs_cred, _sizes.lbs_cred); lsm_set_size(>lbs_file, _sizes.lbs_file); + /* +* The inode blob gets an rcu_head in addition to +* what the modules might need. +*/ + if (needed->lbs_inode && blob_sizes.lbs_inode == 0) + blob_sizes.lbs_inode = sizeof(struct rcu_head); + lsm_set_size(>lbs_inode, _sizes.lbs_inode); } /** @@ -311,6 +324,46 @@ int lsm_file_alloc(struct file *file) return 0; } +/** + * lsm_inode_alloc - allocate a composite inode blob + * @inode: the inode that needs a blob + * + * Allocate the inode blob for all the modules + * + * Returns 0, or -ENOMEM if memory can't be allocated. + */ +int lsm_inode_alloc(struct inode *inode) +{ + if (!lsm_inode_cache) { + inode->i_security = NULL; + return 0; + } + + inode->i_security = kmem_cache_zalloc(lsm_inode_cache, GFP_NOFS); + if (inode->i_security == NULL) + return -ENOMEM; + return 0; +} + +/** + * lsm_early_inode - during initialization allocate a composite inode blob + * @inode: the inode that needs a blob + * + * Allocate the inode blob for all the modules if it's not already there + */ +void lsm_early_inode(struct inode *inode) +{ + int rc; + + if (inode == NULL) + panic("%s: NULL inode.\n", __func__); + if (inode->i_security != NULL) + return; + rc = lsm_inode_alloc(inode); + if (rc) + panic("%s: Early inode alloc failed.\n", __func__); +} + /* * Hook list operation macros. * @@ -557,14 +610,40 @@ EXPORT_SYMBOL(security_sb_parse_opts_str); int security_inode_alloc(struct inode *inode) { - inode->i_security = NULL; - return call_int_hook(inode_alloc_security, 0, inode); + int rc = lsm_inode_alloc(inode); + + if (unlikely(rc)) + return rc; + rc = call_int_hook(inode_alloc_security, 0, inode); + if (unlikely(rc)) + security_inode_free(inode); + return rc; +} + +static void inode_free_by_rcu(struct rcu_head *head) +{ + /* +* The rcu
[PATCH v4 09/19] SELinux: Abstract use of file security blob
Don't use the file->f_security pointer directly. Provide a helper function that provides the security blob pointer. Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook --- security/selinux/hooks.c | 18 +- security/selinux/include/objsec.h | 5 + 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index b629cc302088..641a8ce726ff 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -396,7 +396,7 @@ static int file_alloc_security(struct file *file) static void file_free_security(struct file *file) { - struct file_security_struct *fsec = file->f_security; + struct file_security_struct *fsec = selinux_file(file); file->f_security = NULL; kmem_cache_free(file_security_cache, fsec); } @@ -1879,7 +1879,7 @@ static int file_has_perm(const struct cred *cred, struct file *file, u32 av) { - struct file_security_struct *fsec = file->f_security; + struct file_security_struct *fsec = selinux_file(file); struct inode *inode = file_inode(file); struct common_audit_data ad; u32 sid = cred_sid(cred); @@ -2223,7 +2223,7 @@ static int selinux_binder_transfer_file(struct task_struct *from, struct file *file) { u32 sid = task_sid(to); - struct file_security_struct *fsec = file->f_security; + struct file_security_struct *fsec = selinux_file(file); struct dentry *dentry = file->f_path.dentry; struct inode_security_struct *isec; struct common_audit_data ad; @@ -3535,7 +3535,7 @@ static int selinux_revalidate_file_permission(struct file *file, int mask) static int selinux_file_permission(struct file *file, int mask) { struct inode *inode = file_inode(file); - struct file_security_struct *fsec = file->f_security; + struct file_security_struct *fsec = selinux_file(file); struct inode_security_struct *isec; u32 sid = current_sid(); @@ -3570,7 +3570,7 @@ static int ioctl_has_perm(const struct cred *cred, struct file *file, u32 requested, u16 cmd) { struct common_audit_data ad; - struct file_security_struct *fsec = file->f_security; + struct file_security_struct *fsec = selinux_file(file); struct inode *inode = file_inode(file); struct inode_security_struct *isec; struct lsm_ioctlop_audit ioctl; @@ -3822,7 +3822,7 @@ static void selinux_file_set_fowner(struct file *file) { struct file_security_struct *fsec; - fsec = file->f_security; + fsec = selinux_file(file); fsec->fown_sid = current_sid(); } @@ -3837,7 +3837,7 @@ static int selinux_file_send_sigiotask(struct task_struct *tsk, /* struct fown_struct is never outside the context of a struct file */ file = container_of(fown, struct file, f_owner); - fsec = file->f_security; + fsec = selinux_file(file); if (!signum) perm = signal_to_av(SIGIO); /* as per send_sigio_to_task */ @@ -3861,7 +3861,7 @@ static int selinux_file_open(struct file *file) struct file_security_struct *fsec; struct inode_security_struct *isec; - fsec = file->f_security; + fsec = selinux_file(file); isec = inode_security(file_inode(file)); /* * Save inode label and policy sequence number @@ -4000,7 +4000,7 @@ static int selinux_kernel_module_from_file(struct file *file) ad.type = LSM_AUDIT_DATA_FILE; ad.u.file = file; - fsec = file->f_security; + fsec = selinux_file(file); if (sid != fsec->sid) { rc = avc_has_perm(_state, sid, fsec->sid, SECCLASS_FD, FD__USE, ); diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h index ad511c3d2eb7..cad8b765f6dd 100644 --- a/security/selinux/include/objsec.h +++ b/security/selinux/include/objsec.h @@ -165,4 +165,9 @@ static inline struct task_security_struct *selinux_cred(const struct cred *cred) return cred->security; } +static inline struct file_security_struct *selinux_file(const struct file *file) +{ + return file->f_security; +} + #endif /* _SELINUX_OBJSEC_H_ */ -- 2.17.1 ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH v4 17/19] Smack: Abstract use of ipc security blobs
Don't use the ipc->security pointer directly. Don't use the msg_msg->security pointer directly. Provide helper functions that provides the security blob pointers. Signed-off-by: Casey Schaufler --- security/smack/smack.h | 11 +++ security/smack/smack_lsm.c | 14 +- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/security/smack/smack.h b/security/smack/smack.h index add19b7efc96..52cea142fcf6 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -24,6 +24,7 @@ #include #include #include +#include /* * Use IPv6 port labeling if IPv6 is enabled and secmarks @@ -371,6 +372,16 @@ static inline struct inode_smack *smack_inode(const struct inode *inode) return inode->i_security; } +static inline struct smack_known **smack_msg_msg(const struct msg_msg *msg) +{ + return (struct smack_known **)>security; +} + +static inline struct smack_known **smack_ipc(const struct kern_ipc_perm *ipc) +{ + return (struct smack_known **)>security; +} + /* * Is the directory transmuting? */ diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 6617abb51732..4afc8899f83f 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -2905,7 +2905,9 @@ static void smack_msg_msg_free_security(struct msg_msg *msg) */ static struct smack_known *smack_of_ipc(struct kern_ipc_perm *isp) { - return (struct smack_known *)isp->security; + struct smack_known **blob = smack_ipc(isp); + + return *blob; } /** @@ -2916,9 +2918,9 @@ static struct smack_known *smack_of_ipc(struct kern_ipc_perm *isp) */ static int smack_ipc_alloc_security(struct kern_ipc_perm *isp) { - struct smack_known *skp = smk_of_current(); + struct smack_known **blob = smack_ipc(isp); - isp->security = skp; + *blob = smk_of_current(); return 0; } @@ -3230,7 +3232,8 @@ static int smack_msg_queue_msgrcv(struct kern_ipc_perm *isp, struct msg_msg *msg */ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) { - struct smack_known *iskp = ipp->security; + struct smack_known **blob = smack_ipc(ipp); + struct smack_known *iskp = *blob; int may = smack_flags_to_may(flag); struct smk_audit_info ad; int rc; @@ -3251,7 +3254,8 @@ static int smack_ipc_permission(struct kern_ipc_perm *ipp, short flag) */ static void smack_ipc_getsecid(struct kern_ipc_perm *ipp, u32 *secid) { - struct smack_known *iskp = ipp->security; + struct smack_known **blob = smack_ipc(ipp); + struct smack_known *iskp = *blob; *secid = iskp->smk_secid; } -- 2.17.1 ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
Re: [PATCH v4 05/19] SELinux: Remove unused selinux_is_enabled
On Fri, Sep 21, 2018 at 5:17 PM, Casey Schaufler wrote: > There are no longer users of selinux_is_enabled(). > Remove it. As selinux_is_enabled() is the only reason > for include/linux/selinux.h remove that as well. > > Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook -Kees -- Kees Cook Pixel Security ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH v4 12/19] SELinux: Abstract use of inode security blob
Don't use the inode->i_security pointer directly. Provide a helper function that provides the security blob pointer. Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook --- security/selinux/hooks.c | 26 +- security/selinux/include/objsec.h | 6 ++ security/selinux/selinuxfs.c | 4 ++-- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index fdda53552224..248ae907320f 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -275,7 +275,7 @@ static int __inode_security_revalidate(struct inode *inode, struct dentry *dentry, bool may_sleep) { - struct inode_security_struct *isec = inode->i_security; + struct inode_security_struct *isec = selinux_inode(inode); might_sleep_if(may_sleep); @@ -296,7 +296,7 @@ static int __inode_security_revalidate(struct inode *inode, static struct inode_security_struct *inode_security_novalidate(struct inode *inode) { - return inode->i_security; + return selinux_inode(inode); } static struct inode_security_struct *inode_security_rcu(struct inode *inode, bool rcu) @@ -306,7 +306,7 @@ static struct inode_security_struct *inode_security_rcu(struct inode *inode, boo error = __inode_security_revalidate(inode, NULL, !rcu); if (error) return ERR_PTR(error); - return inode->i_security; + return selinux_inode(inode); } /* @@ -315,14 +315,14 @@ static struct inode_security_struct *inode_security_rcu(struct inode *inode, boo static struct inode_security_struct *inode_security(struct inode *inode) { __inode_security_revalidate(inode, NULL, true); - return inode->i_security; + return selinux_inode(inode); } static struct inode_security_struct *backing_inode_security_novalidate(struct dentry *dentry) { struct inode *inode = d_backing_inode(dentry); - return inode->i_security; + return selinux_inode(inode); } /* @@ -333,7 +333,7 @@ static struct inode_security_struct *backing_inode_security(struct dentry *dentr struct inode *inode = d_backing_inode(dentry); __inode_security_revalidate(inode, dentry, true); - return inode->i_security; + return selinux_inode(inode); } static void inode_free_rcu(struct rcu_head *head) @@ -346,7 +346,7 @@ static void inode_free_rcu(struct rcu_head *head) static void inode_free_security(struct inode *inode) { - struct inode_security_struct *isec = inode->i_security; + struct inode_security_struct *isec = selinux_inode(inode); struct superblock_security_struct *sbsec = inode->i_sb->s_security; /* @@ -1500,7 +1500,7 @@ static int selinux_genfs_get_sid(struct dentry *dentry, static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry) { struct superblock_security_struct *sbsec = NULL; - struct inode_security_struct *isec = inode->i_security; + struct inode_security_struct *isec = selinux_inode(inode); u32 task_sid, sid = 0; u16 sclass; struct dentry *dentry; @@ -1800,7 +1800,7 @@ static int inode_has_perm(const struct cred *cred, return 0; sid = cred_sid(cred); - isec = inode->i_security; + isec = selinux_inode(inode); return avc_has_perm(_state, sid, isec->sid, isec->sclass, perms, adp); @@ -3028,7 +3028,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, /* Possibly defer initialization to selinux_complete_init. */ if (sbsec->flags & SE_SBINITIALIZED) { - struct inode_security_struct *isec = inode->i_security; + struct inode_security_struct *isec = selinux_inode(inode); isec->sclass = inode_mode_to_security_class(inode->i_mode); isec->sid = newsid; isec->initialized = LABEL_INITIALIZED; @@ -3128,7 +3128,7 @@ static noinline int audit_inode_permission(struct inode *inode, unsigned flags) { struct common_audit_data ad; - struct inode_security_struct *isec = inode->i_security; + struct inode_security_struct *isec = selinux_inode(inode); int rc; ad.type = LSM_AUDIT_DATA_INODE; @@ -4148,7 +4148,7 @@ static int selinux_task_kill(struct task_struct *p, struct siginfo *info, static void selinux_task_to_inode(struct task_struct *p, struct inode *inode) { - struct inode_security_struct *isec = inode->i_security; + struct inode_security_struct *isec = selinux_inode(inode); u32 sid = task_sid(p); spin_lock(>lock); @@ -6527,7 +6527,7 @@ static void selinux_release_secctx(char *secdata, u32 seclen) static void
[PATCH v4 10/19] Smack: Abstract use of file security blob
Don't use the file->f_security pointer directly. Provide a helper function that provides the security blob pointer. Signed-off-by: Casey Schaufler --- security/smack/smack.h | 5 + security/smack/smack_lsm.c | 12 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/security/smack/smack.h b/security/smack/smack.h index 01a922856eba..22ca30379209 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -361,6 +361,11 @@ static inline struct task_smack *smack_cred(const struct cred *cred) return cred->security; } +static inline struct smack_known **smack_file(const struct file *file) +{ + return (struct smack_known **)>f_security; +} + /* * Is the directory transmuting? */ diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index a06ea8aa89c4..9ec595f0c3f1 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -1571,9 +1571,9 @@ static void smack_inode_getsecid(struct inode *inode, u32 *secid) */ static int smack_file_alloc_security(struct file *file) { - struct smack_known *skp = smk_of_current(); + struct smack_known **blob = smack_file(file); - file->f_security = skp; + *blob = smk_of_current(); return 0; } @@ -1813,7 +1813,9 @@ static int smack_mmap_file(struct file *file, */ static void smack_file_set_fowner(struct file *file) { - file->f_security = smk_of_current(); + struct smack_known **blob = smack_file(file); + + *blob = smk_of_current(); } /** @@ -1830,6 +1832,7 @@ static void smack_file_set_fowner(struct file *file) static int smack_file_send_sigiotask(struct task_struct *tsk, struct fown_struct *fown, int signum) { + struct smack_known **blob; struct smack_known *skp; struct smack_known *tkp = smk_of_task(smack_cred(tsk->cred)); struct file *file; @@ -1842,7 +1845,8 @@ static int smack_file_send_sigiotask(struct task_struct *tsk, file = container_of(fown, struct file, f_owner); /* we don't log here as rc can be overriden */ - skp = file->f_security; + blob = smack_file(file); + skp = *blob; rc = smk_access(skp, tkp, MAY_DELIVER, NULL); rc = smk_bu_note("sigiotask", skp, tkp, MAY_DELIVER, rc); if (rc != 0 && has_capability(tsk, CAP_MAC_OVERRIDE)) -- 2.17.1 ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH v4 08/19] Infrastructure management of the cred security blob
Move management of the cred security blob out of the security modules and into the security infrastructre. Instead of allocating and freeing space the security modules tell the infrastructure how much space they require. Signed-off-by: Casey Schaufler --- include/linux/lsm_hooks.h | 14 security/Kconfig | 11 security/apparmor/lsm.c | 18 + security/security.c | 106 +- security/selinux/hooks.c | 58 +--- security/selinux/include/objsec.h | 2 + security/smack/smack_lsm.c| 85 +--- security/tomoyo/common.h | 2 +- security/tomoyo/tomoyo.c | 16 - 9 files changed, 212 insertions(+), 100 deletions(-) diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index 97a020c616ad..0bef312efd45 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h @@ -2024,6 +2024,13 @@ struct security_hook_list { char*lsm; } __randomize_layout; +/* + * Security blob size or offset data. + */ +struct lsm_blob_sizes { + int lbs_cred; +}; + /* * Initializing a security_hook_list structure takes * up a lot of space in a source file. This macro takes @@ -2036,6 +2043,7 @@ struct security_hook_list { extern struct security_hook_heads security_hook_heads; extern char *lsm_names; +extern void security_add_blobs(struct lsm_blob_sizes *needed); extern void security_add_hooks(struct security_hook_list *hooks, int count, char *lsm); @@ -2082,4 +2090,10 @@ void __init loadpin_add_hooks(void); static inline void loadpin_add_hooks(void) { }; #endif +extern int lsm_cred_alloc(struct cred *cred, gfp_t gfp); + +#ifdef CONFIG_SECURITY +void lsm_early_cred(struct cred *cred); +#endif + #endif /* ! __LINUX_LSM_HOOKS_H */ diff --git a/security/Kconfig b/security/Kconfig index 27d8b2688f75..22f7664c4977 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -36,6 +36,17 @@ config SECURITY_WRITABLE_HOOKS bool default n +config SECURITY_LSM_DEBUG + bool "Enable debugging of the LSM infrastructure" + depends on SECURITY + help + This allows you to choose debug messages related to + security modules configured into your kernel. These + messages may be helpful in determining how a security + module is using security blobs. + + If you are unsure how to answer this question, answer N. + config SECURITYFS bool "Enable the securityfs filesystem" help diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 4f51705c3c71..c2566aaa138e 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -1126,6 +1126,13 @@ static void apparmor_sock_graft(struct sock *sk, struct socket *parent) ctx->label = aa_get_current_label(); } +/* + * The cred blob is a pointer to, not an instance of, an aa_task_ctx. + */ +struct lsm_blob_sizes apparmor_blob_sizes = { + .lbs_cred = sizeof(struct aa_task_ctx *), +}; + static struct security_hook_list apparmor_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(ptrace_access_check, apparmor_ptrace_access_check), LSM_HOOK_INIT(ptrace_traceme, apparmor_ptrace_traceme), @@ -1455,6 +1462,7 @@ static int __init set_init_ctx(void) if (!ctx) return -ENOMEM; + lsm_early_cred(cred); set_cred_label(cred, aa_get_label(ns_unconfined(root_ns))); task_ctx(current) = ctx; @@ -1540,8 +1548,18 @@ static inline int apparmor_init_sysctl(void) static int __init apparmor_init(void) { + static int finish; int error; + if (!finish) { + if (apparmor_enabled && security_module_enable("apparmor")) + security_add_blobs(_blob_sizes); + else + apparmor_enabled = false; + finish = 1; + return 0; + } + if (!apparmor_enabled || !security_module_enable("apparmor")) { aa_info_message("AppArmor disabled by boot time parameter"); apparmor_enabled = false; diff --git a/security/security.c b/security/security.c index 3dfe75d0d373..ff7df14f6db1 100644 --- a/security/security.c +++ b/security/security.c @@ -41,6 +41,8 @@ struct security_hook_heads security_hook_heads __lsm_ro_after_init; static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain); char *lsm_names; +static struct lsm_blob_sizes blob_sizes; + /* Boot-time LSM user choice */ static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] = CONFIG_DEFAULT_SECURITY; @@ -85,10 +87,22 @@ int __init security_init(void) loadpin_add_hooks(); /* -* Load all the remaining security modules. +* The first call to a module specific init function +* updates the blob size requirements. +*/ +
[PATCH v4 06/19] AppArmor: Abstract use of cred security blob
Don't use the cred->security pointer directly. Provide a helper function that provides the security blob pointer. Signed-off-by: Casey Schaufler --- security/apparmor/domain.c | 2 +- security/apparmor/include/cred.h | 16 +++- security/apparmor/lsm.c | 10 +- security/apparmor/task.c | 6 +++--- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 08c88de0ffda..726910bba84b 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c @@ -975,7 +975,7 @@ int apparmor_bprm_set_creds(struct linux_binprm *bprm) } aa_put_label(cred_label(bprm->cred)); /* transfer reference, released when cred is freed */ - cred_label(bprm->cred) = new; + set_cred_label(bprm->cred, new); done: aa_put_label(label); diff --git a/security/apparmor/include/cred.h b/security/apparmor/include/cred.h index e287b7d0d4be..a90eae76d7c1 100644 --- a/security/apparmor/include/cred.h +++ b/security/apparmor/include/cred.h @@ -23,8 +23,22 @@ #include "policy_ns.h" #include "task.h" -#define cred_label(X) ((X)->security) +static inline struct aa_label *cred_label(const struct cred *cred) +{ + struct aa_label **blob = cred->security; + + AA_BUG(!blob); + return *blob; +} +static inline void set_cred_label(const struct cred *cred, + struct aa_label *label) +{ + struct aa_label **blob = cred->security; + + AA_BUG(!blob); + *blob = label; +} /** * aa_cred_raw_label - obtain cred's label diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c index 8b8b70620bbe..4f51705c3c71 100644 --- a/security/apparmor/lsm.c +++ b/security/apparmor/lsm.c @@ -57,7 +57,7 @@ DEFINE_PER_CPU(struct aa_buffers, aa_buffers); static void apparmor_cred_free(struct cred *cred) { aa_put_label(cred_label(cred)); - cred_label(cred) = NULL; + set_cred_label(cred, NULL); } /* @@ -65,7 +65,7 @@ static void apparmor_cred_free(struct cred *cred) */ static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp) { - cred_label(cred) = NULL; + set_cred_label(cred, NULL); return 0; } @@ -75,7 +75,7 @@ static int apparmor_cred_alloc_blank(struct cred *cred, gfp_t gfp) static int apparmor_cred_prepare(struct cred *new, const struct cred *old, gfp_t gfp) { - cred_label(new) = aa_get_newest_label(cred_label(old)); + set_cred_label(new, aa_get_newest_label(cred_label(old))); return 0; } @@ -84,7 +84,7 @@ static int apparmor_cred_prepare(struct cred *new, const struct cred *old, */ static void apparmor_cred_transfer(struct cred *new, const struct cred *old) { - cred_label(new) = aa_get_newest_label(cred_label(old)); + set_cred_label(new, aa_get_newest_label(cred_label(old))); } static void apparmor_task_free(struct task_struct *task) @@ -1455,7 +1455,7 @@ static int __init set_init_ctx(void) if (!ctx) return -ENOMEM; - cred_label(cred) = aa_get_label(ns_unconfined(root_ns)); + set_cred_label(cred, aa_get_label(ns_unconfined(root_ns))); task_ctx(current) = ctx; return 0; diff --git a/security/apparmor/task.c b/security/apparmor/task.c index c6b78a14da91..4551110f0496 100644 --- a/security/apparmor/task.c +++ b/security/apparmor/task.c @@ -81,7 +81,7 @@ int aa_replace_current_label(struct aa_label *label) */ aa_get_label(label); aa_put_label(cred_label(new)); - cred_label(new) = label; + set_cred_label(new, label); commit_creds(new); return 0; @@ -138,7 +138,7 @@ int aa_set_current_hat(struct aa_label *label, u64 token) return -EACCES; } - cred_label(new) = aa_get_newest_label(label); + set_cred_label(new, aa_get_newest_label(label)); /* clear exec on switching context */ aa_put_label(ctx->onexec); ctx->onexec = NULL; @@ -172,7 +172,7 @@ int aa_restore_previous_label(u64 token) return -ENOMEM; aa_put_label(cred_label(new)); - cred_label(new) = aa_get_newest_label(ctx->previous); + set_cred_label(new, aa_get_newest_label(ctx->previous)); AA_BUG(!cred_label(new)); /* clear exec && prev information when restoring to previous context */ aa_clear_task_ctx_trans(ctx); -- 2.17.1 ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH v4 07/19] TOMOYO: Abstract use of cred security blob
Don't use the cred->security pointer directly. Provide helper functions that provide the security blob pointer. Signed-off-by: Casey Schaufler --- security/tomoyo/common.h| 21 +++-- security/tomoyo/domain.c| 4 +++- security/tomoyo/securityfs_if.c | 15 + security/tomoyo/tomoyo.c| 40 + 4 files changed, 64 insertions(+), 16 deletions(-) diff --git a/security/tomoyo/common.h b/security/tomoyo/common.h index 539bcdd30bb8..c9d8c49e3210 100644 --- a/security/tomoyo/common.h +++ b/security/tomoyo/common.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -1062,6 +1063,7 @@ void tomoyo_write_log2(struct tomoyo_request_info *r, int len, const char *fmt, /** External variable definitions. **/ extern bool tomoyo_policy_loaded; +extern bool tomoyo_enabled; extern const char * const tomoyo_condition_keyword [TOMOYO_MAX_CONDITION_KEYWORD]; extern const char * const tomoyo_dif[TOMOYO_MAX_DOMAIN_INFO_FLAGS]; @@ -1196,6 +1198,17 @@ static inline void tomoyo_put_group(struct tomoyo_group *group) atomic_dec(>head.users); } +/** + * tomoyo_cred - Get a pointer to the tomoyo cred security blob + * @cred - the relevant cred + * + * Returns pointer to the tomoyo cred blob. + */ +static inline struct tomoyo_domain_info **tomoyo_cred(const struct cred *cred) +{ + return (struct tomoyo_domain_info **)>security; +} + /** * tomoyo_domain - Get "struct tomoyo_domain_info" for current thread. * @@ -1203,7 +1216,9 @@ static inline void tomoyo_put_group(struct tomoyo_group *group) */ static inline struct tomoyo_domain_info *tomoyo_domain(void) { - return current_cred()->security; + struct tomoyo_domain_info **blob = tomoyo_cred(current_cred()); + + return *blob; } /** @@ -1216,7 +1231,9 @@ static inline struct tomoyo_domain_info *tomoyo_domain(void) static inline struct tomoyo_domain_info *tomoyo_real_domain(struct task_struct *task) { - return task_cred_xxx(task, security); + struct tomoyo_domain_info **blob = tomoyo_cred(get_task_cred(task)); + + return *blob; } /** diff --git a/security/tomoyo/domain.c b/security/tomoyo/domain.c index f6758dad981f..b7469fdbff01 100644 --- a/security/tomoyo/domain.c +++ b/security/tomoyo/domain.c @@ -678,6 +678,7 @@ static int tomoyo_environ(struct tomoyo_execve *ee) */ int tomoyo_find_next_domain(struct linux_binprm *bprm) { + struct tomoyo_domain_info **blob; struct tomoyo_domain_info *old_domain = tomoyo_domain(); struct tomoyo_domain_info *domain = NULL; const char *original_name = bprm->filename; @@ -843,7 +844,8 @@ int tomoyo_find_next_domain(struct linux_binprm *bprm) domain = old_domain; /* Update reference count on "struct tomoyo_domain_info". */ atomic_inc(>users); - bprm->cred->security = domain; + blob = tomoyo_cred(bprm->cred); + *blob = domain; kfree(exename.name); if (!retval) { ee->r.domain = domain; diff --git a/security/tomoyo/securityfs_if.c b/security/tomoyo/securityfs_if.c index 1d3d7e7a1f05..768dff9608b1 100644 --- a/security/tomoyo/securityfs_if.c +++ b/security/tomoyo/securityfs_if.c @@ -71,9 +71,12 @@ static ssize_t tomoyo_write_self(struct file *file, const char __user *buf, if (!cred) { error = -ENOMEM; } else { - struct tomoyo_domain_info *old_domain = - cred->security; - cred->security = new_domain; + struct tomoyo_domain_info **blob; + struct tomoyo_domain_info *old_domain; + + blob = tomoyo_cred(cred); + old_domain = *blob; + *blob = new_domain; atomic_inc(_domain->users); atomic_dec(_domain->users); commit_creds(cred); @@ -234,10 +237,14 @@ static void __init tomoyo_create_entry(const char *name, const umode_t mode, */ static int __init tomoyo_initerface_init(void) { + struct tomoyo_domain_info *domain; struct dentry *tomoyo_dir; + if (!tomoyo_enabled) + return 0; + domain = tomoyo_domain(); /* Don't create securityfs entries unless registered. */ - if (current_cred()->security != _kernel_domain) + if (domain != _kernel_domain) return 0; tomoyo_dir = securityfs_create_dir("tomoyo", NULL); diff --git a/security/tomoyo/tomoyo.c
[PATCH v4 03/19] SELinux: Abstract use of cred security blob
Don't use the cred->security pointer directly. Provide a helper function that provides the security blob pointer. Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook --- security/selinux/hooks.c | 54 +++ security/selinux/include/objsec.h | 5 +++ security/selinux/xfrm.c | 4 +-- 3 files changed, 34 insertions(+), 29 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index ad9a9b8e9979..9d6cdd21acb6 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -228,7 +228,7 @@ static inline u32 cred_sid(const struct cred *cred) { const struct task_security_struct *tsec; - tsec = cred->security; + tsec = selinux_cred(cred); return tsec->sid; } @@ -464,7 +464,7 @@ static int may_context_mount_sb_relabel(u32 sid, struct superblock_security_struct *sbsec, const struct cred *cred) { - const struct task_security_struct *tsec = cred->security; + const struct task_security_struct *tsec = selinux_cred(cred); int rc; rc = avc_has_perm(_state, @@ -483,7 +483,7 @@ static int may_context_mount_inode_relabel(u32 sid, struct superblock_security_struct *sbsec, const struct cred *cred) { - const struct task_security_struct *tsec = cred->security; + const struct task_security_struct *tsec = selinux_cred(cred); int rc; rc = avc_has_perm(_state, tsec->sid, sbsec->sid, SECCLASS_FILESYSTEM, @@ -1949,7 +1949,7 @@ static int may_create(struct inode *dir, struct dentry *dentry, u16 tclass) { - const struct task_security_struct *tsec = current_security(); + const struct task_security_struct *tsec = selinux_cred(current_cred()); struct inode_security_struct *dsec; struct superblock_security_struct *sbsec; u32 sid, newsid; @@ -1971,7 +1971,7 @@ static int may_create(struct inode *dir, if (rc) return rc; - rc = selinux_determine_inode_label(current_security(), dir, + rc = selinux_determine_inode_label(selinux_cred(current_cred()), dir, >d_name, tclass, ); if (rc) return rc; @@ -2478,8 +2478,8 @@ static int selinux_bprm_set_creds(struct linux_binprm *bprm) if (bprm->called_set_creds) return 0; - old_tsec = current_security(); - new_tsec = bprm->cred->security; + old_tsec = selinux_cred(current_cred()); + new_tsec = selinux_cred(bprm->cred); isec = inode_security(inode); /* Default to the current task SID. */ @@ -2643,7 +2643,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm) struct rlimit *rlim, *initrlim; int rc, i; - new_tsec = bprm->cred->security; + new_tsec = selinux_cred(bprm->cred); if (new_tsec->sid == new_tsec->osid) return; @@ -2686,7 +2686,7 @@ static void selinux_bprm_committing_creds(struct linux_binprm *bprm) */ static void selinux_bprm_committed_creds(struct linux_binprm *bprm) { - const struct task_security_struct *tsec = current_security(); + const struct task_security_struct *tsec = selinux_cred(current_cred()); struct itimerval itimer; u32 osid, sid; int rc, i; @@ -2989,7 +2989,7 @@ static int selinux_dentry_init_security(struct dentry *dentry, int mode, u32 newsid; int rc; - rc = selinux_determine_inode_label(current_security(), + rc = selinux_determine_inode_label(selinux_cred(current_cred()), d_inode(dentry->d_parent), name, inode_mode_to_security_class(mode), ); @@ -3009,14 +3009,14 @@ static int selinux_dentry_create_files_as(struct dentry *dentry, int mode, int rc; struct task_security_struct *tsec; - rc = selinux_determine_inode_label(old->security, + rc = selinux_determine_inode_label(selinux_cred(old), d_inode(dentry->d_parent), name, inode_mode_to_security_class(mode), ); if (rc) return rc; - tsec = new->security; + tsec = selinux_cred(new); tsec->create_sid = newsid; return 0; } @@ -3026,7 +3026,7 @@ static int selinux_inode_init_security(struct inode *inode, struct inode *dir, const char **name, void **value, size_t *len) { - const struct task_security_struct *tsec = current_security(); + const struct task_security_struct *tsec = selinux_cred(current_cred()); struct
[PATCH v4 05/19] SELinux: Remove unused selinux_is_enabled
There are no longer users of selinux_is_enabled(). Remove it. As selinux_is_enabled() is the only reason for include/linux/selinux.h remove that as well. Signed-off-by: Casey Schaufler --- include/linux/cred.h | 1 - include/linux/selinux.h | 35 security/selinux/Makefile| 2 +- security/selinux/exports.c | 23 - security/selinux/hooks.c | 1 - security/selinux/include/audit.h | 3 --- security/selinux/ss/services.c | 1 - 7 files changed, 1 insertion(+), 65 deletions(-) delete mode 100644 include/linux/selinux.h delete mode 100644 security/selinux/exports.c diff --git a/include/linux/cred.h b/include/linux/cred.h index 7eed6101c791..2e715e202e6a 100644 --- a/include/linux/cred.h +++ b/include/linux/cred.h @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/include/linux/selinux.h b/include/linux/selinux.h deleted file mode 100644 index 44f459612690.. --- a/include/linux/selinux.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SELinux services exported to the rest of the kernel. - * - * Author: James Morris - * - * Copyright (C) 2005 Red Hat, Inc., James Morris - * Copyright (C) 2006 Trusted Computer Solutions, Inc. - * Copyright (C) 2006 IBM Corporation, Timothy R. Chavez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * as published by the Free Software Foundation. - */ -#ifndef _LINUX_SELINUX_H -#define _LINUX_SELINUX_H - -struct selinux_audit_rule; -struct audit_context; -struct kern_ipc_perm; - -#ifdef CONFIG_SECURITY_SELINUX - -/** - * selinux_is_enabled - is SELinux enabled? - */ -bool selinux_is_enabled(void); -#else - -static inline bool selinux_is_enabled(void) -{ - return false; -} -#endif /* CONFIG_SECURITY_SELINUX */ - -#endif /* _LINUX_SELINUX_H */ diff --git a/security/selinux/Makefile b/security/selinux/Makefile index c7161f8792b2..ccf950409384 100644 --- a/security/selinux/Makefile +++ b/security/selinux/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_SECURITY_SELINUX) := selinux.o selinux-y := avc.o hooks.o selinuxfs.o netlink.o nlmsgtab.o netif.o \ -netnode.o netport.o ibpkey.o exports.o \ +netnode.o netport.o ibpkey.o \ ss/ebitmap.o ss/hashtab.o ss/symtab.o ss/sidtab.o ss/avtab.o \ ss/policydb.o ss/services.o ss/conditional.o ss/mls.o ss/status.o diff --git a/security/selinux/exports.c b/security/selinux/exports.c deleted file mode 100644 index e75dd94e2d2b.. --- a/security/selinux/exports.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * SELinux services exported to the rest of the kernel. - * - * Author: James Morris - * - * Copyright (C) 2005 Red Hat, Inc., James Morris - * Copyright (C) 2006 Trusted Computer Solutions, Inc. - * Copyright (C) 2006 IBM Corporation, Timothy R. Chavez - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * as published by the Free Software Foundation. - */ -#include -#include - -#include "security.h" - -bool selinux_is_enabled(void) -{ - return selinux_enabled; -} -EXPORT_SYMBOL_GPL(selinux_is_enabled); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 80614ca25a2b..82b28ee878c4 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -79,7 +79,6 @@ #include #include #include -#include #include #include #include diff --git a/security/selinux/include/audit.h b/security/selinux/include/audit.h index 1bdf973433cc..36e1d44c0209 100644 --- a/security/selinux/include/audit.h +++ b/security/selinux/include/audit.h @@ -1,9 +1,6 @@ /* * SELinux support for the Audit LSM hooks * - * Most of below header was moved from include/linux/selinux.h which - * is released under below copyrights: - * * Author: James Morris * * Copyright (C) 2005 Red Hat, Inc., James Morris diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index f3def298a90e..e2235f1a99aa 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include -- 2.17.1 ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH v4 04/19] SELinux: Remove cred security blob poisoning
The SELinux specific credential poisioning only makes sense if SELinux is managing the credentials. As the intent of this patch set is to move the blob management out of the modules and into the infrastructure, the SELinux specific code has to go. The poisioning could be introduced into the infrastructure at some later date. Signed-off-by: Casey Schaufler --- kernel/cred.c| 13 - security/selinux/hooks.c | 6 -- 2 files changed, 19 deletions(-) diff --git a/kernel/cred.c b/kernel/cred.c index ecf03657e71c..fa2061ee4955 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -704,19 +704,6 @@ bool creds_are_invalid(const struct cred *cred) { if (cred->magic != CRED_MAGIC) return true; -#ifdef CONFIG_SECURITY_SELINUX - /* -* cred->security == NULL if security_cred_alloc_blank() or -* security_prepare_creds() returned an error. -*/ - if (selinux_is_enabled() && cred->security) { - if ((unsigned long) cred->security < PAGE_SIZE) - return true; - if ((*(u32 *)cred->security & 0xff00) == - (POISON_FREE << 24 | POISON_FREE << 16 | POISON_FREE << 8)) - return true; - } -#endif return false; } EXPORT_SYMBOL(creds_are_invalid); diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 9d6cdd21acb6..80614ca25a2b 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -3920,12 +3920,6 @@ static void selinux_cred_free(struct cred *cred) { struct task_security_struct *tsec = selinux_cred(cred); - /* -* cred->security == NULL if security_cred_alloc_blank() or -* security_prepare_creds() returned an error. -*/ - BUG_ON(cred->security && (unsigned long) cred->security < PAGE_SIZE); - cred->security = (void *) 0x7UL; kfree(tsec); } -- 2.17.1 ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH v4 01/19] procfs: add smack subdir to attrs
Back in 2007 I made what turned out to be a rather serious mistake in the implementation of the Smack security module. The SELinux module used an interface in /proc to manipulate the security context on processes. Rather than use a similar interface, I used the same interface. The AppArmor team did likewise. Now /proc/.../attr/current will tell you the security "context" of the process, but it will be different depending on the security module you're using. This patch provides a subdirectory in /proc/.../attr for Smack. Smack user space can use the "current" file in this subdirectory and never have to worry about getting SELinux attributes by mistake. Programs that use the old interface will continue to work (or fail, as the case may be) as before. The proposed S.A.R.A security module is dependent on the mechanism to create its own attr subdirectory. The original implementation is by Kees Cook. Signed-off-by: Casey Schaufler Reviewed-by: Kees Cook --- Documentation/admin-guide/LSM/index.rst | 13 +++-- fs/proc/base.c | 64 + fs/proc/internal.h | 1 + include/linux/security.h| 15 -- security/security.c | 24 -- 5 files changed, 96 insertions(+), 21 deletions(-) diff --git a/Documentation/admin-guide/LSM/index.rst b/Documentation/admin-guide/LSM/index.rst index c980dfe9abf1..9842e21afd4a 100644 --- a/Documentation/admin-guide/LSM/index.rst +++ b/Documentation/admin-guide/LSM/index.rst @@ -17,9 +17,8 @@ MAC extensions, other extensions can be built using the LSM to provide specific changes to system operation when these tweaks are not available in the core functionality of Linux itself. -Without a specific LSM built into the kernel, the default LSM will be the -Linux capabilities system. Most LSMs choose to extend the capabilities -system, building their checks on top of the defined capability hooks. +The Linux capabilities modules will always be included. This may be +followed by any number of "minor" modules and at most one "major" module. For more details on capabilities, see ``capabilities(7)`` in the Linux man-pages project. @@ -30,6 +29,14 @@ order in which checks are made. The capability module will always be first, followed by any "minor" modules (e.g. Yama) and then the one "major" module (e.g. SELinux) if there is one configured. +Process attributes associated with "major" security modules should +be accessed and maintained using the special files in ``/proc/.../attr``. +A security module may maintain a module specific subdirectory there, +named after the module. ``/proc/.../attr/smack`` is provided by the Smack +security module and contains all its special files. The files directly +in ``/proc/.../attr`` remain as legacy interfaces for modules that provide +subdirectories. + .. toctree:: :maxdepth: 1 diff --git a/fs/proc/base.c b/fs/proc/base.c index ccf86f16d9f0..bd2dd85310fe 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -140,9 +140,13 @@ struct pid_entry { #define REG(NAME, MODE, fops) \ NOD(NAME, (S_IFREG|(MODE)), NULL, , {}) #define ONE(NAME, MODE, show) \ - NOD(NAME, (S_IFREG|(MODE)), \ + NOD(NAME, (S_IFREG|(MODE)), \ NULL, _single_file_operations, \ { .proc_show = show } ) +#define ATTR(LSM, NAME, MODE) \ + NOD(NAME, (S_IFREG|(MODE)), \ + NULL, _pid_attr_operations,\ + { .lsm = LSM }) /* * Count the number of hardlinks for the pid_entry table, excluding the . @@ -2503,7 +2507,7 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, if (!task) return -ESRCH; - length = security_getprocattr(task, + length = security_getprocattr(task, PROC_I(inode)->op.lsm, (char*)file->f_path.dentry->d_name.name, ); put_task_struct(task); @@ -2552,7 +2556,9 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, if (rv < 0) goto out_free; - rv = security_setprocattr(file->f_path.dentry->d_name.name, page, count); + rv = security_setprocattr(PROC_I(inode)->op.lsm, + file->f_path.dentry->d_name.name, page, + count); mutex_unlock(>signal->cred_guard_mutex); out_free: kfree(page); @@ -2566,13 +2572,53 @@ static const struct file_operations proc_pid_attr_operations = { .llseek = generic_file_llseek, }; +#define LSM_DIR_OPS(LSM) \ +static int proc_##LSM##_attr_dir_iterate(struct file *filp, \ +struct dir_context *ctx) \ +{ \ + return proc_pident_readdir(filp, ctx, \ +
[PATCH v4 02/19] Smack: Abstract use of cred security blob
Don't use the cred->security pointer directly. Provide a helper function that provides the security blob pointer. Signed-off-by: Casey Schaufler --- security/smack/smack.h| 17 +-- security/smack/smack_access.c | 4 +-- security/smack/smack_lsm.c| 57 +-- security/smack/smackfs.c | 18 +-- 4 files changed, 53 insertions(+), 43 deletions(-) diff --git a/security/smack/smack.h b/security/smack/smack.h index f7db791fb566..01a922856eba 100644 --- a/security/smack/smack.h +++ b/security/smack/smack.h @@ -356,6 +356,11 @@ extern struct list_head smack_onlycap_list; #define SMACK_HASH_SLOTS 16 extern struct hlist_head smack_known_hash[SMACK_HASH_SLOTS]; +static inline struct task_smack *smack_cred(const struct cred *cred) +{ + return cred->security; +} + /* * Is the directory transmuting? */ @@ -382,13 +387,19 @@ static inline struct smack_known *smk_of_task(const struct task_smack *tsp) return tsp->smk_task; } -static inline struct smack_known *smk_of_task_struct(const struct task_struct *t) +static inline struct smack_known *smk_of_task_struct( + const struct task_struct *t) { struct smack_known *skp; + const struct cred *cred; rcu_read_lock(); - skp = smk_of_task(__task_cred(t)->security); + + cred = __task_cred(t); + skp = smk_of_task(smack_cred(cred)); + rcu_read_unlock(); + return skp; } @@ -405,7 +416,7 @@ static inline struct smack_known *smk_of_forked(const struct task_smack *tsp) */ static inline struct smack_known *smk_of_current(void) { - return smk_of_task(current_security()); + return smk_of_task(smack_cred(current_cred())); } /* diff --git a/security/smack/smack_access.c b/security/smack/smack_access.c index 9a4c0ad46518..489d49a20b47 100644 --- a/security/smack/smack_access.c +++ b/security/smack/smack_access.c @@ -275,7 +275,7 @@ int smk_tskacc(struct task_smack *tsp, struct smack_known *obj_known, int smk_curacc(struct smack_known *obj_known, u32 mode, struct smk_audit_info *a) { - struct task_smack *tsp = current_security(); + struct task_smack *tsp = smack_cred(current_cred()); return smk_tskacc(tsp, obj_known, mode, a); } @@ -635,7 +635,7 @@ DEFINE_MUTEX(smack_onlycap_lock); */ bool smack_privileged_cred(int cap, const struct cred *cred) { - struct task_smack *tsp = cred->security; + struct task_smack *tsp = smack_cred(cred); struct smack_known *skp = tsp->smk_task; struct smack_known_list_elem *sklep; int rc; diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c index 340fc30ad85d..68ee3ae8f25c 100644 --- a/security/smack/smack_lsm.c +++ b/security/smack/smack_lsm.c @@ -122,7 +122,7 @@ static int smk_bu_note(char *note, struct smack_known *sskp, static int smk_bu_current(char *note, struct smack_known *oskp, int mode, int rc) { - struct task_smack *tsp = current_security(); + struct task_smack *tsp = smack_cred(current_cred()); char acc[SMK_NUM_ACCESS_TYPE + 1]; if (rc <= 0) @@ -143,7 +143,7 @@ static int smk_bu_current(char *note, struct smack_known *oskp, #ifdef CONFIG_SECURITY_SMACK_BRINGUP static int smk_bu_task(struct task_struct *otp, int mode, int rc) { - struct task_smack *tsp = current_security(); + struct task_smack *tsp = smack_cred(current_cred()); struct smack_known *smk_task = smk_of_task_struct(otp); char acc[SMK_NUM_ACCESS_TYPE + 1]; @@ -165,7 +165,7 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc) #ifdef CONFIG_SECURITY_SMACK_BRINGUP static int smk_bu_inode(struct inode *inode, int mode, int rc) { - struct task_smack *tsp = current_security(); + struct task_smack *tsp = smack_cred(current_cred()); struct inode_smack *isp = inode->i_security; char acc[SMK_NUM_ACCESS_TYPE + 1]; @@ -195,7 +195,7 @@ static int smk_bu_inode(struct inode *inode, int mode, int rc) #ifdef CONFIG_SECURITY_SMACK_BRINGUP static int smk_bu_file(struct file *file, int mode, int rc) { - struct task_smack *tsp = current_security(); + struct task_smack *tsp = smack_cred(current_cred()); struct smack_known *sskp = tsp->smk_task; struct inode *inode = file_inode(file); struct inode_smack *isp = inode->i_security; @@ -225,7 +225,7 @@ static int smk_bu_file(struct file *file, int mode, int rc) static int smk_bu_credfile(const struct cred *cred, struct file *file, int mode, int rc) { - struct task_smack *tsp = cred->security; + struct task_smack *tsp = smack_cred(cred); struct smack_known *sskp = tsp->smk_task; struct inode *inode = file_inode(file); struct inode_smack *isp = inode->i_security; @@ -429,7 +429,7 @@ static int
[PATCH v4 00/19] LSM: Module stacking for SARA and Landlock
v4: Finer granularity in the patches and other cleanups suggested by Kees Cook. Removed dead code created by the removal of SELinux credential blob poisoning. v3: Add ipc blob for SARA and task blob for Landlock. Removing the SELinux cred blob pointer poisoning results selinux_is_enabled() being unused, so it and all it's overhead has been removed. Broke up the cred infrastructure patch. v2: Reduce the patchset to what is required to support the proposed SARA and LandLock security modules The SARA security module is intended to be used in conjunction with other security modules. It requires state to be maintained for the credential, which in turn requires a mechanism for sharing the credential security blob. It also uses the ipc security blob. The module also requires mechanism for user space manipulation of the credential information, hence an additional subdirectory in /proc/.../attr. The LandLock security module provides user configurable policy in the secmark mechanism. It requires data in the credential, file, inode and task security blobs. For this to be used along side the existing "major" security modules mechanism for sharing these blobs are provided. A side effect of providing sharing of the crendential security blob is that the TOMOYO module can be used at the same time as the other "major" modules. The mechanism for configuring which security modules are enabled has to change when stacking in enabled. Any module that uses just the security blobs that are shared can be selected. Additionally, one other "major" module can be selected. The security module stacking issues around networking and IPC are not addressed here as they are beyond what is required for TOMOYO, SARA and LandLock. git://github.com/cschaufler/lsm-stacking.git#stacking-4.19-rc2-saralock-v4 Signed-off-by: Casey Schaufler --- Documentation/admin-guide/LSM/index.rst | 23 +- fs/proc/base.c | 64 - fs/proc/internal.h | 1 + include/linux/cred.h| 1 - include/linux/lsm_hooks.h | 24 +- include/linux/security.h| 15 +- include/linux/selinux.h | 35 --- kernel/cred.c | 13 - security/Kconfig| 92 +++ security/apparmor/domain.c | 2 +- security/apparmor/include/cred.h| 24 +- security/apparmor/include/file.h| 9 +- security/apparmor/include/lib.h | 4 + security/apparmor/include/task.h| 18 +- security/apparmor/lsm.c | 68 +++-- security/apparmor/task.c| 6 +- security/security.c | 438 ++-- security/selinux/Makefile | 2 +- security/selinux/exports.c | 23 -- security/selinux/hooks.c| 333 +++- security/selinux/include/audit.h| 3 - security/selinux/include/objsec.h | 48 +++- security/selinux/selinuxfs.c| 4 +- security/selinux/ss/services.c | 1 - security/selinux/xfrm.c | 4 +- security/smack/smack.h | 55 +++- security/smack/smack_access.c | 4 +- security/smack/smack_lsm.c | 315 --- security/smack/smackfs.c| 18 +- security/tomoyo/common.h| 26 +- security/tomoyo/domain.c| 4 +- security/tomoyo/securityfs_if.c | 15 +- security/tomoyo/tomoyo.c| 57 - 33 files changed, 1098 insertions(+), 651 deletions(-) ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.
[PATCH] python/sepolicy: Update to work with setools-4.2.0
Change in internal setools API causes sepolicy to crash when processing AVRules. File "python/sepolicy/sepolicy/__init__.py", line 277, in _setools_rule_to_dict if isinstance(rule, setools.policyrep.terule.AVRule): AttributeError: module 'setools.policyrep' has no attribute 'terule' See https://github.com/SELinuxProject/setools/issues/8 for more details. Stop using internal setools API: - use AttributeError instead of setools specific exceptions - evaluate conditional expressions using conditional.evaluate() instead of qpol_symbol.is_enabled() Signed-off-by: Vit Mojzis --- Thank you for the testing. Your commit message is way more descriptive, so feel free to include it (or just use v2 of your patch instead of this). python/sepolicy/sepolicy/__init__.py | 23 ++- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/python/sepolicy/sepolicy/__init__.py b/python/sepolicy/sepolicy/__init__.py index 2e772867..489c6c6f 100644 --- a/python/sepolicy/sepolicy/__init__.py +++ b/python/sepolicy/sepolicy/__init__.py @@ -278,34 +278,39 @@ def _setools_rule_to_dict(rule): 'class': str(rule.tclass), } +# Evaluate boolean expression associated with given rule (if there is any) try: -enabled = bool(rule.qpol_symbol.is_enabled(rule.policy)) +# Get state of all booleans in the conditional expression +boolstate = {} +for boolean in rule.conditional.booleans: +boolstate[str(boolean)] = boolean.state +#evaluate if the rule is enabled +enabled = rule.conditional.evaluate(**boolstate) == rule.conditional_block + except AttributeError: +# non-conditional rules are always enabled enabled = True -if isinstance(rule, setools.policyrep.terule.AVRule): -d['enabled'] = enabled +d['enabled'] = enabled try: d['permlist'] = list(map(str, rule.perms)) -except setools.policyrep.exception.RuleUseError: +except AttributeError: pass try: d['transtype'] = str(rule.default) -except setools.policyrep.exception.RuleUseError: +except AttributeError: pass try: d['boolean'] = [(str(rule.conditional), enabled)] -except (AttributeError, setools.policyrep.exception.RuleNotConditional): +except AttributeError: pass try: d['filename'] = rule.filename -except (AttributeError, -setools.policyrep.exception.RuleNotConditional, -setools.policyrep.exception.TERuleNoFilename): +except AttributeError: pass return d -- 2.17.1 ___ Selinux mailing list Selinux@tycho.nsa.gov To unsubscribe, send email to selinux-le...@tycho.nsa.gov. To get help, send an email containing "help" to selinux-requ...@tycho.nsa.gov.