Re: [PATCH v5 00/38] LSM: Module stacking for SARA and Landlock

2019-01-09 Thread Casey Schaufler
On 1/8/2019 1:05 PM, James Morris wrote:
> On Mon, 7 Jan 2019, Kees Cook wrote:
>
>> On Tue, Dec 11, 2018 at 1:19 PM Kees Cook  wrote:
>>> On Tue, Dec 11, 2018 at 10:57 AM James Morris  wrote:
>>>> On Tue, 4 Dec 2018, Kees Cook wrote:
>>>>
>>>>> On Mon, Nov 26, 2018 at 3:22 PM Casey Schaufler  
>>>>> wrote:
>>>>>> v5: Include Kees Cook's rework of the lsm command
>>>>>> line interface. Stacking is not conditional.
>>>>> Can you resend this series with corrected "From:" lines in the body, etc?
>>>>>
>>>>> Beyond that, I obviously like it. James, what's needed for this to move 
>>>>> forward?
>>>> If there are no outstanding issues, I plan to merge this for 4.21.
>>> Yeah, it looks good to me. (Excepting getting the authorship sorted.)
>> I didn't see this actually get merged? Was there something that needed
>> fixing? Should I send you a direct pull request for v5.1?
> Yep, please send a new pull request.

Do you want it as is or rebased on 5.0-rc1?

___
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 v5 00/38] LSM: Module stacking for SARA and Landlock

2019-01-09 Thread Casey Schaufler
On 1/8/2019 1:42 PM, Kees Cook wrote:
> On Tue, Jan 8, 2019 at 1:37 PM Casey Schaufler  wrote:
>> On 1/8/2019 1:05 PM, James Morris wrote:
>>> On Mon, 7 Jan 2019, Kees Cook wrote:
>>>
>>>> On Tue, Dec 11, 2018 at 1:19 PM Kees Cook  wrote:
>>>>> On Tue, Dec 11, 2018 at 10:57 AM James Morris  wrote:
>>>>>> On Tue, 4 Dec 2018, Kees Cook wrote:
>>>>>>
>>>>>>> On Mon, Nov 26, 2018 at 3:22 PM Casey Schaufler 
>>>>>>>  wrote:
>>>>>>>> v5: Include Kees Cook's rework of the lsm command
>>>>>>>> line interface. Stacking is not conditional.
>>>>>>> Can you resend this series with corrected "From:" lines in the body, 
>>>>>>> etc?
>>>>>>>
>>>>>>> Beyond that, I obviously like it. James, what's needed for this to move 
>>>>>>> forward?
>>>>>> If there are no outstanding issues, I plan to merge this for 4.21.
>>>>> Yeah, it looks good to me. (Excepting getting the authorship sorted.)
>>>> I didn't see this actually get merged? Was there something that needed
>>>> fixing? Should I send you a direct pull request for v5.1?
>>> Yep, please send a new pull request.
>> Do you want it as is or rebased on 5.0-rc1?
> I've rebased to 5.0-rc1, did some light (re)testing, and sent a pull 
> request...

Thank you.


___
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 v5 12/38] apparmor: Remove SECURITY_APPARMOR_BOOTPARAM_VALUE

2018-11-28 Thread Casey Schaufler
In preparation for removing CONFIG_DEFAULT_SECURITY, this removes the
soon-to-be redundant SECURITY_APPARMOR_BOOTPARAM_VALUE. Since explicit
ordering via CONFIG_LSM or "lsm=" will define whether an LSM is enabled or
not, this CONFIG will become effectively ignored, so remove it. However,
in order to stay backward-compatible with "security=apparmor", the enable
variable defaults to true.

Signed-off-by: Kees Cook 
---
 security/apparmor/Kconfig | 16 
 security/apparmor/lsm.c   |  2 +-
 2 files changed, 1 insertion(+), 17 deletions(-)

diff --git a/security/apparmor/Kconfig b/security/apparmor/Kconfig
index b6b68a7750ce..3de21f46c82a 100644
--- a/security/apparmor/Kconfig
+++ b/security/apparmor/Kconfig
@@ -14,22 +14,6 @@ config SECURITY_APPARMOR
 
  If you are unsure how to answer this question, answer N.
 
-config SECURITY_APPARMOR_BOOTPARAM_VALUE
-   int "AppArmor boot parameter default value"
-   depends on SECURITY_APPARMOR
-   range 0 1
-   default 1
-   help
- This option sets the default value for the kernel parameter
- 'apparmor', which allows AppArmor to be enabled or disabled
-  at boot.  If this option is set to 0 (zero), the AppArmor
- kernel parameter will default to 0, disabling AppArmor at
- boot.  If this option is set to 1 (one), the AppArmor
- kernel parameter will default to 1, enabling AppArmor at
- boot.
-
- If you are unsure how to answer this question, answer 1.
-
 config SECURITY_APPARMOR_HASH
bool "Enable introspection of sha1 hashes for loaded profiles"
depends on SECURITY_APPARMOR
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 37dafab649b1..e8b40008d58c 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1332,7 +1332,7 @@ bool aa_g_paranoid_load = true;
 module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO);
 
 /* Boot time disable flag */
-static int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
+static int apparmor_enabled __lsm_ro_after_init = 1;
 module_param_named(enabled, apparmor_enabled, int, 0444);
 
 static int __init apparmor_enabled_setup(char *str)
-- 
2.14.5


___
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 v5 07/38] LSM: Introduce "lsm=" for boottime LSM selection

2018-11-28 Thread Casey Schaufler
Provide a way to explicitly choose LSM initialization order via the new
"lsm=" comma-separated list of LSMs.

Signed-off-by: Kees Cook 
---
 Documentation/admin-guide/kernel-parameters.txt |  4 
 security/Kconfig|  3 ++-
 security/security.c | 14 +-
 3 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index 81d1d5a74728..ea33bcbaecb2 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2302,6 +2302,10 @@
 
lsm.debug   [SECURITY] Enable LSM initialization debugging output.
 
+   lsm=lsm1,...,lsmN
+   [SECURITY] Choose order of LSM initialization. This
+   overrides CONFIG_LSM.
+
machvec=[IA-64] Force the use of a particular machine-vector
(machvec) in a generic kernel.
Example: machvec=hpzx1_swiotlb
diff --git a/security/Kconfig b/security/Kconfig
index 7de42bbacc28..41aa0be6142f 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -281,7 +281,8 @@ config LSM
default "integrity"
help
  A comma-separated list of LSMs, in initialization order.
- Any LSMs left off this list will be ignored.
+ Any LSMs left off this list will be ignored. This can be
+ controlled at boot with the "lsm=" parameter.
 
  If unsure, leave this as the default.
 
diff --git a/security/security.c b/security/security.c
index 96e0b7d057b0..38fc436e8b4b 100644
--- a/security/security.c
+++ b/security/security.c
@@ -47,6 +47,7 @@ char *lsm_names;
 /* Boot-time LSM user choice */
 static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
CONFIG_DEFAULT_SECURITY;
+static __initdata const char *chosen_lsm_order;
 
 static __initconst const char * const builtin_lsm_order = CONFIG_LSM;
 
@@ -190,7 +191,10 @@ static void __init ordered_lsm_init(void)
ordered_lsms = kcalloc(LSM_COUNT + 1, sizeof(*ordered_lsms),
GFP_KERNEL);
 
-   ordered_lsm_parse(builtin_lsm_order, "builtin");
+   if (chosen_lsm_order)
+   ordered_lsm_parse(chosen_lsm_order, "cmdline");
+   else
+   ordered_lsm_parse(builtin_lsm_order, "builtin");
 
for (lsm = ordered_lsms; *lsm; lsm++)
maybe_initialize_lsm(*lsm);
@@ -252,6 +256,14 @@ static int __init choose_lsm(char *str)
 }
 __setup("security=", choose_lsm);
 
+/* Explicitly choose LSM initialization order. */
+static int __init choose_lsm_order(char *str)
+{
+   chosen_lsm_order = str;
+   return 1;
+}
+__setup("lsm=", choose_lsm_order);
+
 /* Enable LSM order debugging. */
 static int __init enable_debug(char *str)
 {
-- 
2.14.5


___
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 v5 11/38] LSM: Separate idea of "major" LSM from "exclusive" LSM

2018-11-28 Thread Casey Schaufler
In order to both support old "security=" Legacy Major LSM selection, and
handling real exclusivity, this creates LSM_FLAG_EXCLUSIVE and updates
the selection logic to handle them.

Signed-off-by: Kees Cook 
Reviewed-by: Casey Schaufler 
---
 include/linux/lsm_hooks.h  |  1 +
 security/apparmor/lsm.c|  2 +-
 security/security.c| 12 
 security/selinux/hooks.c   |  2 +-
 security/smack/smack_lsm.c |  2 +-
 security/tomoyo/tomoyo.c   |  2 +-
 6 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 272791fdd26e..7d04a0c32011 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2040,6 +2040,7 @@ extern void security_add_hooks(struct security_hook_list 
*hooks, int count,
char *lsm);
 
 #define LSM_FLAG_LEGACY_MAJOR  BIT(0)
+#define LSM_FLAG_EXCLUSIVE BIT(1)
 
 struct lsm_info {
const char *name;   /* Required. */
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index d840c1ef3e4d..37dafab649b1 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1722,7 +1722,7 @@ static int __init apparmor_init(void)
 
 DEFINE_LSM(apparmor) = {
.name = "apparmor",
-   .flags = LSM_FLAG_LEGACY_MAJOR,
+   .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
.enabled = _enabled,
.init = apparmor_init,
 };
diff --git a/security/security.c b/security/security.c
index a7889885585e..0009ef6c83fa 100644
--- a/security/security.c
+++ b/security/security.c
@@ -49,6 +49,7 @@ static __initconst const char * const builtin_lsm_order = 
CONFIG_LSM;
 
 /* Ordered list of LSMs to initialize. */
 static __initdata struct lsm_info **ordered_lsms;
+static __initdata struct lsm_info *exclusive;
 
 static __initdata bool debug;
 #define init_debug(...)\
@@ -129,6 +130,12 @@ static bool __init lsm_allowed(struct lsm_info *lsm)
if (!is_enabled(lsm))
return false;
 
+   /* Not allowed if another exclusive LSM already initialized. */
+   if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && exclusive) {
+   init_debug("exclusive disabled: %s\n", lsm->name);
+   return false;
+   }
+
return true;
 }
 
@@ -144,6 +151,11 @@ static void __init maybe_initialize_lsm(struct lsm_info 
*lsm)
if (enabled) {
int ret;
 
+   if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) {
+   exclusive = lsm;
+   init_debug("exclusive chosen: %s\n", lsm->name);
+   }
+
init_debug("initializing %s\n", lsm->name);
ret = lsm->init();
WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret);
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b81239a09dbb..3687599d9d16 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -7199,7 +7199,7 @@ void selinux_complete_init(void)
all processes and objects when they are created. */
 DEFINE_LSM(selinux) = {
.name = "selinux",
-   .flags = LSM_FLAG_LEGACY_MAJOR,
+   .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
.enabled = _enabled,
.init = selinux_init,
 };
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 56a114c1d750..849426ac6a6c 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4888,6 +4888,6 @@ static __init int smack_init(void)
  */
 DEFINE_LSM(smack) = {
.name = "smack",
-   .flags = LSM_FLAG_LEGACY_MAJOR,
+   .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
.init = smack_init,
 };
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index a46f6bc1e97c..daff7d7897ad 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -550,6 +550,6 @@ static int __init tomoyo_init(void)
 
 DEFINE_LSM(tomoyo) = {
.name = "tomoyo",
-   .flags = LSM_FLAG_LEGACY_MAJOR,
+   .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
.init = tomoyo_init,
 };
-- 
2.14.5


___
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 v5 01/38] LSM: Introduce LSM_FLAG_LEGACY_MAJOR

2018-11-27 Thread Casey Schaufler
On 11/26/2018 9:34 PM, Kees Cook wrote:
> On Mon, Nov 26, 2018 at 3:26 PM Casey Schaufler  
> wrote:
>
> Hmmm... the "From: Kees..." in the body is missing. Are you using "git
> send-email"?

Not for this posting. I will use it henceforth. I had some
email configuration issues to work through.

___
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 v5 37/38] LSM: Infrastructure management of the ipc security blob

2018-11-27 Thread Casey Schaufler
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: adjusted for ordered init series]
Signed-off-by: Kees Cook 
---
 include/linux/lsm_hooks.h |  2 +
 security/security.c   | 91 ++--
 security/selinux/hooks.c  | 98 ++-
 security/selinux/include/objsec.h |  4 +-
 security/smack/smack.h|  4 +-
 security/smack/smack_lsm.c| 32 ++---
 6 files changed, 110 insertions(+), 121 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 243c7c6e181d..f2cc950e6172 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 d3d3963d7914..60ae6b470a0b 100644
--- a/security/security.c
+++ b/security/security.c
@@ -30,6 +30,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 
 #define MAX_LSM_EVM_XATTR  2
@@ -169,6 +170,8 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes 
*needed)
if (needed->lbs_inode && blob_sizes.lbs_inode == 0)
blob_sizes.lbs_inode = sizeof(struct rcu_head);
lsm_set_blob_size(>lbs_inode, _sizes.lbs_inode);
+   lsm_set_blob_size(>lbs_ipc, _sizes.lbs_ipc);
+   lsm_set_blob_size(>lbs_msg_msg, _sizes.lbs_msg_msg);
lsm_set_blob_size(>lbs_task, _sizes.lbs_task);
 }
 
@@ -293,6 +296,8 @@ static void __init ordered_lsm_init(void)
init_debug("cred blob size = %d\n", blob_sizes.lbs_cred);
init_debug("file blob size = %d\n", blob_sizes.lbs_file);
init_debug("inode blob size= %d\n", blob_sizes.lbs_inode);
+   init_debug("ipc blob size  = %d\n", blob_sizes.lbs_ipc);
+   init_debug("msg_msg blob size  = %d\n", blob_sizes.lbs_msg_msg);
init_debug("task blob size = %d\n", blob_sizes.lbs_task);
 
/*
@@ -538,6 +543,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
@@ -1618,22 +1665,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_

[PATCH v5 09/38] LSM: Prepare for reorganizing "security=" logic

2018-11-27 Thread Casey Schaufler
This moves the string handling for "security=" boot parameter into
a stored pointer instead of a string duplicate. This will allow
easier handling of the string when switching logic to use the coming
enable/disable infrastructure.

Signed-off-by: Kees Cook 
Reviewed-by: Casey Schaufler 
Reviewed-by: John Johansen 
---
 security/security.c | 17 -
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/security/security.c b/security/security.c
index ea760d625af6..f4a7b7d52d71 100644
--- a/security/security.c
+++ b/security/security.c
@@ -34,9 +34,6 @@
 
 #define MAX_LSM_EVM_XATTR  2
 
-/* Maximum number of letters for an LSM name string */
-#define SECURITY_NAME_MAX  10
-
 /* How many LSMs were built into the kernel? */
 #define LSM_COUNT (__end_lsm_info - __start_lsm_info)
 
