Re: [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-13 Thread Alan Cox
> | A trusted path is one that is inside is a root owned directory that
> | is not group or world writable.  /bin, /usr/bin, /usr/local/bin, are
> | (under normal circumstances) considered trusted.  Any non-root
> | users home directory is not trusted, nor is /tmp.

You need the entire path to be root owned and root write only from /, and
to assume that the attacker can't get CAP_SYS_DAC. Compare that with
labelling and labelling looks rather better.

It's the same story as ever - paths are not very meaningful for security,
content is. You label content not paths. The existing LSMs can provide
both content label based execution protection and even path based.
SELinux can do it right already, AppArmor appears to be able to do it
compatibly wrong with your proposal already.

> NOTE: root is never restricted by TPE

Why are we talking about "root" not capabilities ? We stopped tying stuff
to "root" 20 years ago.

>*  Can be bypassed by interpreted languages such as python. You can run
>   malicious code by doing: python -c 'evil code'

Or using ld.so since ELF binaries are dynamically loaded and will even
helpfully trying and dynamically load libraries not on your trust path
completely configurably via environment variables.

So all your funky protection goes to poop the moment you hit the most
wannabe n00b attacker who knows how to set LD_PRELOAD.

The unix x bit was never designed as a security feature. It got slightly
tweaked for one for directory path walking but the purpose of the 'x' bit
on a file is solely to stop the user accidentally executing garbage.

> 2. Attacker on system replaces binary used by a privileged user with a
>malicious one
> 
> *  This situation arises when administrator of a system leaves a binary
>as world writable.
> 
> *  TPE is very effective against this threat model

Keeping the executables root is allowed to use in a root owned, only root
reachable space with no setuid bits works even better. Especially as you
can mount it r/o almost all of the time.

Pleae explain how your filesystem mode checks interact with existing file
systems that implement other security semantics eg OpenAFS, or for that
matter DOS ?

[Not an idle question as most distributions keep their EFI system
partition mounted even though it seems a rather silly thing to do]

Alan


Re: [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-13 Thread Alan Cox
> | A trusted path is one that is inside is a root owned directory that
> | is not group or world writable.  /bin, /usr/bin, /usr/local/bin, are
> | (under normal circumstances) considered trusted.  Any non-root
> | users home directory is not trusted, nor is /tmp.

You need the entire path to be root owned and root write only from /, and
to assume that the attacker can't get CAP_SYS_DAC. Compare that with
labelling and labelling looks rather better.

It's the same story as ever - paths are not very meaningful for security,
content is. You label content not paths. The existing LSMs can provide
both content label based execution protection and even path based.
SELinux can do it right already, AppArmor appears to be able to do it
compatibly wrong with your proposal already.

> NOTE: root is never restricted by TPE

Why are we talking about "root" not capabilities ? We stopped tying stuff
to "root" 20 years ago.

>*  Can be bypassed by interpreted languages such as python. You can run
>   malicious code by doing: python -c 'evil code'

Or using ld.so since ELF binaries are dynamically loaded and will even
helpfully trying and dynamically load libraries not on your trust path
completely configurably via environment variables.

So all your funky protection goes to poop the moment you hit the most
wannabe n00b attacker who knows how to set LD_PRELOAD.

The unix x bit was never designed as a security feature. It got slightly
tweaked for one for directory path walking but the purpose of the 'x' bit
on a file is solely to stop the user accidentally executing garbage.

> 2. Attacker on system replaces binary used by a privileged user with a
>malicious one
> 
> *  This situation arises when administrator of a system leaves a binary
>as world writable.
> 
> *  TPE is very effective against this threat model

Keeping the executables root is allowed to use in a root owned, only root
reachable space with no setuid bits works even better. Especially as you
can mount it r/o almost all of the time.

Pleae explain how your filesystem mode checks interact with existing file
systems that implement other security semantics eg OpenAFS, or for that
matter DOS ?

[Not an idle question as most distributions keep their EFI system
partition mounted even though it seems a rather silly thing to do]

Alan


Re: [kernel-hardening] [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-04 Thread Mickaël Salaün
As was pointed out to me, the first grsecurity's implementation of TPE
date back to earlier days (before Git was used for Linux):
https://github.com/linux-scraping/grsecurity-patches/blob/master/grsec-2.4.5/grsecurity-1.4-LIDS-2.4.5.patch

There seem to be multiple implementations inspired by the Phrack
articles. This may be worth to take a look at this different approaches.

 Mickaël

On 04/06/2017 18:43, Mickaël Salaün wrote:
> Hi,
> 
> If you want to get some information about the history of TPE in
> grsecurity, take a look at
> https://github.com/linux-scraping/linux-grsecurity/ and run git log
> grsecurity/grsec_tpe.c
> 
> Here are some links about TPE (before grsecurity used it):
> * http://phrack.org/issues/52/6.html#article
> * http://phrack.org/issues/53/8.html#article
> * https://lwn.net/Articles/32087/
> *
> https://www.usenix.org/legacy/event/usenix04/tech/freenix/full_papers/rahimi/rahimi_html/
> 
> You may want to adjust the credits.
> 
> A more flexible way to configure TPE options (sysctl) may be considered too.
> 
> Regards,
>  Mickaël
> 
> On 03/06/2017 07:53, Matt Brown wrote:
>> This patch was modified from Brad Spengler's Trusted Path Execution (TPE)
>> feature in Grsecurity and also incorporates logging ideas from
>> cormander's tpe-lkm.
>>
>> Modifications from the Grsecurity implementation of TPE were made to
>> turn it into a stackable LSM using the existing LSM hook bprm_set_creds.
>> Also, denial messages were improved by including the full path of the
>> disallowed program. (This idea was taken from cormander's tpe-lkm)
>>
>> Trusted Path Execution is not a new idea:
>>
>> http://phrack.org/issues/52/6.html#article
>>
>> | A trusted path is one that is inside is a root owned directory that
>> | is not group or world writable.  /bin, /usr/bin, /usr/local/bin, are
>> | (under normal circumstances) considered trusted.  Any non-root
>> | users home directory is not trusted, nor is /tmp.
>>
>> This Trusted Path Execution implementation introduces the following
>> Kconfig options and sysctls. These config behaviors are taken straight
>> from Grsecurity's implementation.
>>
>> CONFIG_SECURITY_TPE (sysctl=kernel.tpe.enabled)
>>
>> This option enables Trusted Path Execution. TPE blocks *untrusted*
>> users from executing files that meet the following conditions:
>>
>> * file is not in a root-owned directory
>> * file is writable by a user other than root
>>
>> NOTE: root is never restricted by TPE
>>
>> CONFIG_SECURITY_TPE_GID (sysctl=kernel.tpe.gid)
>>
>> This option defines a group id that, by default, is the untrusted group.
>> If a user is untrusted then it has the checks described in
>> CONFIG_SECURITY_TPE applied. Otherwise, the user is trusted and the
>> checks are not applied. Since root is never restricted by TPE, you can
>> effectively remove the concept of a trusted or untrusted group by
>> setting this value to 0.
>>
>> CONFIG_SECURITY_TPE_ALL (sysctl=kernel.tpe.restrict_all)
>>
>> This option applies another set of restrictions to all non-root users
>> even if they are trusted. This only allows execution under the
>> following conditions:
>>
>> * file is in a directory owned by the user that is not group or
>>   world-writable
>> * file is in a directory owned by root and writable only by root
>>
>> CONFIG_SECURITY_TPE_INVERT (sysctl=kernel.tpe.gid_invert)
>>
>> This option reverses the trust logic of the gid option and makes
>> kernel.tpe.gid into the trusted group. This means that all other groups
>> become untrusted. This sysctl is helpful when you want TPE restrictions
>> to apply to most of the users on the system.
>>
>> Threat Models:
>>
>> 1. Attacker on system executing exploit on system vulnerability
>>
>> *  If attacker uses a binary as a part of their system exploit, TPE can
>>frustrate their efforts
>>
>> *  Issues:
>>*  Can be bypassed by interpreted languages such as python. You can run
>>   malicious code by doing: python -c 'evil code'
>>
>> 2. Attacker on system replaces binary used by a privileged user with a
>>malicious one
>>
>> *  This situation arises when administrator of a system leaves a binary
>>as world writable.
>>
>> *  TPE is very effective against this threat model
>>
>> Signed-off-by: Matt Brown 
>> ---
>>  MAINTAINERS   |   5 ++
>>  include/linux/lsm_hooks.h |   5 ++
>>  security/Kconfig  |   1 +
>>  security/Makefile |   2 +
>>  security/security.c   |   1 +
>>  security/tpe/Kconfig  |  57 +++
>>  security/tpe/Makefile |   3 +
>>  security/tpe/tpe_lsm.c| 175 
>> ++
>>  8 files changed, 249 insertions(+)
>>  create mode 100644 security/tpe/Kconfig
>>  create mode 100644 security/tpe/Makefile
>>  create mode 100644 security/tpe/tpe_lsm.c
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 38d3e4e..1952bd6 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -11357,6 +11357,11 @@ T:  git 
>> 

Re: [kernel-hardening] [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-04 Thread Mickaël Salaün
As was pointed out to me, the first grsecurity's implementation of TPE
date back to earlier days (before Git was used for Linux):
https://github.com/linux-scraping/grsecurity-patches/blob/master/grsec-2.4.5/grsecurity-1.4-LIDS-2.4.5.patch

There seem to be multiple implementations inspired by the Phrack
articles. This may be worth to take a look at this different approaches.

 Mickaël

On 04/06/2017 18:43, Mickaël Salaün wrote:
> Hi,
> 
> If you want to get some information about the history of TPE in
> grsecurity, take a look at
> https://github.com/linux-scraping/linux-grsecurity/ and run git log
> grsecurity/grsec_tpe.c
> 
> Here are some links about TPE (before grsecurity used it):
> * http://phrack.org/issues/52/6.html#article
> * http://phrack.org/issues/53/8.html#article
> * https://lwn.net/Articles/32087/
> *
> https://www.usenix.org/legacy/event/usenix04/tech/freenix/full_papers/rahimi/rahimi_html/
> 
> You may want to adjust the credits.
> 
> A more flexible way to configure TPE options (sysctl) may be considered too.
> 
> Regards,
>  Mickaël
> 
> On 03/06/2017 07:53, Matt Brown wrote:
>> This patch was modified from Brad Spengler's Trusted Path Execution (TPE)
>> feature in Grsecurity and also incorporates logging ideas from
>> cormander's tpe-lkm.
>>
>> Modifications from the Grsecurity implementation of TPE were made to
>> turn it into a stackable LSM using the existing LSM hook bprm_set_creds.
>> Also, denial messages were improved by including the full path of the
>> disallowed program. (This idea was taken from cormander's tpe-lkm)
>>
>> Trusted Path Execution is not a new idea:
>>
>> http://phrack.org/issues/52/6.html#article
>>
>> | A trusted path is one that is inside is a root owned directory that
>> | is not group or world writable.  /bin, /usr/bin, /usr/local/bin, are
>> | (under normal circumstances) considered trusted.  Any non-root
>> | users home directory is not trusted, nor is /tmp.
>>
>> This Trusted Path Execution implementation introduces the following
>> Kconfig options and sysctls. These config behaviors are taken straight
>> from Grsecurity's implementation.
>>
>> CONFIG_SECURITY_TPE (sysctl=kernel.tpe.enabled)
>>
>> This option enables Trusted Path Execution. TPE blocks *untrusted*
>> users from executing files that meet the following conditions:
>>
>> * file is not in a root-owned directory
>> * file is writable by a user other than root
>>
>> NOTE: root is never restricted by TPE
>>
>> CONFIG_SECURITY_TPE_GID (sysctl=kernel.tpe.gid)
>>
>> This option defines a group id that, by default, is the untrusted group.
>> If a user is untrusted then it has the checks described in
>> CONFIG_SECURITY_TPE applied. Otherwise, the user is trusted and the
>> checks are not applied. Since root is never restricted by TPE, you can
>> effectively remove the concept of a trusted or untrusted group by
>> setting this value to 0.
>>
>> CONFIG_SECURITY_TPE_ALL (sysctl=kernel.tpe.restrict_all)
>>
>> This option applies another set of restrictions to all non-root users
>> even if they are trusted. This only allows execution under the
>> following conditions:
>>
>> * file is in a directory owned by the user that is not group or
>>   world-writable
>> * file is in a directory owned by root and writable only by root
>>
>> CONFIG_SECURITY_TPE_INVERT (sysctl=kernel.tpe.gid_invert)
>>
>> This option reverses the trust logic of the gid option and makes
>> kernel.tpe.gid into the trusted group. This means that all other groups
>> become untrusted. This sysctl is helpful when you want TPE restrictions
>> to apply to most of the users on the system.
>>
>> Threat Models:
>>
>> 1. Attacker on system executing exploit on system vulnerability
>>
>> *  If attacker uses a binary as a part of their system exploit, TPE can
>>frustrate their efforts
>>
>> *  Issues:
>>*  Can be bypassed by interpreted languages such as python. You can run
>>   malicious code by doing: python -c 'evil code'
>>
>> 2. Attacker on system replaces binary used by a privileged user with a
>>malicious one
>>
>> *  This situation arises when administrator of a system leaves a binary
>>as world writable.
>>
>> *  TPE is very effective against this threat model
>>
>> Signed-off-by: Matt Brown 
>> ---
>>  MAINTAINERS   |   5 ++
>>  include/linux/lsm_hooks.h |   5 ++
>>  security/Kconfig  |   1 +
>>  security/Makefile |   2 +
>>  security/security.c   |   1 +
>>  security/tpe/Kconfig  |  57 +++
>>  security/tpe/Makefile |   3 +
>>  security/tpe/tpe_lsm.c| 175 
>> ++
>>  8 files changed, 249 insertions(+)
>>  create mode 100644 security/tpe/Kconfig
>>  create mode 100644 security/tpe/Makefile
>>  create mode 100644 security/tpe/tpe_lsm.c
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 38d3e4e..1952bd6 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -11357,6 +11357,11 @@ T:  git 
>> 

Re: [kernel-hardening] [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-04 Thread Mickaël Salaün
Hi,

If you want to get some information about the history of TPE in
grsecurity, take a look at
https://github.com/linux-scraping/linux-grsecurity/ and run git log
grsecurity/grsec_tpe.c

Here are some links about TPE (before grsecurity used it):
* http://phrack.org/issues/52/6.html#article
* http://phrack.org/issues/53/8.html#article
* https://lwn.net/Articles/32087/
*
https://www.usenix.org/legacy/event/usenix04/tech/freenix/full_papers/rahimi/rahimi_html/

You may want to adjust the credits.

A more flexible way to configure TPE options (sysctl) may be considered too.

Regards,
 Mickaël

On 03/06/2017 07:53, Matt Brown wrote:
> This patch was modified from Brad Spengler's Trusted Path Execution (TPE)
> feature in Grsecurity and also incorporates logging ideas from
> cormander's tpe-lkm.
> 
> Modifications from the Grsecurity implementation of TPE were made to
> turn it into a stackable LSM using the existing LSM hook bprm_set_creds.
> Also, denial messages were improved by including the full path of the
> disallowed program. (This idea was taken from cormander's tpe-lkm)
> 
> Trusted Path Execution is not a new idea:
> 
> http://phrack.org/issues/52/6.html#article
> 
> | A trusted path is one that is inside is a root owned directory that
> | is not group or world writable.  /bin, /usr/bin, /usr/local/bin, are
> | (under normal circumstances) considered trusted.  Any non-root
> | users home directory is not trusted, nor is /tmp.
> 
> This Trusted Path Execution implementation introduces the following
> Kconfig options and sysctls. These config behaviors are taken straight
> from Grsecurity's implementation.
> 
> CONFIG_SECURITY_TPE (sysctl=kernel.tpe.enabled)
> 
> This option enables Trusted Path Execution. TPE blocks *untrusted*
> users from executing files that meet the following conditions:
> 
> * file is not in a root-owned directory
> * file is writable by a user other than root
> 
> NOTE: root is never restricted by TPE
> 
> CONFIG_SECURITY_TPE_GID (sysctl=kernel.tpe.gid)
> 
> This option defines a group id that, by default, is the untrusted group.
> If a user is untrusted then it has the checks described in
> CONFIG_SECURITY_TPE applied. Otherwise, the user is trusted and the
> checks are not applied. Since root is never restricted by TPE, you can
> effectively remove the concept of a trusted or untrusted group by
> setting this value to 0.
> 
> CONFIG_SECURITY_TPE_ALL (sysctl=kernel.tpe.restrict_all)
> 
> This option applies another set of restrictions to all non-root users
> even if they are trusted. This only allows execution under the
> following conditions:
> 
> * file is in a directory owned by the user that is not group or
>   world-writable
> * file is in a directory owned by root and writable only by root
> 
> CONFIG_SECURITY_TPE_INVERT (sysctl=kernel.tpe.gid_invert)
> 
> This option reverses the trust logic of the gid option and makes
> kernel.tpe.gid into the trusted group. This means that all other groups
> become untrusted. This sysctl is helpful when you want TPE restrictions
> to apply to most of the users on the system.
> 
> Threat Models:
> 
> 1. Attacker on system executing exploit on system vulnerability
> 
> *  If attacker uses a binary as a part of their system exploit, TPE can
>frustrate their efforts
> 
> *  Issues:
>*  Can be bypassed by interpreted languages such as python. You can run
>   malicious code by doing: python -c 'evil code'
> 
> 2. Attacker on system replaces binary used by a privileged user with a
>malicious one
> 
> *  This situation arises when administrator of a system leaves a binary
>as world writable.
> 
> *  TPE is very effective against this threat model
> 
> Signed-off-by: Matt Brown 
> ---
>  MAINTAINERS   |   5 ++
>  include/linux/lsm_hooks.h |   5 ++
>  security/Kconfig  |   1 +
>  security/Makefile |   2 +
>  security/security.c   |   1 +
>  security/tpe/Kconfig  |  57 +++
>  security/tpe/Makefile |   3 +
>  security/tpe/tpe_lsm.c| 175 
> ++
>  8 files changed, 249 insertions(+)
>  create mode 100644 security/tpe/Kconfig
>  create mode 100644 security/tpe/Makefile
>  create mode 100644 security/tpe/tpe_lsm.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 38d3e4e..1952bd6 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11357,6 +11357,11 @@ T:   git 
> git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git yama/tip
>  S:   Supported
>  F:   security/yama/
>  
> +TPE SECURITY MODULE
> +M:   Matt Brown 
> +S:   Supported
> +F:   security/tpe/
> +
>  SENSABLE PHANTOM
>  M:   Jiri Slaby 
>  S:   Maintained
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index e29d4c6..d017f49 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -1920,5 +1920,10 @@ void __init loadpin_add_hooks(void);
>  #else
>  static inline void 

Re: [kernel-hardening] [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-04 Thread Mickaël Salaün
Hi,

If you want to get some information about the history of TPE in
grsecurity, take a look at
https://github.com/linux-scraping/linux-grsecurity/ and run git log
grsecurity/grsec_tpe.c

Here are some links about TPE (before grsecurity used it):
* http://phrack.org/issues/52/6.html#article
* http://phrack.org/issues/53/8.html#article
* https://lwn.net/Articles/32087/
*
https://www.usenix.org/legacy/event/usenix04/tech/freenix/full_papers/rahimi/rahimi_html/

You may want to adjust the credits.

A more flexible way to configure TPE options (sysctl) may be considered too.

Regards,
 Mickaël

On 03/06/2017 07:53, Matt Brown wrote:
> This patch was modified from Brad Spengler's Trusted Path Execution (TPE)
> feature in Grsecurity and also incorporates logging ideas from
> cormander's tpe-lkm.
> 
> Modifications from the Grsecurity implementation of TPE were made to
> turn it into a stackable LSM using the existing LSM hook bprm_set_creds.
> Also, denial messages were improved by including the full path of the
> disallowed program. (This idea was taken from cormander's tpe-lkm)
> 
> Trusted Path Execution is not a new idea:
> 
> http://phrack.org/issues/52/6.html#article
> 
> | A trusted path is one that is inside is a root owned directory that
> | is not group or world writable.  /bin, /usr/bin, /usr/local/bin, are
> | (under normal circumstances) considered trusted.  Any non-root
> | users home directory is not trusted, nor is /tmp.
> 
> This Trusted Path Execution implementation introduces the following
> Kconfig options and sysctls. These config behaviors are taken straight
> from Grsecurity's implementation.
> 
> CONFIG_SECURITY_TPE (sysctl=kernel.tpe.enabled)
> 
> This option enables Trusted Path Execution. TPE blocks *untrusted*
> users from executing files that meet the following conditions:
> 
> * file is not in a root-owned directory
> * file is writable by a user other than root
> 
> NOTE: root is never restricted by TPE
> 
> CONFIG_SECURITY_TPE_GID (sysctl=kernel.tpe.gid)
> 
> This option defines a group id that, by default, is the untrusted group.
> If a user is untrusted then it has the checks described in
> CONFIG_SECURITY_TPE applied. Otherwise, the user is trusted and the
> checks are not applied. Since root is never restricted by TPE, you can
> effectively remove the concept of a trusted or untrusted group by
> setting this value to 0.
> 
> CONFIG_SECURITY_TPE_ALL (sysctl=kernel.tpe.restrict_all)
> 
> This option applies another set of restrictions to all non-root users
> even if they are trusted. This only allows execution under the
> following conditions:
> 
> * file is in a directory owned by the user that is not group or
>   world-writable
> * file is in a directory owned by root and writable only by root
> 
> CONFIG_SECURITY_TPE_INVERT (sysctl=kernel.tpe.gid_invert)
> 
> This option reverses the trust logic of the gid option and makes
> kernel.tpe.gid into the trusted group. This means that all other groups
> become untrusted. This sysctl is helpful when you want TPE restrictions
> to apply to most of the users on the system.
> 
> Threat Models:
> 
> 1. Attacker on system executing exploit on system vulnerability
> 
> *  If attacker uses a binary as a part of their system exploit, TPE can
>frustrate their efforts
> 
> *  Issues:
>*  Can be bypassed by interpreted languages such as python. You can run
>   malicious code by doing: python -c 'evil code'
> 
> 2. Attacker on system replaces binary used by a privileged user with a
>malicious one
> 
> *  This situation arises when administrator of a system leaves a binary
>as world writable.
> 
> *  TPE is very effective against this threat model
> 
> Signed-off-by: Matt Brown 
> ---
>  MAINTAINERS   |   5 ++
>  include/linux/lsm_hooks.h |   5 ++
>  security/Kconfig  |   1 +
>  security/Makefile |   2 +
>  security/security.c   |   1 +
>  security/tpe/Kconfig  |  57 +++
>  security/tpe/Makefile |   3 +
>  security/tpe/tpe_lsm.c| 175 
> ++
>  8 files changed, 249 insertions(+)
>  create mode 100644 security/tpe/Kconfig
>  create mode 100644 security/tpe/Makefile
>  create mode 100644 security/tpe/tpe_lsm.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 38d3e4e..1952bd6 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -11357,6 +11357,11 @@ T:   git 
> git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git yama/tip
>  S:   Supported
>  F:   security/yama/
>  
> +TPE SECURITY MODULE
> +M:   Matt Brown 
> +S:   Supported
> +F:   security/tpe/
> +
>  SENSABLE PHANTOM
>  M:   Jiri Slaby 
>  S:   Maintained
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index e29d4c6..d017f49 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -1920,5 +1920,10 @@ void __init loadpin_add_hooks(void);
>  #else
>  static inline void loadpin_add_hooks(void) { };
>  #endif
> +#ifdef 

Re: [kernel-hardening] Re: [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-04 Thread Matt Brown

On 06/04/2017 01:47 AM, Eric Biggers wrote:

On Sun, Jun 04, 2017 at 01:24:13AM -0400, Matt Brown wrote:

On 06/03/2017 02:33 AM, Al Viro wrote:

On Sat, Jun 03, 2017 at 01:53:51AM -0400, Matt Brown wrote:


+static int tpe_bprm_set_creds(struct linux_binprm *bprm)
+{
+   struct file *file = bprm->file;
+   struct inode *inode = d_backing_inode(file->f_path.dentry->d_parent);
+   struct inode *file_inode = d_backing_inode(file->f_path.dentry);


Bloody wonderful.  Do tell, what *does* prevent a race with rename(2) here,
somehow making sure that your 'inode' won't get freed right under you?



Good catch. How does this look:

spin_lock(>i_lock);
spin_lock(_inode->i_lock);
if (global_nonroot(inode->i_uid) && !uid_eq(inode->i_uid, cred->uid))
reason1 = "directory not owned by user";
else if (inode->i_mode & 0002)
reason1 = "file in world-writable directory";
else if ((inode->i_mode & 0020) && global_nonroot_gid(inode->i_gid))
reason1 = "file in group-writable directory";
else if (file_inode->i_mode & 0002)
reason1 = "file is world-writable";
spin_unlock(>i_lock);
spin_unlock(_inode->i_lock);

and likewise for other places in the code?


No, it needs to take a reference on the parent dentry before using it, using
dget_parent(), I think, and then dropping it later with dput().  Taking i_lock
isn't needed.

Eric



Got it. Thank you!

Matt Brown


Re: [kernel-hardening] Re: [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-04 Thread Matt Brown

On 06/04/2017 01:47 AM, Eric Biggers wrote:

On Sun, Jun 04, 2017 at 01:24:13AM -0400, Matt Brown wrote:

On 06/03/2017 02:33 AM, Al Viro wrote:

On Sat, Jun 03, 2017 at 01:53:51AM -0400, Matt Brown wrote:


+static int tpe_bprm_set_creds(struct linux_binprm *bprm)
+{
+   struct file *file = bprm->file;
+   struct inode *inode = d_backing_inode(file->f_path.dentry->d_parent);
+   struct inode *file_inode = d_backing_inode(file->f_path.dentry);


Bloody wonderful.  Do tell, what *does* prevent a race with rename(2) here,
somehow making sure that your 'inode' won't get freed right under you?



Good catch. How does this look:

spin_lock(>i_lock);
spin_lock(_inode->i_lock);
if (global_nonroot(inode->i_uid) && !uid_eq(inode->i_uid, cred->uid))
reason1 = "directory not owned by user";
else if (inode->i_mode & 0002)
reason1 = "file in world-writable directory";
else if ((inode->i_mode & 0020) && global_nonroot_gid(inode->i_gid))
reason1 = "file in group-writable directory";
else if (file_inode->i_mode & 0002)
reason1 = "file is world-writable";
spin_unlock(>i_lock);
spin_unlock(_inode->i_lock);

and likewise for other places in the code?


No, it needs to take a reference on the parent dentry before using it, using
dget_parent(), I think, and then dropping it later with dput().  Taking i_lock
isn't needed.

Eric



Got it. Thank you!

Matt Brown


Re: [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-04 Thread Al Viro
On Sun, Jun 04, 2017 at 01:24:13AM -0400, Matt Brown wrote:
> On 06/03/2017 02:33 AM, Al Viro wrote:
> > On Sat, Jun 03, 2017 at 01:53:51AM -0400, Matt Brown wrote:
> > 
> > > +static int tpe_bprm_set_creds(struct linux_binprm *bprm)
> > > +{
> > > + struct file *file = bprm->file;
> > > + struct inode *inode = d_backing_inode(file->f_path.dentry->d_parent);
> > > + struct inode *file_inode = d_backing_inode(file->f_path.dentry);
> > 
> > Bloody wonderful.  Do tell, what *does* prevent a race with rename(2) here,
> > somehow making sure that your 'inode' won't get freed right under you?
> > 
> 
> Good catch. How does this look:
> 
> spin_lock(>i_lock);
> spin_lock(_inode->i_lock);
> if (global_nonroot(inode->i_uid) && !uid_eq(inode->i_uid, cred->uid))
>   reason1 = "directory not owned by user";
> else if (inode->i_mode & 0002)
>   reason1 = "file in world-writable directory";
> else if ((inode->i_mode & 0020) && global_nonroot_gid(inode->i_gid))
>   reason1 = "file in group-writable directory";
> else if (file_inode->i_mode & 0002)
>   reason1 = "file is world-writable";
> spin_unlock(>i_lock);
> spin_unlock(_inode->i_lock);
> 
> and likewise for other places in the code?

Er...  You have a pointer to object that might get freed by a thread
running on another CPU.  So you attempt to take a spinlock sitting
inside that object.  How exactly is that supposed to help anything?


Re: [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-04 Thread Al Viro
On Sun, Jun 04, 2017 at 01:24:13AM -0400, Matt Brown wrote:
> On 06/03/2017 02:33 AM, Al Viro wrote:
> > On Sat, Jun 03, 2017 at 01:53:51AM -0400, Matt Brown wrote:
> > 
> > > +static int tpe_bprm_set_creds(struct linux_binprm *bprm)
> > > +{
> > > + struct file *file = bprm->file;
> > > + struct inode *inode = d_backing_inode(file->f_path.dentry->d_parent);
> > > + struct inode *file_inode = d_backing_inode(file->f_path.dentry);
> > 
> > Bloody wonderful.  Do tell, what *does* prevent a race with rename(2) here,
> > somehow making sure that your 'inode' won't get freed right under you?
> > 
> 
> Good catch. How does this look:
> 
> spin_lock(>i_lock);
> spin_lock(_inode->i_lock);
> if (global_nonroot(inode->i_uid) && !uid_eq(inode->i_uid, cred->uid))
>   reason1 = "directory not owned by user";
> else if (inode->i_mode & 0002)
>   reason1 = "file in world-writable directory";
> else if ((inode->i_mode & 0020) && global_nonroot_gid(inode->i_gid))
>   reason1 = "file in group-writable directory";
> else if (file_inode->i_mode & 0002)
>   reason1 = "file is world-writable";
> spin_unlock(>i_lock);
> spin_unlock(_inode->i_lock);
> 
> and likewise for other places in the code?

Er...  You have a pointer to object that might get freed by a thread
running on another CPU.  So you attempt to take a spinlock sitting
inside that object.  How exactly is that supposed to help anything?


Re: [kernel-hardening] Re: [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-03 Thread Eric Biggers
On Sun, Jun 04, 2017 at 01:24:13AM -0400, Matt Brown wrote:
> On 06/03/2017 02:33 AM, Al Viro wrote:
> > On Sat, Jun 03, 2017 at 01:53:51AM -0400, Matt Brown wrote:
> > 
> > > +static int tpe_bprm_set_creds(struct linux_binprm *bprm)
> > > +{
> > > + struct file *file = bprm->file;
> > > + struct inode *inode = d_backing_inode(file->f_path.dentry->d_parent);
> > > + struct inode *file_inode = d_backing_inode(file->f_path.dentry);
> > 
> > Bloody wonderful.  Do tell, what *does* prevent a race with rename(2) here,
> > somehow making sure that your 'inode' won't get freed right under you?
> > 
> 
> Good catch. How does this look:
> 
> spin_lock(>i_lock);
> spin_lock(_inode->i_lock);
> if (global_nonroot(inode->i_uid) && !uid_eq(inode->i_uid, cred->uid))
>   reason1 = "directory not owned by user";
> else if (inode->i_mode & 0002)
>   reason1 = "file in world-writable directory";
> else if ((inode->i_mode & 0020) && global_nonroot_gid(inode->i_gid))
>   reason1 = "file in group-writable directory";
> else if (file_inode->i_mode & 0002)
>   reason1 = "file is world-writable";
> spin_unlock(>i_lock);
> spin_unlock(_inode->i_lock);
> 
> and likewise for other places in the code?

No, it needs to take a reference on the parent dentry before using it, using
dget_parent(), I think, and then dropping it later with dput().  Taking i_lock
isn't needed.

Eric


Re: [kernel-hardening] Re: [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-03 Thread Eric Biggers
On Sun, Jun 04, 2017 at 01:24:13AM -0400, Matt Brown wrote:
> On 06/03/2017 02:33 AM, Al Viro wrote:
> > On Sat, Jun 03, 2017 at 01:53:51AM -0400, Matt Brown wrote:
> > 
> > > +static int tpe_bprm_set_creds(struct linux_binprm *bprm)
> > > +{
> > > + struct file *file = bprm->file;
> > > + struct inode *inode = d_backing_inode(file->f_path.dentry->d_parent);
> > > + struct inode *file_inode = d_backing_inode(file->f_path.dentry);
> > 
> > Bloody wonderful.  Do tell, what *does* prevent a race with rename(2) here,
> > somehow making sure that your 'inode' won't get freed right under you?
> > 
> 
> Good catch. How does this look:
> 
> spin_lock(>i_lock);
> spin_lock(_inode->i_lock);
> if (global_nonroot(inode->i_uid) && !uid_eq(inode->i_uid, cred->uid))
>   reason1 = "directory not owned by user";
> else if (inode->i_mode & 0002)
>   reason1 = "file in world-writable directory";
> else if ((inode->i_mode & 0020) && global_nonroot_gid(inode->i_gid))
>   reason1 = "file in group-writable directory";
> else if (file_inode->i_mode & 0002)
>   reason1 = "file is world-writable";
> spin_unlock(>i_lock);
> spin_unlock(_inode->i_lock);
> 
> and likewise for other places in the code?

No, it needs to take a reference on the parent dentry before using it, using
dget_parent(), I think, and then dropping it later with dput().  Taking i_lock
isn't needed.

Eric


Re: [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-03 Thread Matt Brown

On 06/03/2017 02:33 AM, Al Viro wrote:

On Sat, Jun 03, 2017 at 01:53:51AM -0400, Matt Brown wrote:


+static int tpe_bprm_set_creds(struct linux_binprm *bprm)
+{
+   struct file *file = bprm->file;
+   struct inode *inode = d_backing_inode(file->f_path.dentry->d_parent);
+   struct inode *file_inode = d_backing_inode(file->f_path.dentry);


Bloody wonderful.  Do tell, what *does* prevent a race with rename(2) here,
somehow making sure that your 'inode' won't get freed right under you?



Good catch. How does this look:

spin_lock(>i_lock);
spin_lock(_inode->i_lock);
if (global_nonroot(inode->i_uid) && !uid_eq(inode->i_uid, cred->uid))
reason1 = "directory not owned by user";
else if (inode->i_mode & 0002)
reason1 = "file in world-writable directory";
else if ((inode->i_mode & 0020) && global_nonroot_gid(inode->i_gid))
reason1 = "file in group-writable directory";
else if (file_inode->i_mode & 0002)
reason1 = "file is world-writable";
spin_unlock(>i_lock);
spin_unlock(_inode->i_lock);

and likewise for other places in the code?


Re: [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-03 Thread Matt Brown

On 06/03/2017 02:33 AM, Al Viro wrote:

On Sat, Jun 03, 2017 at 01:53:51AM -0400, Matt Brown wrote:


+static int tpe_bprm_set_creds(struct linux_binprm *bprm)
+{
+   struct file *file = bprm->file;
+   struct inode *inode = d_backing_inode(file->f_path.dentry->d_parent);
+   struct inode *file_inode = d_backing_inode(file->f_path.dentry);


Bloody wonderful.  Do tell, what *does* prevent a race with rename(2) here,
somehow making sure that your 'inode' won't get freed right under you?



Good catch. How does this look:

spin_lock(>i_lock);
spin_lock(_inode->i_lock);
if (global_nonroot(inode->i_uid) && !uid_eq(inode->i_uid, cred->uid))
reason1 = "directory not owned by user";
else if (inode->i_mode & 0002)
reason1 = "file in world-writable directory";
else if ((inode->i_mode & 0020) && global_nonroot_gid(inode->i_gid))
reason1 = "file in group-writable directory";
else if (file_inode->i_mode & 0002)
reason1 = "file is world-writable";
spin_unlock(>i_lock);
spin_unlock(_inode->i_lock);

and likewise for other places in the code?


Re: [kernel-hardening] [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-03 Thread Matt Brown

On 06/03/2017 06:39 AM, Jann Horn wrote:

On Sat, Jun 3, 2017 at 7:53 AM, Matt Brown  wrote:

This patch was modified from Brad Spengler's Trusted Path Execution (TPE)
feature in Grsecurity and also incorporates logging ideas from
cormander's tpe-lkm.

Modifications from the Grsecurity implementation of TPE were made to
turn it into a stackable LSM using the existing LSM hook bprm_set_creds.
Also, denial messages were improved by including the full path of the
disallowed program. (This idea was taken from cormander's tpe-lkm)

[...]

Threat Models:

[...]

2. Attacker on system replaces binary used by a privileged user with a
   malicious one

*  This situation arises when administrator of a system leaves a binary
   as world writable.

*  TPE is very effective against this threat model


How do you end up with world-writable binaries in $PATH?



Sys Admin screw up. It also protects against world-writable binaries
anywhere on the system, not just in $PATH.


Re: [kernel-hardening] [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-03 Thread Matt Brown

On 06/03/2017 06:39 AM, Jann Horn wrote:

On Sat, Jun 3, 2017 at 7:53 AM, Matt Brown  wrote:

This patch was modified from Brad Spengler's Trusted Path Execution (TPE)
feature in Grsecurity and also incorporates logging ideas from
cormander's tpe-lkm.

Modifications from the Grsecurity implementation of TPE were made to
turn it into a stackable LSM using the existing LSM hook bprm_set_creds.
Also, denial messages were improved by including the full path of the
disallowed program. (This idea was taken from cormander's tpe-lkm)

[...]

Threat Models:

[...]

2. Attacker on system replaces binary used by a privileged user with a
   malicious one

*  This situation arises when administrator of a system leaves a binary
   as world writable.

*  TPE is very effective against this threat model


How do you end up with world-writable binaries in $PATH?



Sys Admin screw up. It also protects against world-writable binaries
anywhere on the system, not just in $PATH.


Re: [kernel-hardening] [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-03 Thread Jann Horn
On Sat, Jun 3, 2017 at 7:53 AM, Matt Brown  wrote:
> This patch was modified from Brad Spengler's Trusted Path Execution (TPE)
> feature in Grsecurity and also incorporates logging ideas from
> cormander's tpe-lkm.
>
> Modifications from the Grsecurity implementation of TPE were made to
> turn it into a stackable LSM using the existing LSM hook bprm_set_creds.
> Also, denial messages were improved by including the full path of the
> disallowed program. (This idea was taken from cormander's tpe-lkm)
[...]
> Threat Models:
[...]
> 2. Attacker on system replaces binary used by a privileged user with a
>malicious one
>
> *  This situation arises when administrator of a system leaves a binary
>as world writable.
>
> *  TPE is very effective against this threat model

How do you end up with world-writable binaries in $PATH?


Re: [kernel-hardening] [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-03 Thread Jann Horn
On Sat, Jun 3, 2017 at 7:53 AM, Matt Brown  wrote:
> This patch was modified from Brad Spengler's Trusted Path Execution (TPE)
> feature in Grsecurity and also incorporates logging ideas from
> cormander's tpe-lkm.
>
> Modifications from the Grsecurity implementation of TPE were made to
> turn it into a stackable LSM using the existing LSM hook bprm_set_creds.
> Also, denial messages were improved by including the full path of the
> disallowed program. (This idea was taken from cormander's tpe-lkm)
[...]
> Threat Models:
[...]
> 2. Attacker on system replaces binary used by a privileged user with a
>malicious one
>
> *  This situation arises when administrator of a system leaves a binary
>as world writable.
>
> *  TPE is very effective against this threat model

How do you end up with world-writable binaries in $PATH?


Re: [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-03 Thread Al Viro
On Sat, Jun 03, 2017 at 01:53:51AM -0400, Matt Brown wrote:

> +static int tpe_bprm_set_creds(struct linux_binprm *bprm)
> +{
> + struct file *file = bprm->file;
> + struct inode *inode = d_backing_inode(file->f_path.dentry->d_parent);
> + struct inode *file_inode = d_backing_inode(file->f_path.dentry);

Bloody wonderful.  Do tell, what *does* prevent a race with rename(2) here,
somehow making sure that your 'inode' won't get freed right under you?


Re: [PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-03 Thread Al Viro
On Sat, Jun 03, 2017 at 01:53:51AM -0400, Matt Brown wrote:

> +static int tpe_bprm_set_creds(struct linux_binprm *bprm)
> +{
> + struct file *file = bprm->file;
> + struct inode *inode = d_backing_inode(file->f_path.dentry->d_parent);
> + struct inode *file_inode = d_backing_inode(file->f_path.dentry);

Bloody wonderful.  Do tell, what *does* prevent a race with rename(2) here,
somehow making sure that your 'inode' won't get freed right under you?


[PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-02 Thread Matt Brown
This patch was modified from Brad Spengler's Trusted Path Execution (TPE)
feature in Grsecurity and also incorporates logging ideas from
cormander's tpe-lkm.

Modifications from the Grsecurity implementation of TPE were made to
turn it into a stackable LSM using the existing LSM hook bprm_set_creds.
Also, denial messages were improved by including the full path of the
disallowed program. (This idea was taken from cormander's tpe-lkm)

Trusted Path Execution is not a new idea:

http://phrack.org/issues/52/6.html#article

| A trusted path is one that is inside is a root owned directory that
| is not group or world writable.  /bin, /usr/bin, /usr/local/bin, are
| (under normal circumstances) considered trusted.  Any non-root
| users home directory is not trusted, nor is /tmp.

This Trusted Path Execution implementation introduces the following
Kconfig options and sysctls. These config behaviors are taken straight
from Grsecurity's implementation.

CONFIG_SECURITY_TPE (sysctl=kernel.tpe.enabled)

This option enables Trusted Path Execution. TPE blocks *untrusted*
users from executing files that meet the following conditions:

* file is not in a root-owned directory
* file is writable by a user other than root

NOTE: root is never restricted by TPE

CONFIG_SECURITY_TPE_GID (sysctl=kernel.tpe.gid)

This option defines a group id that, by default, is the untrusted group.
If a user is untrusted then it has the checks described in
CONFIG_SECURITY_TPE applied. Otherwise, the user is trusted and the
checks are not applied. Since root is never restricted by TPE, you can
effectively remove the concept of a trusted or untrusted group by
setting this value to 0.

CONFIG_SECURITY_TPE_ALL (sysctl=kernel.tpe.restrict_all)

This option applies another set of restrictions to all non-root users
even if they are trusted. This only allows execution under the
following conditions:

* file is in a directory owned by the user that is not group or
  world-writable
* file is in a directory owned by root and writable only by root

CONFIG_SECURITY_TPE_INVERT (sysctl=kernel.tpe.gid_invert)

This option reverses the trust logic of the gid option and makes
kernel.tpe.gid into the trusted group. This means that all other groups
become untrusted. This sysctl is helpful when you want TPE restrictions
to apply to most of the users on the system.

Threat Models:

1. Attacker on system executing exploit on system vulnerability

*  If attacker uses a binary as a part of their system exploit, TPE can
   frustrate their efforts

*  Issues:
   *  Can be bypassed by interpreted languages such as python. You can run
  malicious code by doing: python -c 'evil code'

2. Attacker on system replaces binary used by a privileged user with a
   malicious one

*  This situation arises when administrator of a system leaves a binary
   as world writable.

*  TPE is very effective against this threat model

Signed-off-by: Matt Brown 
---
 MAINTAINERS   |   5 ++
 include/linux/lsm_hooks.h |   5 ++
 security/Kconfig  |   1 +
 security/Makefile |   2 +
 security/security.c   |   1 +
 security/tpe/Kconfig  |  57 +++
 security/tpe/Makefile |   3 +
 security/tpe/tpe_lsm.c| 175 ++
 8 files changed, 249 insertions(+)
 create mode 100644 security/tpe/Kconfig
 create mode 100644 security/tpe/Makefile
 create mode 100644 security/tpe/tpe_lsm.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 38d3e4e..1952bd6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11357,6 +11357,11 @@ T: git 
git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git yama/tip
 S: Supported
 F: security/yama/
 
+TPE SECURITY MODULE
+M: Matt Brown 
+S: Supported
+F: security/tpe/
+
 SENSABLE PHANTOM
 M: Jiri Slaby 
 S: Maintained
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index e29d4c6..d017f49 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1920,5 +1920,10 @@ void __init loadpin_add_hooks(void);
 #else
 static inline void loadpin_add_hooks(void) { };
 #endif
+#ifdef CONFIG_SECURITY_TPE
+void __init tpe_add_hooks(void);
+#else
+static inline void tpe_add_hooks(void) { };
+#endif
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/security/Kconfig b/security/Kconfig
index 34fb609..30e60cd 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -245,6 +245,7 @@ source security/tomoyo/Kconfig
 source security/apparmor/Kconfig
 source security/loadpin/Kconfig
 source security/yama/Kconfig
+source security/tpe/Kconfig
 
 source security/integrity/Kconfig
 
diff --git a/security/Makefile b/security/Makefile
index f2d71cd..f8b5197 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -9,6 +9,7 @@ subdir-$(CONFIG_SECURITY_TOMOYO)+= tomoyo
 subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
 subdir-$(CONFIG_SECURITY_YAMA) += yama
 

[PATCH v1 1/1] Add Trusted Path Execution as a stackable LSM

2017-06-02 Thread Matt Brown
This patch was modified from Brad Spengler's Trusted Path Execution (TPE)
feature in Grsecurity and also incorporates logging ideas from
cormander's tpe-lkm.

Modifications from the Grsecurity implementation of TPE were made to
turn it into a stackable LSM using the existing LSM hook bprm_set_creds.
Also, denial messages were improved by including the full path of the
disallowed program. (This idea was taken from cormander's tpe-lkm)

Trusted Path Execution is not a new idea:

http://phrack.org/issues/52/6.html#article

| A trusted path is one that is inside is a root owned directory that
| is not group or world writable.  /bin, /usr/bin, /usr/local/bin, are
| (under normal circumstances) considered trusted.  Any non-root
| users home directory is not trusted, nor is /tmp.

This Trusted Path Execution implementation introduces the following
Kconfig options and sysctls. These config behaviors are taken straight
from Grsecurity's implementation.

CONFIG_SECURITY_TPE (sysctl=kernel.tpe.enabled)

This option enables Trusted Path Execution. TPE blocks *untrusted*
users from executing files that meet the following conditions:

* file is not in a root-owned directory
* file is writable by a user other than root

NOTE: root is never restricted by TPE

CONFIG_SECURITY_TPE_GID (sysctl=kernel.tpe.gid)

This option defines a group id that, by default, is the untrusted group.
If a user is untrusted then it has the checks described in
CONFIG_SECURITY_TPE applied. Otherwise, the user is trusted and the
checks are not applied. Since root is never restricted by TPE, you can
effectively remove the concept of a trusted or untrusted group by
setting this value to 0.

CONFIG_SECURITY_TPE_ALL (sysctl=kernel.tpe.restrict_all)

This option applies another set of restrictions to all non-root users
even if they are trusted. This only allows execution under the
following conditions:

* file is in a directory owned by the user that is not group or
  world-writable
* file is in a directory owned by root and writable only by root

CONFIG_SECURITY_TPE_INVERT (sysctl=kernel.tpe.gid_invert)

This option reverses the trust logic of the gid option and makes
kernel.tpe.gid into the trusted group. This means that all other groups
become untrusted. This sysctl is helpful when you want TPE restrictions
to apply to most of the users on the system.

Threat Models:

1. Attacker on system executing exploit on system vulnerability

*  If attacker uses a binary as a part of their system exploit, TPE can
   frustrate their efforts

*  Issues:
   *  Can be bypassed by interpreted languages such as python. You can run
  malicious code by doing: python -c 'evil code'

2. Attacker on system replaces binary used by a privileged user with a
   malicious one

*  This situation arises when administrator of a system leaves a binary
   as world writable.

*  TPE is very effective against this threat model

Signed-off-by: Matt Brown 
---
 MAINTAINERS   |   5 ++
 include/linux/lsm_hooks.h |   5 ++
 security/Kconfig  |   1 +
 security/Makefile |   2 +
 security/security.c   |   1 +
 security/tpe/Kconfig  |  57 +++
 security/tpe/Makefile |   3 +
 security/tpe/tpe_lsm.c| 175 ++
 8 files changed, 249 insertions(+)
 create mode 100644 security/tpe/Kconfig
 create mode 100644 security/tpe/Makefile
 create mode 100644 security/tpe/tpe_lsm.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 38d3e4e..1952bd6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11357,6 +11357,11 @@ T: git 
git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git yama/tip
 S: Supported
 F: security/yama/
 
+TPE SECURITY MODULE
+M: Matt Brown 
+S: Supported
+F: security/tpe/
+
 SENSABLE PHANTOM
 M: Jiri Slaby 
 S: Maintained
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index e29d4c6..d017f49 100644
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1920,5 +1920,10 @@ void __init loadpin_add_hooks(void);
 #else
 static inline void loadpin_add_hooks(void) { };
 #endif
+#ifdef CONFIG_SECURITY_TPE
+void __init tpe_add_hooks(void);
+#else
+static inline void tpe_add_hooks(void) { };
+#endif
 
 #endif /* ! __LINUX_LSM_HOOKS_H */
diff --git a/security/Kconfig b/security/Kconfig
index 34fb609..30e60cd 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -245,6 +245,7 @@ source security/tomoyo/Kconfig
 source security/apparmor/Kconfig
 source security/loadpin/Kconfig
 source security/yama/Kconfig
+source security/tpe/Kconfig
 
 source security/integrity/Kconfig
 
diff --git a/security/Makefile b/security/Makefile
index f2d71cd..f8b5197 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -9,6 +9,7 @@ subdir-$(CONFIG_SECURITY_TOMOYO)+= tomoyo
 subdir-$(CONFIG_SECURITY_APPARMOR) += apparmor
 subdir-$(CONFIG_SECURITY_YAMA) += yama
 subdir-$(CONFIG_SECURITY_LOADPIN)  += loadpin