@@ -45,9 +42,8 @@ static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
 
 char *lsm_names;
 /* Boot-time LSM user choice */
-static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
-   CONFIG_DEFAULT_SECURITY;
 static __initdata const char *chosen_lsm_order;
+static __initdata const char *chosen_major_lsm;
 
 static __initconst const char * const builtin_lsm_order = CONFIG_LSM;
 
@@ -138,7 +134,7 @@ static bool __init lsm_allowed(struct lsm_info *lsm)
return true;
 
/* Disabled if this LSM isn't the chosen one. */
-   if (strcmp(lsm->name, chosen_lsm) != 0)
+   if (strcmp(lsm->name, chosen_major_lsm) != 0)
return false;
 
return true;
@@ -168,6 +164,9 @@ static void __init ordered_lsm_parse(const char *order, 
const char *origin)
struct lsm_info *lsm;
char *sep, *name, *next;
 
+   if (!chosen_major_lsm)
+   chosen_major_lsm = CONFIG_DEFAULT_SECURITY;
+
sep = kstrdup(order, GFP_KERNEL);
next = sep;
/* Walk the list, looking for matching LSMs. */
@@ -257,12 +256,12 @@ int __init security_init(void)
 }
 
 /* Save user chosen LSM */
-static int __init choose_lsm(char *str)
+static int __init choose_major_lsm(char *str)
 {
-   strncpy(chosen_lsm, str, SECURITY_NAME_MAX);
+   chosen_major_lsm = str;
return 1;
 }
-__setup("security=", choose_lsm);
+__setup("security=", choose_major_lsm);
 
 /* Explicitly choose LSM initialization order. */
 static int __init choose_lsm_order(char *str)
-- 
2.14.5


___
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 v5 28/38] SELinux: Abstract use of file security blob

2018-11-27 Thread Casey Schaufler
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 
Signed-off-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 ac6d8a2d00f1..ce1d37378eb5 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -393,7 +393,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);
 }
@@ -1881,7 +1881,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);
@@ -2225,7 +2225,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;
@@ -3537,7 +3537,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();
 
@@ -3572,7 +3572,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;
@@ -3824,7 +3824,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();
 }
 
@@ -3839,7 +3839,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 */
@@ -3863,7 +3863,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
@@ -4002,7 +4002,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 c2974b031d05..e0ac2992e059 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 + selinux_blob_sizes.lbs_cred;
 }
 
+static inline struct file_security_struct *selinux_file(const struct file 
*file)
+{
+   return file->f_security;
+}
+
 #endif /* _SELINUX_OBJSEC_H_ */
-- 
2.14.5


___
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 v5 29/38] Smack: Abstract use of file security blob

2018-11-27 Thread Casey Schaufler
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 
Signed-off-by: Kees Cook 
---
 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 b27eb252e953..50854969a391 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -362,6 +362,11 @@ static inline struct task_smack *smack_cred(const struct 
cred *cred)
return cred->security + smack_blob_sizes.lbs_cred;
 }
 
+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 459f7d523ca6..3e11be8cce7e 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -1573,9 +1573,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;
 }
 
@@ -1815,7 +1815,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();
 }
 
 /**
@@ -1832,6 +1834,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));
const struct cred *tcred;
@@ -1845,7 +1848,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);
 
-- 
2.14.5


___
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 v5 36/38] Smack: Abstract use of ipc security blobs

2018-11-27 Thread Casey Schaufler
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 
Signed-off-by: Kees Cook 
---
 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 bf0abc35ca1c..0adddbeecc62 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
@@ -373,6 +374,16 @@ static inline struct inode_smack *smack_inode(const struct 
inode *inode)
return inode->i_security + smack_blob_sizes.lbs_inode;
 }
 
+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 9ff185af378a..ceda326a6e47 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -2918,7 +2918,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;
 }
 
 /**
@@ -2929,9 +2931,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;
 }
 
@@ -3243,7 +3245,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;
@@ -3264,7 +3267,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.14.5


___
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 v5 17/38] Yama: Initialize as ordered LSM

2018-11-27 Thread Casey Schaufler
This converts Yama from being a direct "minor" LSM into an ordered LSM.

Signed-off-by: Kees Cook 
Reviewed-by: Casey Schaufler 
---
 include/linux/lsm_hooks.h | 5 -
 security/Kconfig  | 2 +-
 security/security.c   | 1 -
 security/yama/yama_lsm.c  | 8 +++-
 4 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index b565c0c10269..6cfbd7d78a89 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2087,10 +2087,5 @@ static inline void security_delete_hooks(struct 
security_hook_list *hooks,
 #endif /* CONFIG_SECURITY_WRITABLE_HOOKS */
 
 extern void __init capability_add_hooks(void);
-#ifdef CONFIG_SECURITY_YAMA
-extern void __init yama_add_hooks(void);
-#else
-static inline void __init yama_add_hooks(void) { }
-#endif
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/security/Kconfig b/security/Kconfig
index 566d54215cbe..94a71e022b79 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -241,7 +241,7 @@ source security/integrity/Kconfig
 
 config LSM
string "Ordered list of enabled LSMs"
-   default "loadpin,integrity,selinux,smack,tomoyo,apparmor"
+   default "yama,loadpin,integrity,selinux,smack,tomoyo,apparmor"
help
  A comma-separated list of LSMs, in initialization order.
  Any LSMs left off this list will be ignored. This can be
diff --git a/security/security.c b/security/security.c
index 0c092d62cc47..0c3c66dbf51c 100644
--- a/security/security.c
+++ b/security/security.c
@@ -274,7 +274,6 @@ int __init security_init(void)
 * Load minor LSMs, with the capability module always first.
 */
capability_add_hooks();
-   yama_add_hooks();
 
/* Load LSMs in specified order. */
ordered_lsm_init();
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
index ffda91a4a1aa..eb1da1303d2e 100644
--- a/security/yama/yama_lsm.c
+++ b/security/yama/yama_lsm.c
@@ -477,9 +477,15 @@ static void __init yama_init_sysctl(void)
 static inline void yama_init_sysctl(void) { }
 #endif /* CONFIG_SYSCTL */
 
-void __init yama_add_hooks(void)
+static int __init yama_init(void)
 {
pr_info("Yama: becoming mindful.\n");
security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama");
yama_init_sysctl();
+   return 0;
 }
+
+DEFINE_LSM(yama) = {
+   .name = "yama",
+   .init = yama_init,
+};
-- 
2.14.5


___
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 v5 26/38] TOMOYO: Abstract use of cred security blob

2018-11-27 Thread Casey Schaufler
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: adjusted for ordered init series]
Signed-off-by: Kees Cook 
---
 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..41898613d93b 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 int 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_domai

[PATCH v5 24/38] SELinux: Remove unused selinux_is_enabled

2018-11-27 Thread Casey Schaufler
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 
Signed-off-by: Kees Cook 
---
 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 41b230d459a6..c82f11270de6 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 12e414394530..1a745e2f49a9 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.14.5


___
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 v5 01/38] LSM: Introduce LSM_FLAG_LEGACY_MAJOR

2018-11-27 Thread Casey Schaufler
This adds a flag for the current "major" LSMs to distinguish them when
we have a universal method for ordering all LSMs. It's called "legacy"
since the distinction of "major" will go away in the blob-sharing world.

Signed-off-by: Kees Cook 
Reviewed-by: Casey Schaufler 
Reviewed-by: John Johansen 
---
 include/linux/lsm_hooks.h  | 3 +++
 security/apparmor/lsm.c| 1 +
 security/selinux/hooks.c   | 1 +
 security/smack/smack_lsm.c | 1 +
 security/tomoyo/tomoyo.c   | 1 +
 5 files changed, 7 insertions(+)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index aaeb7fa24dc4..63c0e102de20 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2039,8 +2039,11 @@ extern char *lsm_names;
 extern void security_add_hooks(struct security_hook_list *hooks, int count,
char *lsm);
 
+#define LSM_FLAG_LEGACY_MAJOR  BIT(0)
+
 struct lsm_info {
const char *name;   /* Required. */
+   unsigned long flags;/* Optional: flags describing LSM */
int (*init)(void);  /* Required. */
 };
 
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 42446a216f3b..2edd35ca5044 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1728,5 +1728,6 @@ static int __init apparmor_init(void)
 
 DEFINE_LSM(apparmor) = {
.name = "apparmor",
+   .flags = LSM_FLAG_LEGACY_MAJOR,
.init = apparmor_init,
 };
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7ce683259357..56c6f1849c80 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -7209,6 +7209,7 @@ void selinux_complete_init(void)
all processes and objects when they are created. */
 DEFINE_LSM(selinux) = {
.name = "selinux",
+   .flags = LSM_FLAG_LEGACY_MAJOR,
.init = selinux_init,
 };
 
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 81fb4c1631e9..3639e55b1f4b 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -4891,5 +4891,6 @@ static __init int smack_init(void)
  */
 DEFINE_LSM(smack) = {
.name = "smack",
+   .flags = LSM_FLAG_LEGACY_MAJOR,
.init = smack_init,
 };
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index 1b5b5097efd7..09f7af130d3a 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -552,5 +552,6 @@ static int __init tomoyo_init(void)
 
 DEFINE_LSM(tomoyo) = {
.name = "tomoyo",
+   .flags = LSM_FLAG_LEGACY_MAJOR,
.init = tomoyo_init,
 };
-- 
2.14.5


___
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 v5 38/38] TOMOYO: Update LSM flags to no longer be exclusive

2018-11-27 Thread Casey Schaufler
With blob sharing in place, TOMOYO is no longer an exclusive LSM, so it
can operate separately now. Mark it as such.

Signed-off-by: Kees Cook 
---
 security/tomoyo/tomoyo.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
index 9094cf41a247..066c0daf0efc 100644
--- a/security/tomoyo/tomoyo.c
+++ b/security/tomoyo/tomoyo.c
@@ -577,7 +577,7 @@ static int __init tomoyo_init(void)
 DEFINE_LSM(tomoyo) = {
.name = "tomoyo",
.enabled = _enabled,
-   .flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
+   .flags = LSM_FLAG_LEGACY_MAJOR,
.blobs = _blob_sizes,
.init = tomoyo_init,
 };
-- 
2.14.5


___
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 v5 03/38] LSM: Plumb visibility into optional "enabled" state

2018-11-27 Thread Casey Schaufler
In preparation for lifting the "is this LSM enabled?" logic out of the
individual LSMs, pass in any special enabled state tracking (as needed
for SELinux, AppArmor, and LoadPin). This should be an "int" to include
handling any future cases where "enabled" is exposed via sysctl which
has no "bool" type.

Signed-off-by: Kees Cook 
Reviewed-by: Casey Schaufler 
Reviewed-by: John Johansen 
---
 include/linux/lsm_hooks.h | 1 +
 security/apparmor/lsm.c   | 5 +++--
 security/selinux/hooks.c  | 1 +
 3 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 63c0e102de20..4e2e9cdf78c6 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2044,6 +2044,7 @@ extern void security_add_hooks(struct security_hook_list 
*hooks, int count,
 struct lsm_info {
const char *name;   /* Required. */
unsigned long flags;/* Optional: flags describing LSM */
+   int *enabled;   /* Optional: NULL means enabled. */
int (*init)(void);  /* Required. */
 };
 
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 2edd35ca5044..127a540ef63a 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1332,8 +1332,8 @@ bool aa_g_paranoid_load = true;
 module_param_named(paranoid_load, aa_g_paranoid_load, aabool, S_IRUGO);
 
 /* Boot time disable flag */
-static bool apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
-module_param_named(enabled, apparmor_enabled, bool, S_IRUGO);
+static int apparmor_enabled = CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE;
+module_param_named(enabled, apparmor_enabled, int, 0444);
 
 static int __init apparmor_enabled_setup(char *str)
 {
@@ -1729,5 +1729,6 @@ static int __init apparmor_init(void)
 DEFINE_LSM(apparmor) = {
.name = "apparmor",
.flags = LSM_FLAG_LEGACY_MAJOR,
+   .enabled = _enabled,
.init = apparmor_init,
 };
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 56c6f1849c80..efc0ac1b5019 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -7210,6 +7210,7 @@ void selinux_complete_init(void)
 DEFINE_LSM(selinux) = {
.name = "selinux",
.flags = LSM_FLAG_LEGACY_MAJOR,
+   .enabled = _enabled,
.init = selinux_init,
 };
 
-- 
2.14.5


___
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 v5 22/38] SELinux: Abstract use of cred security blob

2018-11-27 Thread Casey Schaufler
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: adjusted for ordered init series]
Signed-off-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 edd5b8dd3e56..24b6b459fa2a 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -225,7 +225,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;
 }
 
@@ -461,7 +461,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,
@@ -480,7 +480,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,
@@ -1951,7 +1951,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;
@@ -1973,7 +1973,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;
@@ -2480,8 +2480,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. */
@@ -2645,7 +2645,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;
 
@@ -2688,7 +2688,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;
@@ -2991,7 +2991,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),
   );
@@ -3011,14 +3011,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;
 }
@@ -3028,7 +3028,7 @@ static int selinux_inode_init_security(struct inode 
*inode, struct inode *dir,
   const char **name,
   void **value, size_t *len)
 {
-   const str

[PATCH v5 21/38] Smack: Abstract use of cred security blob

2018-11-27 Thread Casey Schaufler
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: adjusted for ordered init series]
Signed-off-by: Kees Cook 
---
 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 849426ac6a6c..f34117b8c3be 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;
s

[PATCH v5 16/38] LoadPin: Initialize as ordered LSM

2018-11-27 Thread Casey Schaufler
This converts LoadPin from being a direct "minor" LSM into an ordered LSM.

Signed-off-by: Kees Cook 
Reviewed-by: Casey Schaufler 
---
 include/linux/lsm_hooks.h  |  5 -
 security/Kconfig   | 39 +--
 security/loadpin/loadpin.c |  8 +++-
 security/security.c|  1 -
 4 files changed, 8 insertions(+), 45 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7d04a0c32011..b565c0c10269 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2092,10 +2092,5 @@ extern void __init yama_add_hooks(void);
 #else
 static inline void __init yama_add_hooks(void) { }
 #endif
-#ifdef CONFIG_SECURITY_LOADPIN
-void __init loadpin_add_hooks(void);
-#else
-static inline void loadpin_add_hooks(void) { };
-#endif
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/security/Kconfig b/security/Kconfig
index 41aa0be6142f..566d54215cbe 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -239,46 +239,9 @@ source security/yama/Kconfig
 
 source security/integrity/Kconfig
 
-choice
-   prompt "Default security module"
-   default DEFAULT_SECURITY_SELINUX if SECURITY_SELINUX
-   default DEFAULT_SECURITY_SMACK if SECURITY_SMACK
-   default DEFAULT_SECURITY_TOMOYO if SECURITY_TOMOYO
-   default DEFAULT_SECURITY_APPARMOR if SECURITY_APPARMOR
-   default DEFAULT_SECURITY_DAC
-
-   help
- Select the security module that will be used by default if the
- kernel parameter security= is not specified.
-
-   config DEFAULT_SECURITY_SELINUX
-   bool "SELinux" if SECURITY_SELINUX=y
-
-   config DEFAULT_SECURITY_SMACK
-   bool "Simplified Mandatory Access Control" if SECURITY_SMACK=y
-
-   config DEFAULT_SECURITY_TOMOYO
-   bool "TOMOYO" if SECURITY_TOMOYO=y
-
-   config DEFAULT_SECURITY_APPARMOR
-   bool "AppArmor" if SECURITY_APPARMOR=y
-
-   config DEFAULT_SECURITY_DAC
-   bool "Unix Discretionary Access Controls"
-
-endchoice
-
-config DEFAULT_SECURITY
-   string
-   default "selinux" if DEFAULT_SECURITY_SELINUX
-   default "smack" if DEFAULT_SECURITY_SMACK
-   default "tomoyo" if DEFAULT_SECURITY_TOMOYO
-   default "apparmor" if DEFAULT_SECURITY_APPARMOR
-   default "" if DEFAULT_SECURITY_DAC
-
 config LSM
string "Ordered list of enabled LSMs"
-   default "integrity"
+   default "loadpin,integrity,selinux,smack,tomoyo,apparmor"
help
  A comma-separated list of LSMs, in initialization order.
  Any LSMs left off this list will be ignored. This can be
diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c
index 48f39631b370..055fb0a64169 100644
--- a/security/loadpin/loadpin.c
+++ b/security/loadpin/loadpin.c
@@ -187,13 +187,19 @@ static struct security_hook_list loadpin_hooks[] 
__lsm_ro_after_init = {
LSM_HOOK_INIT(kernel_load_data, loadpin_load_data),
 };
 
-void __init loadpin_add_hooks(void)
+static int __init loadpin_init(void)
 {
pr_info("ready to pin (currently %senforcing)\n",
enforce ? "" : "not ");
security_add_hooks(loadpin_hooks, ARRAY_SIZE(loadpin_hooks), "loadpin");
+   return 0;
 }
 
+DEFINE_LSM(loadpin) = {
+   .name = "loadpin",
+   .init = loadpin_init,
+};
+
 /* Should not be mutable after boot, so not listed in sysfs (perm == 0). */
 module_param(enforce, int, 0);
 MODULE_PARM_DESC(enforce, "Enforce module/firmware pinning");
diff --git a/security/security.c b/security/security.c
index 3fac0ff39944..0c092d62cc47 100644
--- a/security/security.c
+++ b/security/security.c
@@ -275,7 +275,6 @@ int __init security_init(void)
 */
capability_add_hooks();
yama_add_hooks();
-   loadpin_add_hooks();
 
/* Load LSMs in specified order. */
ordered_lsm_init();
-- 
2.14.5


___
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 v5 25/38] AppArmor: Abstract use of cred security blob

2018-11-27 Thread Casey Schaufler
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: adjusted for ordered init series]
Signed-off-by: Kees Cook 
---
 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 265ae6641a06..a757370f2a0c 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 e8b40008d58c..803ec0a63d87 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -59,7 +59,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);
 }
 
 /*
@@ -67,7 +67,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;
 }
 
@@ -77,7 +77,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;
 }
 
@@ -86,7 +86,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)
@@ -1484,7 +1484,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.14.5


___
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 v5 32/38] Smack: Abstract use of inode security blob

2018-11-27 Thread Casey Schaufler
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 
Signed-off-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 2007d38d0e46..436231dfae33 100644
--- a/security/smack/smack.h
+++ b/security/smack/smack.h
@@ -368,12 +368,17 @@ static inline struct smack_known **smack_file(const 
struct file *file)
   smack_blob_sizes.lbs_file);
 }
 
+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;
 }
 
@@ -382,7 +387,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 c560cb8e155c..c086110cba80 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)
@@ -826,7 +826,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)
@@ -914,7 +914,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;
 
@@ -994,7 +994,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
@@ -1022,7 +1022,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);
@@ -1360,7 +1360,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;
@@ -1441,7 +1441,7 @@ static int smack_inode_removexattr(struct dentry *dentry, 
const char *n

[PATCH v5 27/38] Infrastructure management of the cred security blob

2018-11-27 Thread Casey Schaufler
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 
Reviewed-by: Kees Cook 
[kees: adjusted for ordered init series]
Signed-off-by: Kees Cook 
---
 include/linux/lsm_hooks.h | 12 ++
 security/apparmor/include/cred.h  |  4 +-
 security/apparmor/include/lib.h   |  4 ++
 security/apparmor/lsm.c   |  9 
 security/security.c   | 89 ++-
 security/selinux/hooks.c  | 51 +-
 security/selinux/include/objsec.h |  4 +-
 security/smack/smack.h|  3 +-
 security/smack/smack_lsm.c| 79 +++---
 security/tomoyo/common.h  |  3 +-
 security/tomoyo/tomoyo.c  |  6 +++
 11 files changed, 162 insertions(+), 102 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 15fc49ee41a1..c9458280214e 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
@@ -2053,6 +2060,7 @@ struct lsm_info {
unsigned long flags;/* Optional: flags describing LSM */
int *enabled;   /* Optional: controlled by CONFIG_LSM */
int (*init)(void);  /* Required. */
+   struct lsm_blob_sizes *blobs; /* Optional: for blob sharing. */
 };
 
 extern struct lsm_info __start_lsm_info[], __end_lsm_info[];
@@ -2092,4 +2100,8 @@ static inline void security_delete_hooks(struct 
security_hook_list *hooks,
 #define __lsm_ro_after_init__ro_after_init
 #endif /* CONFIG_SECURITY_WRITABLE_HOOKS */
 
+#ifdef CONFIG_SECURITY
+void __init lsm_early_cred(struct cred *cred);
+#endif
+
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/security/apparmor/include/cred.h b/security/apparmor/include/cred.h
index a757370f2a0c..b9504a05fddc 100644
--- a/security/apparmor/include/cred.h
+++ b/security/apparmor/include/cred.h
@@ -25,7 +25,7 @@
 
 static inline struct aa_label *cred_label(const struct cred *cred)
 {
-   struct aa_label **blob = cred->security;
+   struct aa_label **blob = cred->security + apparmor_blob_sizes.lbs_cred;
 
AA_BUG(!blob);
return *blob;
@@ -34,7 +34,7 @@ static inline struct aa_label *cred_label(const struct cred 
*cred)
 static inline void set_cred_label(const struct cred *cred,
  struct aa_label *label)
 {
-   struct aa_label **blob = cred->security;
+   struct aa_label **blob = cred->security + apparmor_blob_sizes.lbs_cred;
 
AA_BUG(!blob);
*blob = label;
diff --git a/security/apparmor/include/lib.h b/security/apparmor/include/lib.h
index 6505e1ad9e23..bbe9b384d71d 100644
--- a/security/apparmor/include/lib.h
+++ b/security/apparmor/include/lib.h
@@ -16,6 +16,7 @@
 
 #include 
 #include 
+#include 
 
 #include "match.h"
 
@@ -55,6 +56,9 @@ const char *aa_splitn_fqname(const char *fqname, size_t n, 
const char **ns_name,
 size_t *ns_len);
 void aa_info_message(const char *str);
 
+/* Security blob offsets */
+extern struct lsm_blob_sizes apparmor_blob_sizes;
+
 /**
  * aa_strneq - compare null terminated @str to a non null terminated substring
  * @str: a null terminated string
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 803ec0a63d87..70669e676212 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1150,6 +1150,13 @@ static int apparmor_inet_conn_request(struct sock *sk, 
struct sk_buff *skb,
 }
 #endif
 
+/*
+ * The cred blob is a pointer to, not an instance of, an aa_task_ctx.
+ */
+struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = {
+   .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),
@@ -1484,6 +1491,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;
 
@@ -1724,5 +1732,6 @@ DEFINE_LSM(apparmor) = {
.name = "apparmor",
.flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
.enabled = _enabled,
+   .blobs = _blob_sizes,
.init = apparmor_init,
 };
diff --git a/security/security.c b/security/security.c
index 81ff6a71e78e..c49d4a18c75f 100644
--- a/security/secu

[PATCH v5 15/38] LSM: Split LSM preparation from initialization

2018-11-27 Thread Casey Schaufler
Since we already have to do a pass through the LSMs to figure out if
exclusive LSMs should be disabled after the first one is seen as enabled,
this splits the logic up a bit more cleanly. Now we do a full "prepare"
pass through the LSMs (which also allows for later use by the blob-sharing
code), before starting the LSM initialization pass.

Signed-off-by: Kees Cook 
---
 security/security.c | 21 +++--
 1 file changed, 15 insertions(+), 6 deletions(-)

diff --git a/security/security.c b/security/security.c
index df71b54c1ba4..3fac0ff39944 100644
--- a/security/security.c
+++ b/security/security.c
@@ -139,22 +139,28 @@ static bool __init lsm_allowed(struct lsm_info *lsm)
return true;
 }
 
-/* Check if LSM should be initialized. */
-static void __init maybe_initialize_lsm(struct lsm_info *lsm)
+/* Prepare LSM for initialization. */
+static void __init prepare_lsm(struct lsm_info *lsm)
 {
int enabled = lsm_allowed(lsm);
 
/* Record enablement (to handle any following exclusive LSMs). */
set_enabled(lsm, enabled);
 
-   /* If selected, initialize the LSM. */
+   /* If enabled, do pre-initialization work. */
if (enabled) {
-   int ret;
-
if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) {
exclusive = lsm;
init_debug("exclusive chosen: %s\n", lsm->name);
}
+   }
+}
+
+/* Initialize a given LSM, if it is enabled. */
+static void __init initialize_lsm(struct lsm_info *lsm)
+{
+   if (is_enabled(lsm)) {
+   int ret;
 
init_debug("initializing %s\n", lsm->name);
ret = lsm->init();
@@ -240,7 +246,10 @@ static void __init ordered_lsm_init(void)
ordered_lsm_parse(builtin_lsm_order, "builtin");
 
for (lsm = ordered_lsms; *lsm; lsm++)
-   maybe_initialize_lsm(*lsm);
+   prepare_lsm(*lsm);
+
+   for (lsm = ordered_lsms; *lsm; lsm++)
+   initialize_lsm(*lsm);
 
kfree(ordered_lsms);
 }
-- 
2.14.5


___
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 v5 35/38] SELinux: Abstract use of ipc security blobs

2018-11-27 Thread Casey Schaufler
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 
Signed-off-by: Kees Cook 
---
 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 f0e7ac26f3a9..1e56b036018a 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -5889,7 +5889,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;
@@ -5946,7 +5946,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;
@@ -5995,8 +5995,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
@@ -6043,8 +6043,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;
@@ -6097,7 +6097,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;
@@ -6194,7 +6194,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;
@@ -6280,7 +6280,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 562fad58c56b..539cacf4a572 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"
@@ -175,4 +176,16 @@ static inline struct inode_security_struct *selinux_inode(
return inode->i_security + selinux_blob_sizes.lbs_inode;
 }
 
+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.14.5


___
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 v5 33/38] LSM: Infrastructure management of the inode security

2018-11-27 Thread Casey Schaufler
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 
Reviewed-by: Kees Cook 
[kees: adjusted for ordered init series]
Signed-off-by: Kees Cook 
---
 include/linux/lsm_hooks.h |  3 ++
 security/security.c   | 64 +++--
 security/selinux/hooks.c  | 37 ---
 security/selinux/include/objsec.h |  9 +++--
 security/smack/smack.h|  2 +-
 security/smack/smack_lsm.c| 76 +--
 6 files changed, 93 insertions(+), 98 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 64499c2d44cd..65440005ec92 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;
 };
 
 /*
@@ -2101,6 +2102,8 @@ 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 lsm_inode_alloc(struct inode *inode);
+
 #ifdef CONFIG_SECURITY
 void __init lsm_early_cred(struct cred *cred);
 #endif
diff --git a/security/security.c b/security/security.c
index 499842ece0fb..0cc48072eb3b 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 __lsm_ro_after_init;
@@ -161,6 +162,13 @@ static void __init lsm_set_blob_sizes(struct 
lsm_blob_sizes *needed)
 
lsm_set_blob_size(>lbs_cred, _sizes.lbs_cred);
lsm_set_blob_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_blob_size(>lbs_inode, _sizes.lbs_inode);
 }
 
 /* Prepare LSM for initialization. */
@@ -283,6 +291,7 @@ static void __init ordered_lsm_init(void)
 
init_debug("cred blob size = %d\n", blob_sizes.lbs_cred);
init_debug("file blob size = %d\n", blob_sizes.lbs_file);
+   init_debug("inode blob size= %d\n", blob_sizes.lbs_inode);
 
/*
 * Create any kmem_caches needed for blobs
@@ -291,6 +300,10 @@ static void __init ordered_lsm_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);
 
for (lsm = ordered_lsms; *lsm; lsm++)
initialize_lsm(*lsm);
@@ -481,6 +494,27 @@ static 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;
+}
+
 /*
  * Hook list operation macros.
  *
@@ -727,14 +761,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 head is at the start of the inode blob
+*/
+   kmem_cache_free(lsm_inode_cache, head);
 }
 
 void security_inode_free(struct inode *inode)
 {
integrity_inode_free(inode);
call_void_hook(inode_free_security, inode);
+  

[PATCH v5 30/38] LSM: Infrastructure management of the file security

2018-11-27 Thread Casey Schaufler
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: adjusted for ordered init series]
Signed-off-by: Kees Cook 
---
 include/linux/lsm_hooks.h |  1 +
 security/apparmor/include/file.h  |  5 +++-
 security/apparmor/lsm.c   | 19 +++---
 security/security.c   | 54 ---
 security/selinux/hooks.c  | 25 ++
 security/selinux/include/objsec.h |  2 +-
 security/smack/smack.h|  3 ++-
 security/smack/smack_lsm.c| 14 +-
 8 files changed, 72 insertions(+), 51 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index c9458280214e..64499c2d44cd 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/include/file.h b/security/apparmor/include/file.h
index 4c2c8ac8842f..8be09208cf7c 100644
--- a/security/apparmor/include/file.h
+++ b/security/apparmor/include/file.h
@@ -32,7 +32,10 @@ struct path;
 AA_MAY_CHMOD | AA_MAY_CHOWN | AA_MAY_LOCK | \
 AA_EXEC_MMAP | AA_MAY_LINK)
 
-#define file_ctx(X) ((struct aa_file_ctx *)(X)->f_security)
+static inline struct aa_file_ctx *file_ctx(struct file *file)
+{
+   return file->f_security + apparmor_blob_sizes.lbs_file;
+}
 
 /* struct aa_file_ctx - the AppArmor context the file was opened in
  * @lock: lock to update the ctx
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 70669e676212..3ae8c902d740 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -433,21 +433,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)
@@ -1155,6 +1155,7 @@ static int apparmor_inet_conn_request(struct sock *sk, 
struct sk_buff *skb,
  */
 struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = {
.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 c49d4a18c75f..499842ece0fb 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 __lsm_ro_after_init;
 
@@ -158,6 +160,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes 
*needed)
return;
 
lsm_set_blob_size(>lbs_cred, _sizes.lbs_cred);
+   lsm_set_blob_size(>lbs_file, _sizes.lbs_file);
 }
 
 /* Prepare LSM for initialization. */
@@ -279,6 +282,15 @@ static void __init ordered_lsm_init(void)
prepare_lsm(*lsm);
 
init_debug("cred blob size = %d\n", blob_sizes.lbs_cred);
+   init_debug("file blob size = %d\n", blob_sizes.lbs_file);
+
+   /*
+* 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);
 
for (lsm = ordered_lsms; *lsm; lsm++)
initialize_lsm(*lsm);
@@ -448,6 +460,27 @@ void __init lsm_early_cred(struct cred *cred)
panic("%s: Early cred alloc failed.\n", __func__);
 }
 
+/**
+ * lsm_file_alloc - allocate a composite file blob
+ * @file: the file that needs a blob
+ *
+ * Allocate the file blo

[PATCH v5 34/38] LSM: Infrastructure management of the task security

2018-11-27 Thread Casey Schaufler
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: adjusted for ordered init series]
Signed-off-by: Kees Cook 
---
 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 65440005ec92..243c7c6e181d 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;
 };
 
 /*
@@ -2106,6 +2107,7 @@ extern int lsm_inode_alloc(struct inode *inode);
 
 #ifdef CONFIG_SECURITY
 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/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 3ae8c902d740..83dc23f33a29 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -93,19 +93,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;
 }
@@ -1156,6 +1151,7 @@ static int apparmor_inet_conn_request(struct sock *sk, 
struct sk_buff *skb,
 struct lsm_blob_sizes apparmor_blob_sizes __lsm_ro_after_init = {
.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 = {
@@ -1486,15 +1482,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 0cc48072eb3b..d3d3963d7914 100644
--- a/security/security.c
+++ b/security/security.c
@@ -169,6 +169,7 @@ static void __init lsm_set_blob_sizes(struct lsm_blob_sizes 
*needed)
if (needed->lbs_inode && blob_sizes.lbs_inode == 0)
blob_sizes.lbs_inode = sizeof(struct rcu_head);
lsm_set_blob_size(>lbs_inode, _sizes.lbs_inode);
+   lsm_set_blob_size(>lbs_task, _sizes.lbs_task);
 }
 
 /* Prepare LSM for initialization. */
@@ -292,6 +293,7 @@ static void __init ordered_lsm_init(void)
init_debug("cred blob size = %d\n", blob_sizes.lbs_cred);
init_debug(

[PATCH v5 31/38] SELinux: Abstract use of inode security blob

2018-11-27 Thread Casey Schaufler
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 
Signed-off-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 9669a059ce0f..3069e95d86e6 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -272,7 +272,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);
 
@@ -293,7 +293,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)
@@ -303,7 +303,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);
 }
 
 /*
@@ -312,14 +312,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);
 }
 
 /*
@@ -330,7 +330,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)
@@ -343,7 +343,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;
 
/*
@@ -1502,7 +1502,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;
@@ -1802,7 +1802,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);
@@ -3030,7 +3030,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;
@@ -3130,7 +3130,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;
@@ -4150,7 +4150,7 @@ static int selinux_task_kill(struct task_struct *p, 
struct kernel_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);
@@ -6529,7 +6529,7 @@

[PATCH v5 20/38] procfs: add smack subdir to attrs

2018-11-27 Thread Casey Schaufler
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 
Signed-off-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 ce3465479447..e133de4897df 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 .
@@ -2517,7 +2521,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);
@@ -2566,7 +2570,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);
@@ -2580,13 +2586,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_i

[PATCH v5 19/38] capability: Initialize as LSM_ORDER_FIRST

2018-11-27 Thread Casey Schaufler
This converts capabilities to use the new LSM_ORDER_FIRST position.

Signed-off-by: Kees Cook 
Reviewed-by: Casey Schaufler 
---
 include/linux/lsm_hooks.h | 2 --
 security/commoncap.c  | 9 -
 security/security.c   | 5 -
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 83858e3df9e5..15fc49ee41a1 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2092,6 +2092,4 @@ 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 void __init capability_add_hooks(void);
-
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/security/commoncap.c b/security/commoncap.c
index 18a4fdf6f6eb..ec387535e597 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -1363,10 +1363,17 @@ struct security_hook_list capability_hooks[] 
__lsm_ro_after_init = {
LSM_HOOK_INIT(vm_enough_memory, cap_vm_enough_memory),
 };
 
-void __init capability_add_hooks(void)
+static int __init capability_init(void)
 {
security_add_hooks(capability_hooks, ARRAY_SIZE(capability_hooks),
"capability");
+   return 0;
 }
 
+DEFINE_LSM(capability) = {
+   .name = "capability",
+   .order = LSM_ORDER_FIRST,
+   .init = capability_init,
+};
+
 #endif /* CONFIG_SECURITY */
diff --git a/security/security.c b/security/security.c
index 701507174f40..eab64bdc60fb 100644
--- a/security/security.c
+++ b/security/security.c
@@ -277,11 +277,6 @@ int __init security_init(void)
 i++)
INIT_HLIST_HEAD([i]);
 
-   /*
-* Load minor LSMs, with the capability module always first.
-*/
-   capability_add_hooks();
-
/* Load LSMs in specified order. */
ordered_lsm_init();
 
-- 
2.14.5


___
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 v5 23/38] SELinux: Remove cred security blob poisoning

2018-11-27 Thread Casey Schaufler
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 
Signed-off-by: Kees Cook 
---
 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 24b6b459fa2a..41b230d459a6 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3922,12 +3922,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.14.5


___
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 v5 14/38] LSM: Add all exclusive LSMs to ordered initialization

2018-11-27 Thread Casey Schaufler
This removes CONFIG_DEFAULT_SECURITY in favor of the explicit ordering
offered by CONFIG_LSM and adds all the exclusive LSMs to the ordered
LSM initialization. The old meaning of CONFIG_DEFAULT_SECURITY is now
captured by which exclusive LSM is listed first in the LSM order. All
LSMs not added to the ordered list are explicitly disabled.

Signed-off-by: Kees Cook 
Signed-off-by: Casey Schaufler 
---
 security/security.c | 45 -
 1 file changed, 20 insertions(+), 25 deletions(-)

diff --git a/security/security.c b/security/security.c
index 0009ef6c83fa..df71b54c1ba4 100644
--- a/security/security.c
+++ b/security/security.c
@@ -169,8 +169,6 @@ static void __init ordered_lsm_parse(const char *order, 
const char *origin)
char *sep, *name, *next;
 
/* Process "security=", if given. */
-   if (!chosen_major_lsm)
-   chosen_major_lsm = CONFIG_DEFAULT_SECURITY;
if (chosen_major_lsm) {
struct lsm_info *major;
 
@@ -198,8 +196,7 @@ static void __init ordered_lsm_parse(const char *order, 
const char *origin)
bool found = false;
 
for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
-   if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) == 0 &&
-   strcmp(lsm->name, name) == 0) {
+   if (strcmp(lsm->name, name) == 0) {
append_ordered_lsm(lsm, origin);
found = true;
}
@@ -208,6 +205,25 @@ static void __init ordered_lsm_parse(const char *order, 
const char *origin)
if (!found)
init_debug("%s ignored: %s\n", origin, name);
}
+
+   /* Process "security=", if given. */
+   if (chosen_major_lsm) {
+   for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
+   if (exists_ordered_lsm(lsm))
+   continue;
+   if (strcmp(lsm->name, chosen_major_lsm) == 0)
+   append_ordered_lsm(lsm, "security=");
+   }
+   }
+
+   /* Disable all LSMs not in the ordered list. */
+   for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
+   if (exists_ordered_lsm(lsm))
+   continue;
+   set_enabled(lsm, false);
+   init_debug("%s disabled: %s\n", origin, lsm->name);
+   }
+
kfree(sep);
 }
 
@@ -229,22 +245,6 @@ static void __init ordered_lsm_init(void)
kfree(ordered_lsms);
 }
 
-static void __init major_lsm_init(void)
-{
-   struct lsm_info *lsm;
-
-   for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
-   if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) == 0)
-   continue;
-
-   /* Enable this LSM, if it is not already set. */
-   if (!lsm->enabled)
-   lsm->enabled = _enabled_true;
-
-   maybe_initialize_lsm(lsm);
-   }
-}
-
 /**
  * security_init - initializes the security framework
  *
@@ -271,11 +271,6 @@ int __init security_init(void)
/* Load LSMs in specified order. */
ordered_lsm_init();
 
-   /*
-* Load all the remaining security modules.
-*/
-   major_lsm_init();
-
return 0;
 }
 
-- 
2.14.5


___
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 v5 18/38] LSM: Introduce enum lsm_order

2018-11-27 Thread Casey Schaufler
In preparation for distinguishing the "capability" LSM from other LSMs, it
must be ordered first. This introduces LSM_ORDER_MUTABLE for the general
LSMs and LSM_ORDER_FIRST for capability. In the future LSM_ORDER_LAST
for could be added for anything that must run last (e.g. Landlock may
use this).

Signed-off-by: Kees Cook 
---
 include/linux/lsm_hooks.h | 6 ++
 security/security.c   | 9 -
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 6cfbd7d78a89..83858e3df9e5 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2042,8 +2042,14 @@ extern void security_add_hooks(struct security_hook_list 
*hooks, int count,
 #define LSM_FLAG_LEGACY_MAJOR  BIT(0)
 #define LSM_FLAG_EXCLUSIVE BIT(1)
 
+enum lsm_order {
+   LSM_ORDER_FIRST = -1,   /* This is only for capabilities. */
+   LSM_ORDER_MUTABLE = 0,
+};
+
 struct lsm_info {
const char *name;   /* Required. */
+   enum lsm_order order;   /* Optional: default is LSM_ORDER_MUTABLE */
unsigned long flags;/* Optional: flags describing LSM */
int *enabled;   /* Optional: controlled by CONFIG_LSM */
int (*init)(void);  /* Required. */
diff --git a/security/security.c b/security/security.c
index 0c3c66dbf51c..701507174f40 100644
--- a/security/security.c
+++ b/security/security.c
@@ -174,6 +174,12 @@ static void __init ordered_lsm_parse(const char *order, 
const char *origin)
struct lsm_info *lsm;
char *sep, *name, *next;
 
+   /* LSM_ORDER_FIRST is always first. */
+   for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
+   if (lsm->order == LSM_ORDER_FIRST)
+   append_ordered_lsm(lsm, "first");
+   }
+
/* Process "security=", if given. */
if (chosen_major_lsm) {
struct lsm_info *major;
@@ -202,7 +208,8 @@ static void __init ordered_lsm_parse(const char *order, 
const char *origin)
bool found = false;
 
for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
-   if (strcmp(lsm->name, name) == 0) {
+   if (lsm->order == LSM_ORDER_MUTABLE &&
+   strcmp(lsm->name, name) == 0) {
append_ordered_lsm(lsm, origin);
found = true;
}
-- 
2.14.5


___
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 v5 13/38] selinux: Remove SECURITY_SELINUX_BOOTPARAM_VALUE

2018-11-27 Thread Casey Schaufler
In preparation for removing CONFIG_DEFAULT_SECURITY, this removes the
soon-to-be redundant SECURITY_SELINUX_BOOTPARAM_VALUE. Since explicit
ordering via CONFIG_LSM or "lsm=" will define whether an LSM is enabled or
not, this CONFIG will become effectively ignored, so remove it. However,
in order to stay backward-compatible with "security=selinux", the enable
variable defaults to true.

Signed-off-by: Kees Cook 
---
 security/selinux/Kconfig | 15 ---
 security/selinux/hooks.c |  5 +
 2 files changed, 1 insertion(+), 19 deletions(-)

diff --git a/security/selinux/Kconfig b/security/selinux/Kconfig
index 8af7a690eb40..55f032f1fc2d 100644
--- a/security/selinux/Kconfig
+++ b/security/selinux/Kconfig
@@ -22,21 +22,6 @@ config SECURITY_SELINUX_BOOTPARAM
 
  If you are unsure how to answer this question, answer N.
 
-config SECURITY_SELINUX_BOOTPARAM_VALUE
-   int "NSA SELinux boot parameter default value"
-   depends on SECURITY_SELINUX_BOOTPARAM
-   range 0 1
-   default 1
-   help
- This option sets the default value for the kernel parameter
- 'selinux', which allows SELinux to be disabled at boot.  If this
- option is set to 0 (zero), the SELinux kernel parameter will
- default to 0, disabling SELinux at bootup.  If this option is
- set to 1 (one), the SELinux kernel parameter will default to 1,
- enabling SELinux at bootup.
-
- If you are unsure how to answer this question, answer 1.
-
 config SECURITY_SELINUX_DISABLE
bool "NSA SELinux runtime disable"
depends on SECURITY_SELINUX
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 3687599d9d16..edd5b8dd3e56 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -120,9 +120,8 @@ __setup("enforcing=", enforcing_setup);
 #define selinux_enforcing_boot 1
 #endif
 
+int selinux_enabled __lsm_ro_after_init = 1;
 #ifdef CONFIG_SECURITY_SELINUX_BOOTPARAM
-int selinux_enabled = CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE;
-
 static int __init selinux_enabled_setup(char *str)
 {
unsigned long enabled;
@@ -131,8 +130,6 @@ static int __init selinux_enabled_setup(char *str)
return 1;
 }
 __setup("selinux=", selinux_enabled_setup);
-#else
-int selinux_enabled = 1;
 #endif
 
 static unsigned int selinux_checkreqprot_boot =
-- 
2.14.5


___
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 v5 05/38] LSM: Build ordered list of LSMs to initialize

2018-11-27 Thread Casey Schaufler
This constructs an ordered list of LSMs to initialize, using a hard-coded
list of only "integrity": minor LSMs continue to have direct hook calls,
and major LSMs continue to initialize separately.

Signed-off-by: Kees Cook 
Reviewed-by: Casey Schaufler 
---
 security/security.c | 58 -
 1 file changed, 53 insertions(+), 5 deletions(-)

diff --git a/security/security.c b/security/security.c
index 7562da854b62..4c193aba4531 100644
--- a/security/security.c
+++ b/security/security.c
@@ -37,6 +37,9 @@
 /* Maximum number of letters for an LSM name string */
 #define SECURITY_NAME_MAX  10
 
+/* How many LSMs were built into the kernel? */
+#define LSM_COUNT (__end_lsm_info - __start_lsm_info)
+
 struct security_hook_heads security_hook_heads __lsm_ro_after_init;
 static ATOMIC_NOTIFIER_HEAD(lsm_notifier_chain);
 
@@ -45,6 +48,9 @@ char *lsm_names;
 static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
CONFIG_DEFAULT_SECURITY;
 
+/* Ordered list of LSMs to initialize. */
+static __initdata struct lsm_info **ordered_lsms;
+
 static __initdata bool debug;
 #define init_debug(...)\
do {\
@@ -85,6 +91,34 @@ static void __init set_enabled(struct lsm_info *lsm, bool 
enabled)
}
 }
 
+/* Is an LSM already listed in the ordered LSMs list? */
+static bool __init exists_ordered_lsm(struct lsm_info *lsm)
+{
+   struct lsm_info **check;
+
+   for (check = ordered_lsms; *check; check++)
+   if (*check == lsm)
+   return true;
+
+   return false;
+}
+
+/* Append an LSM to the list of ordered LSMs to initialize. */
+static int last_lsm __initdata;
+static void __init append_ordered_lsm(struct lsm_info *lsm, const char *from)
+{
+   /* Ignore duplicate selections. */
+   if (exists_ordered_lsm(lsm))
+   return;
+
+   if (WARN(last_lsm == LSM_COUNT, "%s: out of LSM slots!?\n", from))
+   return;
+
+   ordered_lsms[last_lsm++] = lsm;
+   init_debug("%s ordering: %s (%sabled)\n", from, lsm->name,
+  is_enabled(lsm) ? "en" : "dis");
+}
+
 /* Is an LSM allowed to be initialized? */
 static bool __init lsm_allowed(struct lsm_info *lsm)
 {
@@ -121,18 +155,32 @@ static void __init maybe_initialize_lsm(struct lsm_info 
*lsm)
}
 }
 
-static void __init ordered_lsm_init(void)
+/* Populate ordered LSMs list from single LSM name. */
+static void __init ordered_lsm_parse(const char *order, const char *origin)
 {
struct lsm_info *lsm;
 
for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
-   if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) != 0)
-   continue;
-
-   maybe_initialize_lsm(lsm);
+   if (strcmp(lsm->name, order) == 0)
+   append_ordered_lsm(lsm, origin);
}
 }
 
+static void __init ordered_lsm_init(void)
+{
+   struct lsm_info **lsm;
+
+   ordered_lsms = kcalloc(LSM_COUNT + 1, sizeof(*ordered_lsms),
+   GFP_KERNEL);
+
+   ordered_lsm_parse("integrity", "builtin");
+
+   for (lsm = ordered_lsms; *lsm; lsm++)
+   maybe_initialize_lsm(*lsm);
+
+   kfree(ordered_lsms);
+}
+
 static void __init major_lsm_init(void)
 {
struct lsm_info *lsm;
-- 
2.14.5


___
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 v5 10/38] LSM: Refactor "security=" in terms of enable/disable

2018-11-27 Thread Casey Schaufler
For what are marked as the Legacy Major LSMs, make them effectively
exclusive when selected on the "security=" boot parameter, to handle
the future case of when a previously major LSMs become non-exclusive
(e.g. when TOMOYO starts blob-sharing).

Signed-off-by: Kees Cook 
Reviewed-by: Casey Schaufler 
---
 security/security.c | 28 
 1 file changed, 20 insertions(+), 8 deletions(-)

diff --git a/security/security.c b/security/security.c
index f4a7b7d52d71..a7889885585e 100644
--- a/security/security.c
+++ b/security/security.c
@@ -129,14 +129,6 @@ static bool __init lsm_allowed(struct lsm_info *lsm)
if (!is_enabled(lsm))
return false;
 
-   /* Skip major-specific checks if not a major LSM. */
-   if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) == 0)
-   return true;
-
-   /* Disabled if this LSM isn't the chosen one. */
-   if (strcmp(lsm->name, chosen_major_lsm) != 0)
-   return false;
-
return true;
 }
 
@@ -164,8 +156,28 @@ static void __init ordered_lsm_parse(const char *order, 
const char *origin)
struct lsm_info *lsm;
char *sep, *name, *next;
 
+   /* Process "security=", if given. */
if (!chosen_major_lsm)
chosen_major_lsm = CONFIG_DEFAULT_SECURITY;
+   if (chosen_major_lsm) {
+   struct lsm_info *major;
+
+   /*
+* To match the original "security=" behavior, this
+* explicitly does NOT fallback to another Legacy Major
+* if the selected one was separately disabled: disable
+* all non-matching Legacy Major LSMs.
+*/
+   for (major = __start_lsm_info; major < __end_lsm_info;
+major++) {
+   if ((major->flags & LSM_FLAG_LEGACY_MAJOR) &&
+   strcmp(major->name, chosen_major_lsm) != 0) {
+   set_enabled(major, false);
+   init_debug("security=%s disabled: %s\n",
+  chosen_major_lsm, major->name);
+   }
+   }
+   }
 
sep = kstrdup(order, GFP_KERNEL);
next = sep;
-- 
2.14.5


___
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 v5 02/38] LSM: Provide separate ordered initialization

2018-11-27 Thread Casey Schaufler
This provides a place for ordered LSMs to be initialized, separate from
the "major" LSMs. This is mainly a copy/paste from major_lsm_init() to
ordered_lsm_init(), but it will change drastically in later patches.

What is not obvious in the patch is that this change moves the integrity
LSM from major_lsm_init() into ordered_lsm_init(), since it is not marked
with the LSM_FLAG_LEGACY_MAJOR. As it is the only LSM in the "ordered"
list, there is no reordering yet created.

Signed-off-by: Kees Cook 
Reviewed-by: Casey Schaufler 
Reviewed-by: John Johansen 
---
 security/security.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/security/security.c b/security/security.c
index 04d173eb93f6..0688dfd57e95 100644
--- a/security/security.c
+++ b/security/security.c
@@ -52,12 +52,30 @@ static __initdata bool debug;
pr_info(__VA_ARGS__);   \
} while (0)
 
+static void __init ordered_lsm_init(void)
+{
+   struct lsm_info *lsm;
+   int ret;
+
+   for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
+   if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) != 0)
+   continue;
+
+   init_debug("initializing %s\n", lsm->name);
+   ret = lsm->init();
+   WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret);
+   }
+}
+
 static void __init major_lsm_init(void)
 {
struct lsm_info *lsm;
int ret;
 
for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
+   if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) == 0)
+   continue;
+
init_debug("initializing %s\n", lsm->name);
ret = lsm->init();
WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret);
@@ -87,6 +105,9 @@ int __init security_init(void)
yama_add_hooks();
loadpin_add_hooks();
 
+   /* Load LSMs in specified order. */
+   ordered_lsm_init();
+
/*
 * Load all the remaining security modules.
 */
-- 
2.14.5


___
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 v5 08/38] LSM: Tie enabling logic to presence in ordered list

2018-11-27 Thread Casey Schaufler
Until now, any LSM without an enable storage variable was considered
enabled. This inverts the logic and sets defaults to true only if the
LSM gets added to the ordered initialization list. (And an exception
continues for the major LSMs until they are integrated into the ordered
initialization in a later patch.)

Signed-off-by: Kees Cook 
---
 include/linux/lsm_hooks.h |  2 +-
 security/security.c   | 14 +++---
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index dabd2761acfc..272791fdd26e 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2044,7 +2044,7 @@ extern void security_add_hooks(struct security_hook_list 
*hooks, int count,
 struct lsm_info {
const char *name;   /* Required. */
unsigned long flags;/* Optional: flags describing LSM */
-   int *enabled;   /* Optional: NULL means enabled. */
+   int *enabled;   /* Optional: controlled by CONFIG_LSM */
int (*init)(void);  /* Required. */
 };
 
diff --git a/security/security.c b/security/security.c
index 38fc436e8b4b..ea760d625af6 100644
--- a/security/security.c
+++ b/security/security.c
@@ -63,10 +63,10 @@ static __initdata bool debug;
 
 static bool __init is_enabled(struct lsm_info *lsm)
 {
-   if (!lsm->enabled || *lsm->enabled)
-   return true;
+   if (!lsm->enabled)
+   return false;
 
-   return false;
+   return *lsm->enabled;
 }
 
 /* Mark an LSM's enabled flag. */
@@ -117,7 +117,11 @@ static void __init append_ordered_lsm(struct lsm_info 
*lsm, const char *from)
if (WARN(last_lsm == LSM_COUNT, "%s: out of LSM slots!?\n", from))
return;
 
+   /* Enable this LSM, if it is not already set. */
+   if (!lsm->enabled)
+   lsm->enabled = _enabled_true;
ordered_lsms[last_lsm++] = lsm;
+
init_debug("%s ordering: %s (%sabled)\n", from, lsm->name,
   is_enabled(lsm) ? "en" : "dis");
 }
@@ -210,6 +214,10 @@ static void __init major_lsm_init(void)
if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) == 0)
continue;
 
+   /* Enable this LSM, if it is not already set. */
+   if (!lsm->enabled)
+   lsm->enabled = _enabled_true;
+
maybe_initialize_lsm(lsm);
}
 }
-- 
2.14.5


___
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 v5 04/38] LSM: Lift LSM selection out of individual LSMs

2018-11-27 Thread Casey Schaufler
As a prerequisite to adjusting LSM selection logic in the future, this
moves the selection logic up out of the individual major LSMs, making
their init functions only run when actually enabled. This considers all
LSMs enabled by default unless they specified an external "enable"
variable.

Signed-off-by: Kees Cook 
Reviewed-by: Casey Schaufler 
Reviewed-by: John Johansen 
---
 include/linux/lsm_hooks.h  |   1 -
 security/apparmor/lsm.c|   6 ---
 security/security.c| 102 +++--
 security/selinux/hooks.c   |  10 -
 security/smack/smack_lsm.c |   3 --
 security/tomoyo/tomoyo.c   |   2 -
 6 files changed, 71 insertions(+), 53 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 4e2e9cdf78c6..dabd2761acfc 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2085,7 +2085,6 @@ 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 void __init capability_add_hooks(void);
 #ifdef CONFIG_SECURITY_YAMA
 extern void __init yama_add_hooks(void);
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 127a540ef63a..d840c1ef3e4d 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -1662,12 +1662,6 @@ static int __init apparmor_init(void)
 {
int error;
 
-   if (!apparmor_enabled || !security_module_enable("apparmor")) {
-   aa_info_message("AppArmor disabled by boot time parameter");
-   apparmor_enabled = false;
-   return 0;
-   }
-
aa_secids_init();
 
error = aa_setup_dfa_engine();
diff --git a/security/security.c b/security/security.c
index 0688dfd57e95..7562da854b62 100644
--- a/security/security.c
+++ b/security/security.c
@@ -52,33 +52,96 @@ static __initdata bool debug;
pr_info(__VA_ARGS__);   \
} while (0)
 
+static bool __init is_enabled(struct lsm_info *lsm)
+{
+   if (!lsm->enabled || *lsm->enabled)
+   return true;
+
+   return false;
+}
+
+/* Mark an LSM's enabled flag. */
+static int lsm_enabled_true __initdata = 1;
+static int lsm_enabled_false __initdata = 0;
+static void __init set_enabled(struct lsm_info *lsm, bool enabled)
+{
+   /*
+* When an LSM hasn't configured an enable variable, we can use
+* a hard-coded location for storing the default enabled state.
+*/
+   if (!lsm->enabled) {
+   if (enabled)
+   lsm->enabled = _enabled_true;
+   else
+   lsm->enabled = _enabled_false;
+   } else if (lsm->enabled == _enabled_true) {
+   if (!enabled)
+   lsm->enabled = _enabled_false;
+   } else if (lsm->enabled == _enabled_false) {
+   if (enabled)
+   lsm->enabled = _enabled_true;
+   } else {
+   *lsm->enabled = enabled;
+   }
+}
+
+/* Is an LSM allowed to be initialized? */
+static bool __init lsm_allowed(struct lsm_info *lsm)
+{
+   /* Skip if the LSM is disabled. */
+   if (!is_enabled(lsm))
+   return false;
+
+   /* Skip major-specific checks if not a major LSM. */
+   if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) == 0)
+   return true;
+
+   /* Disabled if this LSM isn't the chosen one. */
+   if (strcmp(lsm->name, chosen_lsm) != 0)
+   return false;
+
+   return true;
+}
+
+/* Check if LSM should be initialized. */
+static void __init maybe_initialize_lsm(struct lsm_info *lsm)
+{
+   int enabled = lsm_allowed(lsm);
+
+   /* Record enablement (to handle any following exclusive LSMs). */
+   set_enabled(lsm, enabled);
+
+   /* If selected, initialize the LSM. */
+   if (enabled) {
+   int ret;
+
+   init_debug("initializing %s\n", lsm->name);
+   ret = lsm->init();
+   WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret);
+   }
+}
+
 static void __init ordered_lsm_init(void)
 {
struct lsm_info *lsm;
-   int ret;
 
for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) != 0)
continue;
 
-   init_debug("initializing %s\n", lsm->name);
-   ret = lsm->init();
-   WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret);
+   maybe_initialize_lsm(lsm);
}
 }
 
 static void __init major_lsm_init(void)
 {
struct lsm_info *lsm;
-   int ret;
 
for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
 

[PATCH v5 06/38] LSM: Introduce CONFIG_LSM

2018-11-27 Thread Casey Schaufler
This provides a way to declare LSM initialization order via the new
CONFIG_LSM. Currently only non-major LSMs are recognized. This will
be expanded in future patches.

Signed-off-by: Kees Cook 
---
 security/Kconfig|  9 +
 security/security.c | 27 ++-
 2 files changed, 31 insertions(+), 5 deletions(-)

diff --git a/security/Kconfig b/security/Kconfig
index d9aa521b5206..7de42bbacc28 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -276,5 +276,14 @@ config DEFAULT_SECURITY
default "apparmor" if DEFAULT_SECURITY_APPARMOR
default "" if DEFAULT_SECURITY_DAC
 
+config LSM
+   string "Ordered list of enabled LSMs"
+   default "integrity"
+   help
+ A comma-separated list of LSMs, in initialization order.
+ Any LSMs left off this list will be ignored.
+
+ If unsure, leave this as the default.
+
 endmenu
 
diff --git a/security/security.c b/security/security.c
index 4c193aba4531..96e0b7d057b0 100644
--- a/security/security.c
+++ b/security/security.c
@@ -48,6 +48,8 @@ char *lsm_names;
 static __initdata char chosen_lsm[SECURITY_NAME_MAX + 1] =
CONFIG_DEFAULT_SECURITY;
 
+static __initconst const char * const builtin_lsm_order = CONFIG_LSM;
+
 /* Ordered list of LSMs to initialize. */
 static __initdata struct lsm_info **ordered_lsms;
 
@@ -155,15 +157,30 @@ static void __init maybe_initialize_lsm(struct lsm_info 
*lsm)
}
 }
 
-/* Populate ordered LSMs list from single LSM name. */
+/* Populate ordered LSMs list from comma-separated LSM name list. */
 static void __init ordered_lsm_parse(const char *order, const char *origin)
 {
struct lsm_info *lsm;
+   char *sep, *name, *next;
+
+   sep = kstrdup(order, GFP_KERNEL);
+   next = sep;
+   /* Walk the list, looking for matching LSMs. */
+   while ((name = strsep(, ",")) != NULL) {
+   bool found = false;
+
+   for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
+   if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) == 0 &&
+   strcmp(lsm->name, name) == 0) {
+   append_ordered_lsm(lsm, origin);
+   found = true;
+   }
+   }
 
-   for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
-   if (strcmp(lsm->name, order) == 0)
-   append_ordered_lsm(lsm, origin);
+   if (!found)
+   init_debug("%s ignored: %s\n", origin, name);
}
+   kfree(sep);
 }
 
 static void __init ordered_lsm_init(void)
@@ -173,7 +190,7 @@ static void __init ordered_lsm_init(void)
ordered_lsms = kcalloc(LSM_COUNT + 1, sizeof(*ordered_lsms),
GFP_KERNEL);
 
-   ordered_lsm_parse("integrity", "builtin");
+   ordered_lsm_parse(builtin_lsm_order, "builtin");
 
for (lsm = ordered_lsms; *lsm; lsm++)
maybe_initialize_lsm(*lsm);
-- 
2.14.5


___
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 v5 00/38] LSM: Module stacking for SARA and Landlock

2018-11-27 Thread Casey Schaufler
v5: Include Kees Cook's rework of the lsm command
line interface. Stacking is not conditional.
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 "security="
option works as before. A new "lsm=" option allows the
order of module execution to be supplied at boot time.

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#blob-4.20-rc2

Signed-off-by: Casey Schaufler 
---
 Documentation/admin-guide/LSM/index.rst |  13 +-
 Documentation/admin-guide/kernel-parameters.txt |   4 +
 fs/proc/base.c  |  64 ++-
 fs/proc/internal.h  |   1 +
 include/linux/cred.h|   1 -
 include/linux/lsm_hooks.h   |  40 +-
 include/linux/security.h|  15 +-
 include/linux/selinux.h |  35 --
 kernel/cred.c   |  13 -
 security/Kconfig|  41 +-
 security/apparmor/Kconfig   |  16 -
 security/apparmor/domain.c  |   2 +-
 security/apparmor/include/cred.h|  16 +-
 security/apparmor/include/file.h|   5 +-
 security/apparmor/include/lib.h |   4 +
 security/apparmor/include/task.h|  18 +-
 security/apparmor/lsm.c |  65 ++-
 security/apparmor/task.c|   6 +-
 security/commoncap.c|   9 +-
 security/loadpin/loadpin.c  |   8 +-
 security/security.c | 635 +---
 security/selinux/Kconfig|  15 -
 security/selinux/Makefile   |   2 +-
 security/selinux/exports.c  |  23 -
 security/selinux/hooks.c| 345 -
 security/selinux/include/audit.h|   3 -
 security/selinux/include/objsec.h   |  38 +-
 security/selinux/selinuxfs.c|   4 +-
 security/selinux/ss/services.c  |   1 -
 security/selinux/xfrm.c |   4 +-
 security/smack/smack.h  |  44 +-
 security/smack/smack_access.c   |   4 +-
 security/smack/smack_lsm.c  | 316 
 security/smack/smackfs.c|  18 +-
 security/tomoyo/common.h|  22 +-
 security/tomoyo/domain.c|   4 +-
 security/tomoyo/securityfs_if.c |  15 +-
 security/tomoyo/tomoyo.c|  49 +-
 security/yama/yama_lsm.c|   8 +-
 39 files changed, 1133 insertions(+), 793 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 v6 5/5] sidechannel: Linux Security Module for sidechannel

2018-11-05 Thread Casey Schaufler
From: Casey Schaufler 

This is a new Linux Security Module (LSM) that checks for
potential sidechannel issues that are not covered in the
ptrace PTRACE_MODE_SCHED option. Namespace differences are
checked in this intitial version. Additional checks should
be added when they are determined to be useful.

Signed-off-by: Casey Schaufler 
---
 include/linux/lsm_hooks.h  |  5 ++
 security/Kconfig   |  1 +
 security/Makefile  |  2 +
 security/security.c|  1 +
 security/sidechannel/Kconfig   | 13 +
 security/sidechannel/Makefile  |  1 +
 security/sidechannel/sidechannel.c | 88 ++
 7 files changed, 111 insertions(+)
 create mode 100644 security/sidechannel/Kconfig
 create mode 100644 security/sidechannel/Makefile
 create mode 100644 security/sidechannel/sidechannel.c

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 97a020c616ad..3cb6516dba3c 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2081,5 +2081,10 @@ void __init loadpin_add_hooks(void);
 #else
 static inline void loadpin_add_hooks(void) { };
 #endif
+#ifdef CONFIG_SECURITY_SIDECHANNEL
+void __init sidechannel_add_hooks(void);
+#else
+static inline void sidechannel_add_hooks(void) { };
+#endif
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/security/Kconfig b/security/Kconfig
index d9aa521b5206..6b814a3f93ea 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -236,6 +236,7 @@ source security/tomoyo/Kconfig
 source security/apparmor/Kconfig
 source security/loadpin/Kconfig
 source security/yama/Kconfig
+source security/sidechannel/Kconfig
 
 source security/integrity/Kconfig
 
diff --git a/security/Makefile b/security/Makefile
index 4d2d3782ddef..d0c9e1b227f9 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -10,6 +10,7 @@ subdir-$(CONFIG_SECURITY_TOMOYO)+= tomoyo
 subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
 subdir-$(CONFIG_SECURITY_YAMA) += yama
 subdir-$(CONFIG_SECURITY_LOADPIN)  += loadpin
+subdir-$(CONFIG_SECURITY_SIDECHANNEL)  += sidechannel
 
 # always enable default capabilities
 obj-y  += commoncap.o
@@ -25,6 +26,7 @@ obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/
 obj-$(CONFIG_SECURITY_APPARMOR)+= apparmor/
 obj-$(CONFIG_SECURITY_YAMA)+= yama/
 obj-$(CONFIG_SECURITY_LOADPIN) += loadpin/
+obj-$(CONFIG_SECURITY_SIDECHANNEL) += sidechannel/
 obj-$(CONFIG_CGROUP_DEVICE)+= device_cgroup.o
 
 # Object integrity file lists
diff --git a/security/security.c b/security/security.c
index 12460f20c652..6047634d86a0 100644
--- a/security/security.c
+++ b/security/security.c
@@ -85,6 +85,7 @@ int __init security_init(void)
capability_add_hooks();
yama_add_hooks();
loadpin_add_hooks();
+   sidechannel_add_hooks();
 
/*
 * Load all the remaining security modules.
diff --git a/security/sidechannel/Kconfig b/security/sidechannel/Kconfig
new file mode 100644
index ..653033027415
--- /dev/null
+++ b/security/sidechannel/Kconfig
@@ -0,0 +1,13 @@
+config SECURITY_SIDECHANNEL
+   bool "Sidechannel attack safety extra checks"
+   depends on SECURITY
+   default n
+   help
+ Look for a variety of cases where a side-channel attack
+ could potentially be exploited. Instruct the switching
+ code to use the indirect_branch_prediction_barrier in
+ cases where the passed task and the current task may be
+ at risk.
+
+  If you are unsure how to answer this question, answer N.
+
diff --git a/security/sidechannel/Makefile b/security/sidechannel/Makefile
new file mode 100644
index ..f61d83f28035
--- /dev/null
+++ b/security/sidechannel/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SECURITY_SIDECHANNEL) += sidechannel.o
diff --git a/security/sidechannel/sidechannel.c 
b/security/sidechannel/sidechannel.c
new file mode 100644
index ..18a67d19c020
--- /dev/null
+++ b/security/sidechannel/sidechannel.c
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Side Channel Safety Security Module
+ *
+ * Copyright (C) 2018 Intel Corporation.
+ *
+ */
+
+#define pr_fmt(fmt) "SideChannel: " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef CONFIG_NAMESPACES
+/**
+ * safe_by_namespace - Are task and current sidechannel safe?
+ * @p: task to check on
+ *
+ * Returns 0 if the tasks are sidechannel safe, -EACCES otherwise.
+ */
+static int safe_by_namespace(struct task_struct *p)
+{
+   struct cgroup_namespace *ccgn = NULL;
+   struct cgroup_namespace *pcgn = NULL;
+
+   /*
+* Namespace checks. Considered safe if:
+*  cgroup namespace is the same
+*  User namespace is the same
+*  PID namespace is the same
+*/
+   

[PATCH v6 4/5] Capability: Complete PTRACE_MODE_SCHED

2018-11-05 Thread Casey Schaufler
From: Casey Schaufler 

Allow a complete ptrace access check with mode PTRACE_MODE_SCHED.
Disable the inappropriate privilege check in the capability code
that does incompatible locking.

Signed-off-by: Casey Schaufler 
---
 kernel/ptrace.c  | 2 --
 security/commoncap.c | 3 ++-
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 99cfddde6a55..0b6a9df51c3b 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -331,8 +331,6 @@ static int __ptrace_may_access(struct task_struct *task, 
unsigned int mode)
 !ptrace_has_cap(mm->user_ns, mode)))
return -EPERM;
 
-   if (mode & PTRACE_MODE_SCHED)
-   return 0;
return security_ptrace_access_check(task, mode);
 }
 
diff --git a/security/commoncap.c b/security/commoncap.c
index 2e489d6a3ac8..70a7e3d19c16 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -152,7 +152,8 @@ int cap_ptrace_access_check(struct task_struct *child, 
unsigned int mode)
if (cred->user_ns == child_cred->user_ns &&
cap_issubset(child_cred->cap_permitted, *caller_caps))
goto out;
-   if (ns_capable(child_cred->user_ns, CAP_SYS_PTRACE))
+   if (!(mode & PTRACE_MODE_SCHED) &&
+   ns_capable(child_cred->user_ns, CAP_SYS_PTRACE))
goto out;
ret = -EPERM;
 out:
-- 
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 v6 1/5] AppArmor: Prepare for PTRACE_MODE_SCHED

2018-11-05 Thread Casey Schaufler
From: Casey Schaufler 

A ptrace access check with mode PTRACE_MODE_SCHED gets called
from process switching code. This precludes the use of audit,
as the locking is incompatible. Don't do audit in the PTRACE_MODE_SCHED
case.

Signed-off-by: Casey Schaufler 
---
 security/apparmor/domain.c  | 2 +-
 security/apparmor/include/ipc.h | 2 +-
 security/apparmor/ipc.c | 8 +---
 security/apparmor/lsm.c | 5 +++--
 4 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 08c88de0ffda..28300f4c3ef9 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -77,7 +77,7 @@ static int may_change_ptraced_domain(struct aa_label 
*to_label,
if (!tracer || unconfined(tracerl))
goto out;
 
-   error = aa_may_ptrace(tracerl, to_label, PTRACE_MODE_ATTACH);
+   error = aa_may_ptrace(tracerl, to_label, PTRACE_MODE_ATTACH, true);
 
 out:
rcu_read_unlock();
diff --git a/security/apparmor/include/ipc.h b/security/apparmor/include/ipc.h
index 5ffc218d1e74..299d1c45fef0 100644
--- a/security/apparmor/include/ipc.h
+++ b/security/apparmor/include/ipc.h
@@ -34,7 +34,7 @@ struct aa_profile;
"xcpu xfsz vtalrm prof winch io pwr sys emt lost"
 
 int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
- u32 request);
+ u32 request, bool audit);
 int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig);
 
 #endif /* __AA_IPC_H */
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
index 527ea1557120..9ed110afc822 100644
--- a/security/apparmor/ipc.c
+++ b/security/apparmor/ipc.c
@@ -121,15 +121,17 @@ static int profile_tracer_perm(struct aa_profile *tracer,
  * Returns: %0 else error code if permission denied or error
  */
 int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
- u32 request)
+ u32 request, bool audit)
 {
struct aa_profile *profile;
u32 xrequest = request << PTRACE_PERM_SHIFT;
DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE);
 
return xcheck_labels(tracer, tracee, profile,
-   profile_tracer_perm(profile, tracee, request, ),
-   profile_tracee_perm(profile, tracer, xrequest, ));
+   profile_tracer_perm(profile, tracee, request,
+   audit ?  : NULL),
+   profile_tracee_perm(profile, tracer, xrequest,
+   audit ?  : NULL));
 }
 
 
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 8b8b70620bbe..da9d0b228857 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -118,7 +118,8 @@ static int apparmor_ptrace_access_check(struct task_struct 
*child,
tracee = aa_get_task_label(child);
error = aa_may_ptrace(tracer, tracee,
(mode & PTRACE_MODE_READ) ? AA_PTRACE_READ
- : AA_PTRACE_TRACE);
+ : AA_PTRACE_TRACE,
+   !(mode & PTRACE_MODE_SCHED));
aa_put_label(tracee);
end_current_label_crit_section(tracer);
 
@@ -132,7 +133,7 @@ static int apparmor_ptrace_traceme(struct task_struct 
*parent)
 
tracee = begin_current_label_crit_section();
tracer = aa_get_task_label(parent);
-   error = aa_may_ptrace(tracer, tracee, AA_PTRACE_TRACE);
+   error = aa_may_ptrace(tracer, tracee, AA_PTRACE_TRACE, true);
aa_put_label(tracer);
end_current_label_crit_section(tracee);
 
-- 
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 v6 3/5] SELinux: Prepare for PTRACE_MODE_SCHED

2018-11-05 Thread Casey Schaufler
From: Casey Schaufler 

A ptrace access check with mode PTRACE_MODE_SCHED gets called
from process switching code. This precludes the use of audit or avc,
as the locking is incompatible. The only available check that
can be made without using avc is a comparison of the secids.
This is not very satisfactory as it will indicate possible
vulnerabilies much too aggressively.

Signed-off-by: Casey Schaufler 
---
 security/selinux/hooks.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index ad9a9b8e9979..160239791007 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2267,6 +2267,8 @@ static int selinux_ptrace_access_check(struct task_struct 
*child,
u32 sid = current_sid();
u32 csid = task_sid(child);
 
+   if (mode & PTRACE_MODE_SCHED)
+   return sid == csid ? 0 : -EACCES;
if (mode & PTRACE_MODE_READ)
return avc_has_perm(_state,
sid, csid, SECCLASS_FILE, FILE__READ, NULL);
-- 
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 v6 0/5] LSM: Support ptrace sidechannel access checks

2018-11-05 Thread Casey Schaufler
V6: Based on Tim Chen's "[Patch v4 00/18] Provide process property
based options to enable Spectre v2 userspace-userspace protection*"
patch set.
v5: Revamped to match Jiri Kosina 
Harden spectrev2 userspace-userspace protection v7
Fixed locking issues in the LSM code.
Dropped the new LSM hook and use a ptrace hook instead.
v4: select namespace checks if user namespaces are enabled
and credential checks are request.
v3: get_task_cred wasn't a good choice due to refcounts.
Use lower level protection instead
v2: SELinux access policy corrected.
Use real_cred instead of cred.

This patchset provide a mechanism by which a security module
can advise the system about potential side-channel vulnerabilities.
The existing security modules have been updated to avoid locking
issues in the face of PTRACE_MODE_SCHED. A new security
module is provided to make determinations regarding task attributes
including namespaces.

Signed-off-by: Casey Schaufler 
---
 include/linux/lsm_hooks.h  |  5 +++
 kernel/ptrace.c|  2 -
 security/Kconfig   |  1 +
 security/Makefile  |  2 +
 security/apparmor/domain.c |  2 +-
 security/apparmor/include/ipc.h|  2 +-
 security/apparmor/ipc.c|  8 ++--
 security/apparmor/lsm.c|  5 ++-
 security/commoncap.c   |  3 +-
 security/security.c|  1 +
 security/selinux/hooks.c   |  2 +
 security/sidechannel/Kconfig   | 13 ++
 security/sidechannel/Makefile  |  1 +
 security/sidechannel/sidechannel.c | 88 ++
 security/smack/smack_lsm.c |  3 +-
 15 files changed, 127 insertions(+), 11 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 v6 2/5] Smack: Prepare for PTRACE_MODE_SCHED

2018-11-05 Thread Casey Schaufler
From: Casey Schaufler 

A ptrace access check with mode PTRACE_MODE_SCHED gets called
from process switching code. This precludes the use of audit,
as the locking is incompatible. Don't do audit in the PTRACE_MODE_SCHED
case.

Signed-off-by: Casey Schaufler 
---
 security/smack/smack_lsm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 340fc30ad85d..ffa95bcab599 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -422,7 +422,8 @@ static int smk_ptrace_rule_check(struct task_struct *tracer,
struct task_smack *tsp;
struct smack_known *tracer_known;
 
-   if ((mode & PTRACE_MODE_NOAUDIT) == 0) {
+   if ((mode & PTRACE_MODE_NOAUDIT) == 0 &&
+   (mode & PTRACE_MODE_SCHED) == 0) {
smk_ad_init(, func, LSM_AUDIT_DATA_TASK);
smk_ad_setfield_u_tsk(, tracer);
saip = 
-- 
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 14/19] LSM: Infrastructure management of the inode security

2018-10-04 Thread Casey Schaufler
On 10/3/2018 11:13 AM, James Morris wrote:
> On Fri, 21 Sep 2018, Kees Cook wrote:
>
>> On Fri, Sep 21, 2018 at 5:19 PM, Casey Schaufler  
>> wrote:
>>> + * 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.
>>
> Calling panic() is not appropriate here. Perhaps if it was during 
> boot-time initialization of LSM infrastructure, but not on the fly.

Tetsuo's patch makes this an __init function. It's only for doing
init time stuff like root inode initialization during start-up.
If it fails the caller is going to have to panic. This came straight
out of the SELinux system initialization code. I could go back to
having each LSM do it's own panic, but that seems silly.

>
> Use a WARN_ONCE then propagate the error back and fail the operation.
>
>

___
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 v5 5/5] sidechannel: Linux Security Module for sidechannel

2018-09-28 Thread Casey Schaufler
On 9/27/2018 2:45 PM, James Morris wrote:
> On Wed, 26 Sep 2018, Casey Schaufler wrote:
>
>> +/*
>> + * Namespace checks. Considered safe if:
>> + *  cgroup namespace is the same
>> + *  User namespace is the same
>> + *  PID namespace is the same
>> + */
>> +if (current->nsproxy)
>> +ccgn = current->nsproxy->cgroup_ns;
>> +if (p->nsproxy)
>> +pcgn = p->nsproxy->cgroup_ns;
>> +if (ccgn != pcgn)
>> +return -EACCES;
>> +if (current->cred->user_ns != p->cred->user_ns)
>> +return -EACCES;
>> +if (task_active_pid_ns(current) != task_active_pid_ns(p))
>> +return -EACCES;
>> +return 0;
> I really don't like the idea of hard-coding namespace security semantics 
> in an LSM.  Also, I'm not sure if these semantics make any sense.

Checks on namespaces where explicitly requested. I think
these are the most sensible, but I'm willing to be educated.
I was also requested to check on potential issues between containers,
but as there is no kernel concept of containers this is the
best I see we can do.

> It least make it user configurable.

Would you have a suggested granularity? I could have a
configuration option for each of cgroups, user and pid
namespaces but that's getting to be a lot of knobs to
twist.

___
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 04/19] SELinux: Remove cred security blob poisoning

2018-09-28 Thread Casey Schaufler
On 9/27/2018 3:13 PM, James Morris wrote:
> On Fri, 21 Sep 2018, 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.
> If it's useful, it should be incorporated into core LSM, otherwise that's 
> a regression for SELinux

When I discussed this code with David Howells he indicated
that it was primarily used for debugging the original shared
credential implementation and that is was not especially
valuable any longer. If someone thinks it is valuable we
should consider doing it in the infrastructure for all the
blobs, not just the credential.

___
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 6/5] capability: Repair sidechannel test in ptrace

2018-09-27 Thread Casey Schaufler
From: Casey Schaufler 

The PTRACE_MODE_SCHED check erroniously returns 0 in
all cases. It should be returning -EPERM. This fixes
the logic to correct that error.

Signed-off-by: Casey Schaufler 
---
 security/commoncap.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/security/commoncap.c b/security/commoncap.c
index e77457110d05..70a7e3d19c16 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -152,9 +152,8 @@ int cap_ptrace_access_check(struct task_struct *child, 
unsigned int mode)
if (cred->user_ns == child_cred->user_ns &&
cap_issubset(child_cred->cap_permitted, *caller_caps))
goto out;
-   if (mode & PTRACE_MODE_SCHED)
-   goto out;
-   if (ns_capable(child_cred->user_ns, CAP_SYS_PTRACE))
+   if (!(mode & PTRACE_MODE_SCHED) &&
+   ns_capable(child_cred->user_ns, CAP_SYS_PTRACE))
goto out;
ret = -EPERM;
 out:
-- 
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 21/19] LSM: Cleanup and fixes from Tetsuo Handa

2018-09-27 Thread Casey Schaufler
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.

The original changes are from Tetsuo Handa. I have made minor
changes in some places, but this is mostly his code.

Signed-off-by: Casey Schaufler 
---
 include/linux/lsm_hooks.h |  6 ++
 security/security.c   | 27 ---
 security/selinux/hooks.c  |  5 -
 security/selinux/include/objsec.h |  2 ++
 security/smack/smack_lsm.c|  8 +++-
 5 files changed, 19 insertions(+), 29 deletions(-)

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 7e8b32fdf576..80146147531f 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2095,13 +2095,11 @@ 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);
 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 76f7dc49b63c..d986045dd4c0 100644
--- a/security/security.c
+++ b/security/security.c
@@ -267,7 +267,7 @@ EXPORT_SYMBOL(unregister_lsm_notifier);
  *
  * 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;
@@ -378,25 +378,6 @@ int lsm_inode_alloc(struct inode *inode)
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__);
-}
-
 /**
  * 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;
 
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 44337d2349d9..e54b7dbac775 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -332,8 +332,11 @@ static struct inode_security_struct 
*backing_inode_security(struct dentry *dentr
 static void inode_free_security(struct inode *inode)
 {
struct inode_security_struct *isec = selinux_inode(inode);
-   struct superblock_security_struct *sbsec = inode->i_sb->s_security;
+   struct superblock_security_struct *sbsec;
 
+   if (!isec)
+   return;
+   sbsec = inode->i_sb->s_security;
/*
 * As not all inode security structures are in a list, we check for
 * empty list outside of the lock to make sure that we won't waste
diff --git a/security/selinux/include/objsec.h 
b/security/selinux/include/objsec.h
index ee4471213909..8231ae02560e 100644
--- a/security/selinux/include/objsec.h
+++ b/security/selinux/include/objsec.h
@@ -180,6 +180,8 @@ static inline struct inode_security_struct *selinux_inode(
const struct inode *inode)
 {
 #ifdef CONFIG_SECURITY_STACKING
+   if (unlikely(!inode->i_security))
+   return NULL;
return inode->i_security + selinux_blob_sizes.lbs_inode;
 #else
return inode->i_security;
diff --git a/secur

[PATCH v4 20/19] LSM: Correct file blob free empty blob check

2018-09-27 Thread Casey Schaufler
Instead of checking if the kmem_cache for file blobs
has been initialized check if the blob is NULL. This
allows non-blob using modules to do other kinds of
clean up in the security_file_free hooks.

Signed-off-by: Casey Schaufler 
---
 security/security.c | 9 -
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/security/security.c b/security/security.c
index e7c8506041f1..76f7dc49b63c 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1202,14 +1202,13 @@ void security_file_free(struct file *file)
 {
void *blob;
 
-   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);
+   if (blob) {
+   file->f_security = NULL;
+   kmem_cache_free(lsm_file_cache, blob);
+   }
 }
 
 int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-- 
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 v5 4/5] Capability: Complete PTRACE_MODE_SCHED

2018-09-27 Thread Casey Schaufler
From: Casey Schaufler 

Allow a complete ptrace access check with mode PTRACE_MODE_SCHED.
Disable the inappropriate privilege check in the capability code
that does incompatible locking.

Signed-off-by: Casey Schaufler 
---
 kernel/ptrace.c  | 2 --
 security/commoncap.c | 2 ++
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 99cfddde6a55..0b6a9df51c3b 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -331,8 +331,6 @@ static int __ptrace_may_access(struct task_struct *task, 
unsigned int mode)
 !ptrace_has_cap(mm->user_ns, mode)))
return -EPERM;
 
-   if (mode & PTRACE_MODE_SCHED)
-   return 0;
return security_ptrace_access_check(task, mode);
 }
 
diff --git a/security/commoncap.c b/security/commoncap.c
index 2e489d6a3ac8..e77457110d05 100644
--- a/security/commoncap.c
+++ b/security/commoncap.c
@@ -152,6 +152,8 @@ int cap_ptrace_access_check(struct task_struct *child, 
unsigned int mode)
if (cred->user_ns == child_cred->user_ns &&
cap_issubset(child_cred->cap_permitted, *caller_caps))
goto out;
+   if (mode & PTRACE_MODE_SCHED)
+   goto out;
if (ns_capable(child_cred->user_ns, CAP_SYS_PTRACE))
goto out;
ret = -EPERM;
-- 
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 v5 2/5] Smack: Prepare for PTRACE_MODE_SCHED

2018-09-27 Thread Casey Schaufler
From: Casey Schaufler 

A ptrace access check with mode PTRACE_MODE_SCHED gets called
from process switching code. This precludes the use of audit,
as the locking is incompatible. Don't do audit in the PTRACE_MODE_SCHED
case.

Signed-off-by: Casey Schaufler 
---
 security/smack/smack_lsm.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 340fc30ad85d..ffa95bcab599 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -422,7 +422,8 @@ static int smk_ptrace_rule_check(struct task_struct *tracer,
struct task_smack *tsp;
struct smack_known *tracer_known;
 
-   if ((mode & PTRACE_MODE_NOAUDIT) == 0) {
+   if ((mode & PTRACE_MODE_NOAUDIT) == 0 &&
+   (mode & PTRACE_MODE_SCHED) == 0) {
smk_ad_init(, func, LSM_AUDIT_DATA_TASK);
smk_ad_setfield_u_tsk(, tracer);
saip = 
-- 
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 v5 5/5] sidechannel: Linux Security Module for sidechannel

2018-09-27 Thread Casey Schaufler
From: Casey Schaufler 

This is a new Linux Security Module (LSM) that checks for
potential sidechannel issues that are not covered in the
ptrace PTRACE_MODE_SCHED option. Namespace differences are
checked in this intitial version. Additional checks should
be added when they are determined to be useful.

Signed-off-by: Casey Schaufler 
---
 include/linux/lsm_hooks.h  |  5 ++
 security/Kconfig   |  1 +
 security/Makefile  |  2 +
 security/security.c|  1 +
 security/sidechannel/Kconfig   | 13 +
 security/sidechannel/Makefile  |  1 +
 security/sidechannel/sidechannel.c | 88 ++
 7 files changed, 111 insertions(+)
 create mode 100644 security/sidechannel/Kconfig
 create mode 100644 security/sidechannel/Makefile
 create mode 100644 security/sidechannel/sidechannel.c

diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 97a020c616ad..3cb6516dba3c 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -2081,5 +2081,10 @@ void __init loadpin_add_hooks(void);
 #else
 static inline void loadpin_add_hooks(void) { };
 #endif
+#ifdef CONFIG_SECURITY_SIDECHANNEL
+void __init sidechannel_add_hooks(void);
+#else
+static inline void sidechannel_add_hooks(void) { };
+#endif
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/security/Kconfig b/security/Kconfig
index d9aa521b5206..6b814a3f93ea 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -236,6 +236,7 @@ source security/tomoyo/Kconfig
 source security/apparmor/Kconfig
 source security/loadpin/Kconfig
 source security/yama/Kconfig
+source security/sidechannel/Kconfig
 
 source security/integrity/Kconfig
 
diff --git a/security/Makefile b/security/Makefile
index 4d2d3782ddef..d0c9e1b227f9 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -10,6 +10,7 @@ subdir-$(CONFIG_SECURITY_TOMOYO)+= tomoyo
 subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
 subdir-$(CONFIG_SECURITY_YAMA) += yama
 subdir-$(CONFIG_SECURITY_LOADPIN)  += loadpin
+subdir-$(CONFIG_SECURITY_SIDECHANNEL)  += sidechannel
 
 # always enable default capabilities
 obj-y  += commoncap.o
@@ -25,6 +26,7 @@ obj-$(CONFIG_SECURITY_TOMOYO) += tomoyo/
 obj-$(CONFIG_SECURITY_APPARMOR)+= apparmor/
 obj-$(CONFIG_SECURITY_YAMA)+= yama/
 obj-$(CONFIG_SECURITY_LOADPIN) += loadpin/
+obj-$(CONFIG_SECURITY_SIDECHANNEL) += sidechannel/
 obj-$(CONFIG_CGROUP_DEVICE)+= device_cgroup.o
 
 # Object integrity file lists
diff --git a/security/security.c b/security/security.c
index 736e78da1ab9..2129b0e31d7b 100644
--- a/security/security.c
+++ b/security/security.c
@@ -83,6 +83,7 @@ int __init security_init(void)
capability_add_hooks();
yama_add_hooks();
loadpin_add_hooks();
+   sidechannel_add_hooks();
 
/*
 * Load all the remaining security modules.
diff --git a/security/sidechannel/Kconfig b/security/sidechannel/Kconfig
new file mode 100644
index ..653033027415
--- /dev/null
+++ b/security/sidechannel/Kconfig
@@ -0,0 +1,13 @@
+config SECURITY_SIDECHANNEL
+   bool "Sidechannel attack safety extra checks"
+   depends on SECURITY
+   default n
+   help
+ Look for a variety of cases where a side-channel attack
+ could potentially be exploited. Instruct the switching
+ code to use the indirect_branch_prediction_barrier in
+ cases where the passed task and the current task may be
+ at risk.
+
+  If you are unsure how to answer this question, answer N.
+
diff --git a/security/sidechannel/Makefile b/security/sidechannel/Makefile
new file mode 100644
index ..f61d83f28035
--- /dev/null
+++ b/security/sidechannel/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_SECURITY_SIDECHANNEL) += sidechannel.o
diff --git a/security/sidechannel/sidechannel.c 
b/security/sidechannel/sidechannel.c
new file mode 100644
index ..18a67d19c020
--- /dev/null
+++ b/security/sidechannel/sidechannel.c
@@ -0,0 +1,88 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Side Channel Safety Security Module
+ *
+ * Copyright (C) 2018 Intel Corporation.
+ *
+ */
+
+#define pr_fmt(fmt) "SideChannel: " fmt
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#ifdef CONFIG_NAMESPACES
+/**
+ * safe_by_namespace - Are task and current sidechannel safe?
+ * @p: task to check on
+ *
+ * Returns 0 if the tasks are sidechannel safe, -EACCES otherwise.
+ */
+static int safe_by_namespace(struct task_struct *p)
+{
+   struct cgroup_namespace *ccgn = NULL;
+   struct cgroup_namespace *pcgn = NULL;
+
+   /*
+* Namespace checks. Considered safe if:
+*  cgroup namespace is the same
+*  User namespace is the same
+*  PID namespace is the same
+*/
+   

[PATCH v5 1/5] AppArmor: Prepare for PTRACE_MODE_SCHED

2018-09-27 Thread Casey Schaufler
From: Casey Schaufler 

A ptrace access check with mode PTRACE_MODE_SCHED gets called
from process switching code. This precludes the use of audit,
as the locking is incompatible. Don't do audit in the PTRACE_MODE_SCHED
case.

Signed-off-by: Casey Schaufler 
---
 security/apparmor/domain.c  | 2 +-
 security/apparmor/include/ipc.h | 2 +-
 security/apparmor/ipc.c | 8 +---
 security/apparmor/lsm.c | 5 +++--
 4 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
index 08c88de0ffda..28300f4c3ef9 100644
--- a/security/apparmor/domain.c
+++ b/security/apparmor/domain.c
@@ -77,7 +77,7 @@ static int may_change_ptraced_domain(struct aa_label 
*to_label,
if (!tracer || unconfined(tracerl))
goto out;
 
-   error = aa_may_ptrace(tracerl, to_label, PTRACE_MODE_ATTACH);
+   error = aa_may_ptrace(tracerl, to_label, PTRACE_MODE_ATTACH, true);
 
 out:
rcu_read_unlock();
diff --git a/security/apparmor/include/ipc.h b/security/apparmor/include/ipc.h
index 5ffc218d1e74..299d1c45fef0 100644
--- a/security/apparmor/include/ipc.h
+++ b/security/apparmor/include/ipc.h
@@ -34,7 +34,7 @@ struct aa_profile;
"xcpu xfsz vtalrm prof winch io pwr sys emt lost"
 
 int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
- u32 request);
+ u32 request, bool audit);
 int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig);
 
 #endif /* __AA_IPC_H */
diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c
index 527ea1557120..9ed110afc822 100644
--- a/security/apparmor/ipc.c
+++ b/security/apparmor/ipc.c
@@ -121,15 +121,17 @@ static int profile_tracer_perm(struct aa_profile *tracer,
  * Returns: %0 else error code if permission denied or error
  */
 int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee,
- u32 request)
+ u32 request, bool audit)
 {
struct aa_profile *profile;
u32 xrequest = request << PTRACE_PERM_SHIFT;
DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, OP_PTRACE);
 
return xcheck_labels(tracer, tracee, profile,
-   profile_tracer_perm(profile, tracee, request, ),
-   profile_tracee_perm(profile, tracer, xrequest, ));
+   profile_tracer_perm(profile, tracee, request,
+   audit ?  : NULL),
+   profile_tracee_perm(profile, tracer, xrequest,
+   audit ?  : NULL));
 }
 
 
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
index 8b8b70620bbe..da9d0b228857 100644
--- a/security/apparmor/lsm.c
+++ b/security/apparmor/lsm.c
@@ -118,7 +118,8 @@ static int apparmor_ptrace_access_check(struct task_struct 
*child,
tracee = aa_get_task_label(child);
error = aa_may_ptrace(tracer, tracee,
(mode & PTRACE_MODE_READ) ? AA_PTRACE_READ
- : AA_PTRACE_TRACE);
+ : AA_PTRACE_TRACE,
+   !(mode & PTRACE_MODE_SCHED));
aa_put_label(tracee);
end_current_label_crit_section(tracer);
 
@@ -132,7 +133,7 @@ static int apparmor_ptrace_traceme(struct task_struct 
*parent)
 
tracee = begin_current_label_crit_section();
tracer = aa_get_task_label(parent);
-   error = aa_may_ptrace(tracer, tracee, AA_PTRACE_TRACE);
+   error = aa_may_ptrace(tracer, tracee, AA_PTRACE_TRACE, true);
aa_put_label(tracer);
end_current_label_crit_section(tracee);
 
-- 
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 v5 3/5] SELinux: Prepare for PTRACE_MODE_SCHED

2018-09-27 Thread Casey Schaufler
From: Casey Schaufler 

A ptrace access check with mode PTRACE_MODE_SCHED gets called
from process switching code. This precludes the use of audit or avc,
as the locking is incompatible. The only available check that
can be made without using avc is a comparison of the secids.
This is not very satisfactory as it will indicate possible
vulnerabilies much too aggressively.

Signed-off-by: Casey Schaufler 
---
 security/selinux/hooks.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index ad9a9b8e9979..160239791007 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2267,6 +2267,8 @@ static int selinux_ptrace_access_check(struct task_struct 
*child,
u32 sid = current_sid();
u32 csid = task_sid(child);
 
+   if (mode & PTRACE_MODE_SCHED)
+   return sid == csid ? 0 : -EACCES;
if (mode & PTRACE_MODE_READ)
return avc_has_perm(_state,
sid, csid, SECCLASS_FILE, FILE__READ, NULL);
-- 
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 v5 0/5] LSM: Support ptrace sidechannel access checks

2018-09-27 Thread Casey Schaufler
v5: Revamped to match Jiri Kosina 
Harden spectrev2 userspace-userspace protection v7
Fixed locking issues in the LSM code.
Dropped the new LSM hook and use a ptrace hook instead.
v4: select namespace checks if user namespaces are enabled
and credential checks are request.
v3: get_task_cred wasn't a good choice due to refcounts.
Use lower level protection instead
v2: SELinux access policy corrected.
Use real_cred instead of cred.

This patchset provide a mechanism by which a security module
can advise the system about potential side-channel vulnerabilities.
The existing security modules have been updated to avoid locking
issues in the face of PTRACE_MODE_SCHED. A new security
module is provided to make determinations regarding task attributes
including namespaces.

Signed-off-by: Casey Schaufler 
---
 include/linux/lsm_hooks.h  |  5 +++
 kernel/ptrace.c|  2 -
 security/Kconfig   |  1 +
 security/Makefile  |  2 +
 security/apparmor/domain.c |  2 +-
 security/apparmor/include/ipc.h|  2 +-
 security/apparmor/ipc.c|  8 ++--
 security/apparmor/lsm.c|  5 ++-
 security/commoncap.c   |  2 +
 security/security.c|  1 +
 security/selinux/hooks.c   |  2 +
 security/sidechannel/Kconfig   | 13 ++
 security/sidechannel/Makefile  |  1 +
 security/sidechannel/sidechannel.c | 88 ++
 security/smack/smack_lsm.c |  3 +-
 15 files changed, 127 insertions(+), 10 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.


Re: [PATCH v4 00/19] LSM: Module stacking for SARA and Landlock

2018-09-25 Thread Casey Schaufler
On 9/24/2018 10:53 AM, Tetsuo Handa wrote:
> 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.

That is true with the code in this patch set. As I mentioned,
changing the blob handling to include a header with real use
information would be required.

> Even if they could, they after all have to somehow check whether
> corresponding init hook was called. That's checking for NULL.

Right.

>>>>> @@ -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.

OK, you're correct. Checking for an initialized kmem_cache isn't appropriate.

___
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

2018-09-24 Thread Casey Schaufler
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);
>>> -
>> 

Re: [PATCH v4 00/19] LSM: Module stacking for SARA and Landlock

2018-09-24 Thread Casey Schaufler
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

2018-09-24 Thread Casey Schaufler
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 v4 00/19] LSM: Module stacking for SARA and Landlock

2018-09-24 Thread Casey Schaufler
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.


[PATCH v4 15/19] LSM: Infrastructure management of the task security

2018-09-24 Thread Casey Schaufler
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);
ls

[PATCH v4 19/19] LSM: Blob sharing support for S.A.R.A and LandLock

2018-09-24 Thread Casey Schaufler
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
+ "se

[PATCH v4 16/19] SELinux: Abstract use of ipc security blobs

2018-09-24 Thread Casey Schaufler
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.


[PATCH v4 09/19] SELinux: Abstract use of file security blob

2018-09-24 Thread Casey Schaufler
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

2018-09-24 Thread Casey Schaufler
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;
 
-

[PATCH v4 11/19] LSM: Infrastructure management of the file security

2018-09-24 Thread Casey Schaufler
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)
+

[PATCH v4 18/19] LSM: Infrastructure management of the ipc security blob

2018-09-24 Thread Casey Schaufler
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)
 

[PATCH v4 14/19] LSM: Infrastructure management of the inode security

2018-09-24 Thread Casey Schaufler
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);
+ 

[PATCH v4 09/19] SELinux: Abstract use of file security blob

2018-09-24 Thread Casey Schaufler
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

2018-09-24 Thread Casey Schaufler
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.


[PATCH v4 12/19] SELinux: Abstract use of inode security blob

2018-09-24 Thread Casey Schaufler
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 @@ stat

[PATCH v4 10/19] Smack: Abstract use of file security blob

2018-09-24 Thread Casey Schaufler
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

2018-09-24 Thread Casey Schaufler
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 specifi

[PATCH v4 06/19] AppArmor: Abstract use of cred security blob

2018-09-24 Thread Casey Schaufler
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

2018-09-24 Thread Casey Schaufler
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(

[PATCH v4 03/19] SELinux: Abstract use of cred security blob

2018-09-24 Thread Casey Schaufler
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_se

[PATCH v4 05/19] SELinux: Remove unused selinux_is_enabled

2018-09-24 Thread Casey Schaufler
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

2018-09-24 Thread Casey Schaufler
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

2018-09-24 Thread Casey Schaufler
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, \
+ 

[PATCH v4 02/19] Smack: Abstract use of cred security blob

2018-09-24 Thread Casey Schaufler
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_s

[PATCH v4 00/19] LSM: Module stacking for SARA and Landlock

2018-09-24 Thread Casey Schaufler
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.


Re: [PATCH v3 09/16] SELinux: Abstract use of file security blob

2018-09-20 Thread Casey Schaufler
On 9/20/2018 1:51 AM, David Laight wrote:
> From: Casey Schaufler
>> Sent: 20 September 2018 01:21
>>
>> 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.
> ...
>> +static inline struct file_security_struct *selinux_file(const struct file 
>> *file)
>> +{
>> +return file->f_security;
>> +}
>> +
> Why?

In patch 16/16 this becomes:

 static inline struct file_security_struct *selinux_file(const struct file 
*file)
 {
+#ifdef CONFIG_SECURITY_STACKING
+   return file->f_security + selinux_blob_sizes.lbs_file;
+#else
return file->f_security;
+#endif
 }

You could hard code this bit everywhere it's used, but that
would be prone to error. I'm not generally an abstractionist
myself, but it these cases abstraction adds value.

___
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] netfilter: nf_tables: add SECMARK support

2018-09-20 Thread Casey Schaufler
On 9/20/2018 12:18 AM, Christian Göttsche wrote:
>> I've only had a cursory look at your patch, but how is it
>> different from what's in xt_SECMARK.c ?
> xt_SEXMARK.c is for xtables, use-able in iptables; this is for nftables (nft)

Thank you. I am enlightened.


___
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 15/16] LSM: Infrastructure management of the ipc security blob

2018-09-20 Thread Casey Schaufler
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  | 116 ++
 security/selinux/include/objsec.h |  13 
 security/smack/smack.h|  11 +++
 security/smack/smack_lsm.c|  46 
 6 files changed, 148 insertions(+), 131 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 securit

[PATCH v3 14/16] LSM: Infrastructure management of the task security blob

2018-09-20 Thread Casey Schaufler
LSM: Infrastructure management of the task security blob

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.

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  | 56 ++--
 4 files changed, 63 insertions(+), 28 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 2501cdcbebff..7e11de7eec21 100644
--- a/security/security.c
+++ b/security/security.c
@@ -116,7 +116,8 @@ 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);
+   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)
  

[PATCH v3 16/16] LSM: Blob sharing support for S.A.R.A and LandLock

2018-09-20 Thread Casey Schaufler
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  | 17 +++---
 security/tomoyo/common.h| 12 +++-
 security/tomoyo/tomoyo.c|  3 +-
 14 files changed, 194 insertions(+), 22 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 modul

[PATCH v3 13/16] LSM: Infrastructure management of the inode security

2018-09-20 Thread Casey Schaufler
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..2501cdcbebff 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 (unli

[PATCH v3 12/16] Smack: Abstract use of inode security blob

2018-09-20 Thread Casey Schaufler
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 
---
 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)
   

[PATCH v3 10/16] LSM: Infrastructure management of the file security blob

2018-09-20 Thread Casey Schaufler
LSM: Infrastructure management of the file security blob

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 |  5 
 security/smack/smack_lsm.c | 26 +++---
 6 files changed, 78 insertions(+), 52 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

[PATCH v3 09/16] SELinux: Abstract use of file security blob

2018-09-20 Thread Casey Schaufler
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 
---
 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 v3 11/16] SELinux: Abstract use of inode security blob

2018-09-20 Thread Casey Schaufler
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 
---
 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 @@ stat

[PATCH v3 08/16] LSM: Infrastructure management of the cred security blob

2018-09-20 Thread Casey Schaufler
LSM: 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  |  17 -
 9 files changed, 213 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 t

[PATCH v3 06/16] AppArmor: Abstract use of cred security blob

2018-09-20 Thread Casey Schaufler
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 v3 03/16] SELinux: Abstract use of cred security blob

2018-09-20 Thread Casey Schaufler
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 
---
 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

[PATCH v3 05/16] SELinux: Remove unused selinux_is_enabled

2018-09-20 Thread Casey Schaufler
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.


  1   2   3   4   >