wx

2020-08-03 Thread Gabriel Edgal
-- 
Dear friend do you receive my last message? write me back to my email
let me know.


Re: [PATCH v5 06/12] S.A.R.A.: WX protection

2019-07-08 Thread Kees Cook
On Sun, Jul 07, 2019 at 05:49:35PM +0200, Salvatore Mesoraca wrote:
> Al Viro  wrote:
> >
> > On Sat, Jul 06, 2019 at 12:54:47PM +0200, Salvatore Mesoraca wrote:
> >
> > > +#define sara_warn_or_return(err, msg) do {   \
> > > + if ((sara_wxp_flags & SARA_WXP_VERBOSE))\
> > > + pr_wxp(msg);\
> > > + if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))  \
> > > + return -err;\
> > > +} while (0)
> > > +
> > > +#define sara_warn_or_goto(label, msg) do {   \
> > > + if ((sara_wxp_flags & SARA_WXP_VERBOSE))\
> > > + pr_wxp(msg);\
> > > + if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))  \
> > > + goto label; \
> > > +} while (0)
> >
> > No.  This kind of "style" has no place in the kernel.
> >
> > Don't hide control flow.  It's nasty enough to reviewers,
> > but it's pure hell on anyone who strays into your code while
> > chasing a bug or doing general code audit.  In effect, you
> > are creating your oh-so-private C dialect and assuming that
> > everyone who ever looks at your code will start with learning
> > that *AND* incorporating it into their mental C parser.
> > I'm sorry, but you are not that important.
> >
> > If it looks like a function call, a casual reader will assume
> > that this is exactly what it is.  And when one is scanning
> > through a function (e.g. to tell if handling of some kind
> > of refcounts is correct, with twentieth grep through the
> > tree having brought something in your code into the view),
> > the last thing one wants is to switch between the area-specific
> > C dialects.  Simply because looking at yours is sandwiched
> > between digging through some crap in drivers/target/ and that
> > weird thing in kernel/tracing/, hopefully staying limited
> > to 20 seconds of glancing through several functions in your
> > code.
> >
> > Don't Do That.  Really.
> 
> I understand your concerns.
> The first version of SARA didn't use these macros,
> they were added because I was asked[1] to do so.
> 
> I have absolutely no problems in reverting this change.
> I just want to make sure that there is agreement on this matter.
> Maybe Kees can clarify his stance.
> 
> Thank you for your suggestions.
> 
> [1] 
> https://lkml.kernel.org/r/CAGXu5jJuQx2qOt_aDqDQDcqGOZ5kmr5rQ9Zjv=mrrcj65er...@mail.gmail.com

I just didn't like how difficult it was to review the repeated checking.
I thought then (and still think now) it's worth the unusual style to
improve the immediate readability. Obviously Al disagrees. I'm not
against dropping my suggestion; it's just a pain to review it and it
seems like an area that would be highly prone to subtle typos. Perhaps
some middle ground:

#define sara_warn(msg)  ({  \
if ((sara_wxp_flags & SARA_WXP_VERBOSE))\
pr_wxp(msg);\
!(sara_wxp_flags & SARA_WXP_COMPLAIN);  \
})

...

if (unlikely(sara_wxp_flags & SARA_WXP_WXORX &&
 vm_flags & VM_WRITE &&
 vm_flags & VM_EXEC &&
 sara_warn("W^X")))
return -EPERM;

that way the copy/pasting isn't present but the control flow is visible?

-- 
Kees Cook


RE: [PATCH v5 06/12] S.A.R.A.: WX protection

2019-07-08 Thread David Laight
From: Salvatore Mesoraca
> Sent: 06 July 2019 11:55
...
> Executable MMAP prevention works by preventing any new executable
> allocation after the dynamic libraries have been loaded. It works under the
> assumption that, when the dynamic libraries have been finished loading, the
> RELRO section will be marked read only.

What about writing to the file of a dynamic library after it is loaded
but before it is faulted it (or after evicting it from the I$).

...
> +#define find_relro_section(ELFH, ELFP, FILE, RELRO, FOUND) do {  
> \
> + unsigned long i;\
> + int _tmp;   \
> + loff_t _pos = 0;\
> + if (ELFH.e_type == ET_DYN || ELFH.e_type == ET_EXEC) {  \
> + for (i = 0; i < ELFH.e_phnum; ++i) {\
> + _pos = ELFH.e_phoff + i*sizeof(ELFP);   \
> + _tmp = kernel_read(FILE, , sizeof(ELFP),   \
> +&_pos);  \
> + if (_tmp != sizeof(ELFP))   \
> + break;  \
> + if (ELFP.p_type == PT_GNU_RELRO) {  \
> + RELRO = ELFP.p_offset >> PAGE_SHIFT;\
> + FOUND = true;   \
> + break;  \
> + }   \
> + }   \
> + }   \
> +} while (0)

This is big for a #define.
Since it contains kernel_read() it can't really matter if it is
a real function.

David

-
Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, 
UK
Registration No: 1397386 (Wales)



Re: [PATCH v5 06/12] S.A.R.A.: WX protection

2019-07-07 Thread Salvatore Mesoraca
Al Viro  wrote:
>
> On Sat, Jul 06, 2019 at 12:54:47PM +0200, Salvatore Mesoraca wrote:
>
> > +#define sara_warn_or_return(err, msg) do {   \
> > + if ((sara_wxp_flags & SARA_WXP_VERBOSE))\
> > + pr_wxp(msg);\
> > + if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))  \
> > + return -err;\
> > +} while (0)
> > +
> > +#define sara_warn_or_goto(label, msg) do {   \
> > + if ((sara_wxp_flags & SARA_WXP_VERBOSE))\
> > + pr_wxp(msg);\
> > + if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))  \
> > + goto label; \
> > +} while (0)
>
> No.  This kind of "style" has no place in the kernel.
>
> Don't hide control flow.  It's nasty enough to reviewers,
> but it's pure hell on anyone who strays into your code while
> chasing a bug or doing general code audit.  In effect, you
> are creating your oh-so-private C dialect and assuming that
> everyone who ever looks at your code will start with learning
> that *AND* incorporating it into their mental C parser.
> I'm sorry, but you are not that important.
>
> If it looks like a function call, a casual reader will assume
> that this is exactly what it is.  And when one is scanning
> through a function (e.g. to tell if handling of some kind
> of refcounts is correct, with twentieth grep through the
> tree having brought something in your code into the view),
> the last thing one wants is to switch between the area-specific
> C dialects.  Simply because looking at yours is sandwiched
> between digging through some crap in drivers/target/ and that
> weird thing in kernel/tracing/, hopefully staying limited
> to 20 seconds of glancing through several functions in your
> code.
>
> Don't Do That.  Really.

I understand your concerns.
The first version of SARA didn't use these macros,
they were added because I was asked[1] to do so.

I have absolutely no problems in reverting this change.
I just want to make sure that there is agreement on this matter.
Maybe Kees can clarify his stance.

Thank you for your suggestions.

[1] 
https://lkml.kernel.org/r/CAGXu5jJuQx2qOt_aDqDQDcqGOZ5kmr5rQ9Zjv=mrrcj65er...@mail.gmail.com


Re: [PATCH v5 06/12] S.A.R.A.: WX protection

2019-07-06 Thread Al Viro
On Sat, Jul 06, 2019 at 12:54:47PM +0200, Salvatore Mesoraca wrote:

> +#define sara_warn_or_return(err, msg) do {   \
> + if ((sara_wxp_flags & SARA_WXP_VERBOSE))\
> + pr_wxp(msg);\
> + if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))  \
> + return -err;\
> +} while (0)
> +
> +#define sara_warn_or_goto(label, msg) do {   \
> + if ((sara_wxp_flags & SARA_WXP_VERBOSE))\
> + pr_wxp(msg);\
> + if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))  \
> + goto label; \
> +} while (0)

No.  This kind of "style" has no place in the kernel.

Don't hide control flow.  It's nasty enough to reviewers,
but it's pure hell on anyone who strays into your code while
chasing a bug or doing general code audit.  In effect, you
are creating your oh-so-private C dialect and assuming that
everyone who ever looks at your code will start with learning
that *AND* incorporating it into their mental C parser.
I'm sorry, but you are not that important.

If it looks like a function call, a casual reader will assume
that this is exactly what it is.  And when one is scanning
through a function (e.g. to tell if handling of some kind
of refcounts is correct, with twentieth grep through the
tree having brought something in your code into the view),
the last thing one wants is to switch between the area-specific
C dialects.  Simply because looking at yours is sandwiched
between digging through some crap in drivers/target/ and that
weird thing in kernel/tracing/, hopefully staying limited
to 20 seconds of glancing through several functions in your
code.

Don't Do That.  Really.


Re: [PATCH v5 06/12] S.A.R.A.: WX protection

2019-07-06 Thread Randy Dunlap
On 7/6/19 3:54 AM, Salvatore Mesoraca wrote:
> diff --git a/security/sara/Kconfig b/security/sara/Kconfig
> index b98cf27..54a96e0 100644
> --- a/security/sara/Kconfig
> +++ b/security/sara/Kconfig
> @@ -60,3 +60,77 @@ config SECURITY_SARA_NO_RUNTIME_ENABLE
>  
> If unsure, answer Y.
>  
> +config SECURITY_SARA_WXPROT
> + bool "WX Protection: W^X and W!->X protections"
> + depends on SECURITY_SARA
> + default y
> + help
> +   WX Protection aims to improve user-space programs security by 
> applying:
> + - W^X memory restriction
> + - W!->X (once writable never executable) mprotect restriction
> + - Executable MMAP prevention
> +   See Documentation/admin-guide/LSM/SARA.rst. for further information.

.rst for further information.

> +
> +   If unsure, answer Y.
> +
> +choice
> + prompt "Default action for W^X and W!->X protections"
> + depends on SECURITY_SARA
> + depends on SECURITY_SARA_WXPROT
> + default SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
> +
> +help

Use tab instead of spaces for indentation above.

> +   Choose the default behaviour of WX Protection when no config
> +   rule matches or no rule is loaded.
> +   For further information on available flags and their meaning
> +   see Documentation/admin-guide/LSM/SARA.rst.
> +
> + config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
> + bool "Protections enabled but not enforced."
> + help
> +   All features enabled except "Executable MMAP prevention",
> +   verbose reporting, but no actual enforce: it just complains.
> +   Its numeric value is 0x3f, for more information see
> +   Documentation/admin-guide/LSM/SARA.rst.
> +
> +config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
> + bool "Full protection, verbose."
> + help
> +   All features enabled except "Executable MMAP prevention".
> +   The enabled features will be enforced with verbose reporting.
> +   Its numeric value is 0x2f, for more information see
> +   Documentation/admin-guide/LSM/SARA.rst.
> +
> +config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE
> + bool "Full protection, quiet."
> + help
> +   All features enabled except "Executable MMAP prevention".
> +   The enabled features will be enforced quietly.
> +   Its numeric value is 0xf, for more information see
> +   Documentation/admin-guide/LSM/SARA.rst.
> +
> + config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_NONE
> + bool "No protection at all."
> + help
> +   All features disabled.
> +   Its numeric value is 0, for more information see
> +       Documentation/admin-guide/LSM/SARA.rst.
> +endchoice
> +
> +config SECURITY_SARA_WXPROT_DISABLED
> + bool "WX protection will be disabled at boot."
> + depends on SECURITY_SARA_WXPROT
> + default n

Omit "default n" please.

> + help
> +   If you say Y here WX protection won't be enabled at startup. You can
> +   override this option via user-space utilities or at boot time via
> +   "sara.wxprot_enabled=[0|1]" kernel parameter.
> +
> +   If unsure, answer N.
> +
> +config SECURITY_SARA_WXPROT_DEFAULT_FLAGS
> + hex
> + default "0x3f" if 
> SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
> + default "0x2f" if SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
> + default "0xf" if SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE
> + default "0" if SECURITY_SARA_WXPROT_DEFAULT_FLAGS_NONE


-- 
~Randy


[PATCH v5 06/12] S.A.R.A.: WX protection

2019-07-06 Thread Salvatore Mesoraca
Introduction of S.A.R.A. WX Protection.
It aims to improve user-space programs security by applying:
- W^X enforcement
- W!->X (once writable never executable) mprotect restriction
- Executable MMAP prevention

All of the above features can be enabled or disabled both system wide
or on a per executable basis through the use of configuration.
W^X enforcement works by blocking any memory allocation or mprotect
invocation with both the WRITE and the EXEC flags enabled.
W!->X restriction works by preventing any mprotect invocation that makes
executable any page that is flagged VM_MAYWRITE.
Additional restrictions are in place for System V shared memory segments:
if a segment was attached as writable (executable) in the past it won't be
allowed to be attached as executable (writable) in the future.
This feature can be configured separately for stack, heap and other
allocations.
Executable MMAP prevention works by preventing any new executable
allocation after the dynamic libraries have been loaded. It works under the
assumption that, when the dynamic libraries have been finished loading, the
RELRO section will be marked read only.

Parts of WX Protection are inspired by some of the features available in
PaX according to my understanding of the code. Changes or omissions from
the original code are mine and don't reflect the original grsecurity/PaX
code.

Signed-off-by: Salvatore Mesoraca 
---
 security/sara/Kconfig  |  74 +
 security/sara/Makefile |   1 +
 security/sara/include/wxprot.h |  29 ++
 security/sara/main.c   |   6 +
 security/sara/wxprot.c | 679 +
 5 files changed, 789 insertions(+)
 create mode 100644 security/sara/include/wxprot.h
 create mode 100644 security/sara/wxprot.c

diff --git a/security/sara/Kconfig b/security/sara/Kconfig
index b98cf27..54a96e0 100644
--- a/security/sara/Kconfig
+++ b/security/sara/Kconfig
@@ -60,3 +60,77 @@ config SECURITY_SARA_NO_RUNTIME_ENABLE
 
  If unsure, answer Y.
 
+config SECURITY_SARA_WXPROT
+   bool "WX Protection: W^X and W!->X protections"
+   depends on SECURITY_SARA
+   default y
+       help
+ WX Protection aims to improve user-space programs security by 
applying:
+   - W^X memory restriction
+   - W!->X (once writable never executable) mprotect restriction
+   - Executable MMAP prevention
+ See Documentation/admin-guide/LSM/SARA.rst. for further information.
+
+ If unsure, answer Y.
+
+choice
+   prompt "Default action for W^X and W!->X protections"
+   depends on SECURITY_SARA
+   depends on SECURITY_SARA_WXPROT
+   default SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+
+help
+     Choose the default behaviour of WX Protection when no config
+ rule matches or no rule is loaded.
+ For further information on available flags and their meaning
+ see Documentation/admin-guide/LSM/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+   bool "Protections enabled but not enforced."
+   help
+ All features enabled except "Executable MMAP prevention",
+ verbose reporting, but no actual enforce: it just complains.
+ Its numeric value is 0x3f, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
+   bool "Full protection, verbose."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced with verbose reporting.
+ Its numeric value is 0x2f, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE
+   bool "Full protection, quiet."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced quietly.
+ Its numeric value is 0xf, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_NONE
+   bool "No protection at all."
+   help
+ All features disabled.
+ Its numeric value is 0, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+endchoice
+
+config SECURITY_SARA_WXPROT_DISABLED
+   bool "WX protection will be disabled at boot."
+   depends on SECURITY_SARA_WXPROT
+   default n
+   help
+ If you say Y here WX protection won't be enabled at startup. You can
+ override this option via user-space utilities or 

[PATCH v5 09/12] S.A.R.A.: WX protection procattr interface

2019-07-06 Thread Salvatore Mesoraca
This allow threads to get current WX Protection flags for themselves or
for other threads (if they have CAP_MAC_ADMIN).
It also allow a thread to set itself flags to a stricter set of rules than
the current one.
Via a new wxprot flag (SARA_WXP_FORCE_WXORX) is it possible to ask the
kernel to rescan the memory and remove the VM_WRITE flag from any area
that is marked both writable and executable.
Protections that prevent the runtime creation of executable code
can be troublesome for all those programs that actually need to do it
e.g. programs shipping with a JIT compiler built-in.
This feature can be use to run the JIT compiler with few restrictions while
enforcing full WX Protection in the rest of the program.
To simplify access to this interface a CC0 licensed library is available
here: https://github.com/smeso/libsara

Signed-off-by: Salvatore Mesoraca 
---
 fs/proc/base.c |  11 
 security/sara/wxprot.c | 150 +
 2 files changed, 161 insertions(+)

diff --git a/fs/proc/base.c b/fs/proc/base.c
index 255f675..7873d27 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2612,6 +2612,13 @@ static ssize_t proc_pid_attr_write(struct file * file, 
const char __user * buf,
 LSM_DIR_OPS(smack);
 #endif
 
+#ifdef CONFIG_SECURITY_SARA
+static const struct pid_entry sara_attr_dir_stuff[] = {
+   ATTR("sara", "wxprot", 0666),
+};
+LSM_DIR_OPS(sara);
+#endif
+
 static const struct pid_entry attr_dir_stuff[] = {
ATTR(NULL, "current",   0666),
ATTR(NULL, "prev",  0444),
@@ -2623,6 +2630,10 @@ static ssize_t proc_pid_attr_write(struct file * file, 
const char __user * buf,
DIR("smack",0555,
proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops),
 #endif
+#ifdef CONFIG_SECURITY_SARA
+   DIR("sara", 0555,
+   proc_sara_attr_dir_inode_ops, proc_sara_attr_dir_ops),
+#endif
 };
 
 static int proc_attr_dir_readdir(struct file *file, struct dir_context *ctx)
diff --git a/security/sara/wxprot.c b/security/sara/wxprot.c
index 9c42bfc..84f7b1e 100644
--- a/security/sara/wxprot.c
+++ b/security/sara/wxprot.c
@@ -14,6 +14,7 @@
 #ifdef CONFIG_SECURITY_SARA_WXPROT
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -42,6 +43,7 @@
 #define SARA_WXP_COMPLAIN  0x0010
 #define SARA_WXP_VERBOSE   0x0020
 #define SARA_WXP_MMAP  0x0040
+#define SARA_WXP_FORCE_WXORX   0x0080
 #define SARA_WXP_EMUTRAMP  0x0100
 #define SARA_WXP_TRANSFER  0x0200
 #define SARA_WXP_NONE  0x
@@ -540,6 +542,152 @@ static int sara_pagefault_handler(struct pt_regs *regs,
 }
 #endif
 
+static int sara_getprocattr(struct task_struct *p, char *name, char **value)
+{
+   int ret;
+   u16 flags;
+   char *buf;
+
+   ret = -EINVAL;
+   if (strcmp(name, "wxprot") != 0)
+   goto out;
+
+   ret = -EACCES;
+   if (unlikely(current != p &&
+!capable(CAP_MAC_ADMIN)))
+   goto out;
+
+   ret = -ENOMEM;
+   buf = kzalloc(8, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto out;
+
+   if (!sara_enabled || !wxprot_enabled) {
+   flags = 0x0;
+   } else {
+   rcu_read_lock();
+   flags = get_sara_wxp_flags(__task_cred(p));
+   rcu_read_unlock();
+   }
+
+   snprintf(buf, 8, "0x%04x\n", flags);
+   ret = strlen(buf);
+   *value = buf;
+
+out:
+   return ret;
+}
+
+static int sara_setprocattr(const char *name, void *value, size_t size)
+{
+   int ret;
+   struct vm_area_struct *vma;
+   struct cred *new = prepare_creds();
+   u16 cur_flags;
+   u16 req_flags;
+   char *buf = NULL;
+
+   ret = -EINVAL;
+   if (!sara_enabled || !wxprot_enabled)
+   goto error;
+   if (unlikely(new == NULL))
+   return -ENOMEM;
+   if (strcmp(name, "wxprot") != 0)
+   goto error;
+   if (unlikely(value == NULL || size == 0 || size > 7))
+   goto error;
+   ret = -ENOMEM;
+   buf = kmalloc(size+1, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto error;
+   buf[size] = '\0';
+   memcpy(buf, value, size);
+   ret = -EINVAL;
+   if (unlikely(strlen(buf) != size))
+   goto error;
+   if (unlikely(kstrtou16(buf, 0, _flags) != 0))
+   goto error;
+   /*
+* SARA_WXP_FORCE_WXORX is a procattr only flag with a special
+* meaning and it isn't recognized by are_flags_valid
+*/
+   if (unlikely(!are_flags_valid(req_flags & ~SARA_WXP_FORCE_WXORX)))
+   goto error;
+   /*
+* Extra checks on requested flags:
+*   - SARA_WXP_FORCE_WXORX requires SARA_WXP_WXORX
+*   - SARA_WXP_MMAP can only be activ

[PATCH 4.14 033/146] x86/mm/dump_pagetables: Check user space page table for WX pages

2018-01-01 Thread Greg Kroah-Hartman
4.14-stable review patch.  If anyone has any objections, please let me know.

--

From: Thomas Gleixner <t...@linutronix.de>

commit b4bf4f924b1d7bade38fd51b2e401d20d0956e4d upstream.

ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the PAGE_TABLE_ISOLATION user space page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL.

Add the check for the user space page table.

Signed-off-by: Thomas Gleixner <t...@linutronix.de>
Cc: Andy Lutomirski <l...@kernel.org>
Cc: Boris Ostrovsky <boris.ostrov...@oracle.com>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Brian Gerst <brge...@gmail.com>
Cc: Dave Hansen <dave.han...@linux.intel.com>
Cc: David Laight <david.lai...@aculab.com>
Cc: Denys Vlasenko <dvlas...@redhat.com>
Cc: Eduardo Valentin <edu...@amazon.com>
Cc: Greg KH <gre...@linuxfoundation.org>
Cc: H. Peter Anvin <h...@zytor.com>
Cc: Josh Poimboeuf <jpoim...@redhat.com>
Cc: Juergen Gross <jgr...@suse.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Will Deacon <will.dea...@arm.com>
Cc: aligu...@amazon.com
Cc: daniel.gr...@iaik.tugraz.at
Cc: hu...@google.com
Cc: keesc...@google.com
Cc: linux...@kvack.org
Signed-off-by: Ingo Molnar <mi...@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 arch/x86/include/asm/pgtable.h |1 +
 arch/x86/mm/debug_pagetables.c |2 +-
 arch/x86/mm/dump_pagetables.c  |   30 +-
 3 files changed, 27 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -476,7 +476,7 @@ static inline bool is_hypervisor_range(i
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -489,7 +489,7 @@ static void ptdump_walk_pgd_level_core(s
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -527,13 +527,33 @@ static void ptdump_walk_pgd_level_core(s
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+static void ptdump_walk_user_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_PAGE_TABLE_ISOLATION
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   if (!static_cpu_has(X86_FEATURE_PTI))
+   return;
+
+   pr_info("x86/mm: Checking user space page tables\n");
+   pgd = kernel_to_user_pgdp(pgd);
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_user_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)




[PATCH 4.14 033/146] x86/mm/dump_pagetables: Check user space page table for WX pages

2018-01-01 Thread Greg Kroah-Hartman
4.14-stable review patch.  If anyone has any objections, please let me know.

--

From: Thomas Gleixner 

commit b4bf4f924b1d7bade38fd51b2e401d20d0956e4d upstream.

ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the PAGE_TABLE_ISOLATION user space page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL.

Add the check for the user space page table.

Signed-off-by: Thomas Gleixner 
Cc: Andy Lutomirski 
Cc: Boris Ostrovsky 
Cc: Borislav Petkov 
Cc: Brian Gerst 
Cc: Dave Hansen 
Cc: David Laight 
Cc: Denys Vlasenko 
Cc: Eduardo Valentin 
Cc: Greg KH 
Cc: H. Peter Anvin 
Cc: Josh Poimboeuf 
Cc: Juergen Gross 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Will Deacon 
Cc: aligu...@amazon.com
Cc: daniel.gr...@iaik.tugraz.at
Cc: hu...@google.com
Cc: keesc...@google.com
Cc: linux...@kvack.org
Signed-off-by: Ingo Molnar 
Signed-off-by: Greg Kroah-Hartman 

---
 arch/x86/include/asm/pgtable.h |1 +
 arch/x86/mm/debug_pagetables.c |2 +-
 arch/x86/mm/dump_pagetables.c  |   30 +-
 3 files changed, 27 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -476,7 +476,7 @@ static inline bool is_hypervisor_range(i
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -489,7 +489,7 @@ static void ptdump_walk_pgd_level_core(s
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -527,13 +527,33 @@ static void ptdump_walk_pgd_level_core(s
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+static void ptdump_walk_user_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_PAGE_TABLE_ISOLATION
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   if (!static_cpu_has(X86_FEATURE_PTI))
+   return;
+
+   pr_info("x86/mm: Checking user space page tables\n");
+   pgd = kernel_to_user_pgdp(pgd);
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_user_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)




[patch V181 52/54] x86/mm/dump_pagetables: Check user space page table for WX pages

2017-12-20 Thread Thomas Gleixner
From: Thomas Gleixner <t...@linutronix.de>

ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the PAGE_TABLE_ISOLATION user space page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL.

Add the check for the user space page table.

Signed-off-by: Thomas Gleixner <t...@linutronix.de>
Signed-off-by: Ingo Molnar <mi...@kernel.org>
Cc: Andy Lutomirski <l...@kernel.org>
Cc: Boris Ostrovsky <boris.ostrov...@oracle.com>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Brian Gerst <brge...@gmail.com>
Cc: Dave Hansen <dave.han...@linux.intel.com>
Cc: David Laight <david.lai...@aculab.com>
Cc: Denys Vlasenko <dvlas...@redhat.com>
Cc: Eduardo Valentin <edu...@amazon.com>
Cc: Greg KH <gre...@linuxfoundation.org>
Cc: H. Peter Anvin <h...@zytor.com>
Cc: Josh Poimboeuf <jpoim...@redhat.com>
Cc: Juergen Gross <jgr...@suse.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Will Deacon <will.dea...@arm.com>
Cc: aligu...@amazon.com
Cc: daniel.gr...@iaik.tugraz.at
Cc: hu...@google.com
Cc: keesc...@google.com
Cc: linux...@kvack.org
---
 arch/x86/include/asm/pgtable.h |1 +
 arch/x86/mm/debug_pagetables.c |2 +-
 arch/x86/mm/dump_pagetables.c  |   30 +-
 3 files changed, 27 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -476,7 +476,7 @@ static inline bool is_hypervisor_range(i
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -489,7 +489,7 @@ static void ptdump_walk_pgd_level_core(s
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -527,13 +527,33 @@ static void ptdump_walk_pgd_level_core(s
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+static void ptdump_walk_user_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_PAGE_TABLE_ISOLATION
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   if (!static_cpu_has(X86_FEATURE_PTI))
+   return;
+
+   pr_info("x86/mm: Checking user space page tables\n");
+   pgd = kernel_to_user_pgdp(pgd);
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_user_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)




[patch V181 52/54] x86/mm/dump_pagetables: Check user space page table for WX pages

2017-12-20 Thread Thomas Gleixner
From: Thomas Gleixner 

ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the PAGE_TABLE_ISOLATION user space page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL.

Add the check for the user space page table.

Signed-off-by: Thomas Gleixner 
Signed-off-by: Ingo Molnar 
Cc: Andy Lutomirski 
Cc: Boris Ostrovsky 
Cc: Borislav Petkov 
Cc: Brian Gerst 
Cc: Dave Hansen 
Cc: David Laight 
Cc: Denys Vlasenko 
Cc: Eduardo Valentin 
Cc: Greg KH 
Cc: H. Peter Anvin 
Cc: Josh Poimboeuf 
Cc: Juergen Gross 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Will Deacon 
Cc: aligu...@amazon.com
Cc: daniel.gr...@iaik.tugraz.at
Cc: hu...@google.com
Cc: keesc...@google.com
Cc: linux...@kvack.org
---
 arch/x86/include/asm/pgtable.h |1 +
 arch/x86/mm/debug_pagetables.c |2 +-
 arch/x86/mm/dump_pagetables.c  |   30 +-
 3 files changed, 27 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -476,7 +476,7 @@ static inline bool is_hypervisor_range(i
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -489,7 +489,7 @@ static void ptdump_walk_pgd_level_core(s
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -527,13 +527,33 @@ static void ptdump_walk_pgd_level_core(s
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+static void ptdump_walk_user_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_PAGE_TABLE_ISOLATION
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   if (!static_cpu_has(X86_FEATURE_PTI))
+   return;
+
+   pr_info("x86/mm: Checking user space page tables\n");
+   pgd = kernel_to_user_pgdp(pgd);
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_user_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)




[patch V163 49/51] x86/mm/dump_pagetables: Check user space page table for WX pages

2017-12-18 Thread Thomas Gleixner
From: Thomas Gleixner <t...@linutronix.de>

ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the PAGE_TABLE_ISOLATION user space page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL.

Add the check for the user space page table.

Signed-off-by: Thomas Gleixner <t...@linutronix.de>
Signed-off-by: Ingo Molnar <mi...@kernel.org>
Cc: Andy Lutomirski <l...@kernel.org>
Cc: Boris Ostrovsky <boris.ostrov...@oracle.com>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Brian Gerst <brge...@gmail.com>
Cc: Dave Hansen <dave.han...@linux.intel.com>
Cc: David Laight <david.lai...@aculab.com>
Cc: Denys Vlasenko <dvlas...@redhat.com>
Cc: Eduardo Valentin <edu...@amazon.com>
Cc: Greg KH <gre...@linuxfoundation.org>
Cc: H. Peter Anvin <h...@zytor.com>
Cc: Josh Poimboeuf <jpoim...@redhat.com>
Cc: Juergen Gross <jgr...@suse.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Will Deacon <will.dea...@arm.com>
Cc: aligu...@amazon.com
Cc: daniel.gr...@iaik.tugraz.at
Cc: hu...@google.com
Cc: keesc...@google.com
Cc: linux...@kvack.org
---
 arch/x86/include/asm/pgtable.h |1 +
 arch/x86/mm/debug_pagetables.c |2 +-
 arch/x86/mm/dump_pagetables.c  |   30 +-
 3 files changed, 27 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -459,7 +459,7 @@ static inline bool is_hypervisor_range(i
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -472,7 +472,7 @@ static void ptdump_walk_pgd_level_core(s
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -510,13 +510,33 @@ static void ptdump_walk_pgd_level_core(s
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+static void ptdump_walk_user_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_PAGE_TABLE_ISOLATION
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   if (!static_cpu_has(X86_FEATURE_PTI))
+   return;
+
+   pr_info("x86/mm: Checking user space page tables\n");
+   pgd = kernel_to_user_pgdp(pgd);
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_user_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)




[patch V163 49/51] x86/mm/dump_pagetables: Check user space page table for WX pages

2017-12-18 Thread Thomas Gleixner
From: Thomas Gleixner 

ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the PAGE_TABLE_ISOLATION user space page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL.

Add the check for the user space page table.

Signed-off-by: Thomas Gleixner 
Signed-off-by: Ingo Molnar 
Cc: Andy Lutomirski 
Cc: Boris Ostrovsky 
Cc: Borislav Petkov 
Cc: Brian Gerst 
Cc: Dave Hansen 
Cc: David Laight 
Cc: Denys Vlasenko 
Cc: Eduardo Valentin 
Cc: Greg KH 
Cc: H. Peter Anvin 
Cc: Josh Poimboeuf 
Cc: Juergen Gross 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Will Deacon 
Cc: aligu...@amazon.com
Cc: daniel.gr...@iaik.tugraz.at
Cc: hu...@google.com
Cc: keesc...@google.com
Cc: linux...@kvack.org
---
 arch/x86/include/asm/pgtable.h |1 +
 arch/x86/mm/debug_pagetables.c |2 +-
 arch/x86/mm/dump_pagetables.c  |   30 +-
 3 files changed, 27 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -459,7 +459,7 @@ static inline bool is_hypervisor_range(i
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -472,7 +472,7 @@ static void ptdump_walk_pgd_level_core(s
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -510,13 +510,33 @@ static void ptdump_walk_pgd_level_core(s
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+static void ptdump_walk_user_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_PAGE_TABLE_ISOLATION
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   if (!static_cpu_has(X86_FEATURE_PTI))
+   return;
+
+   pr_info("x86/mm: Checking user space page tables\n");
+   pgd = kernel_to_user_pgdp(pgd);
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_user_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)




[patch V149 48/50] x86/mm/dump_pagetables: Check user space page table for WX pages

2017-12-16 Thread Thomas Gleixner
From: Thomas Gleixner <t...@linutronix.de>

ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the PAGE_TABLE_ISOLATION user space page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL.

Add the check for the user space page table.

Signed-off-by: Thomas Gleixner <t...@linutronix.de>
Signed-off-by: Ingo Molnar <mi...@kernel.org>
Cc: Andy Lutomirski <l...@kernel.org>
Cc: Boris Ostrovsky <boris.ostrov...@oracle.com>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Brian Gerst <brge...@gmail.com>
Cc: Dave Hansen <dave.han...@linux.intel.com>
Cc: David Laight <david.lai...@aculab.com>
Cc: Denys Vlasenko <dvlas...@redhat.com>
Cc: Eduardo Valentin <edu...@amazon.com>
Cc: Greg KH <gre...@linuxfoundation.org>
Cc: H. Peter Anvin <h...@zytor.com>
Cc: Josh Poimboeuf <jpoim...@redhat.com>
Cc: Juergen Gross <jgr...@suse.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Will Deacon <will.dea...@arm.com>
Cc: aligu...@amazon.com
Cc: daniel.gr...@iaik.tugraz.at
Cc: hu...@google.com
Cc: keesc...@google.com
Cc: linux...@kvack.org
---
 arch/x86/include/asm/pgtable.h |1 +
 arch/x86/mm/debug_pagetables.c |2 +-
 arch/x86/mm/dump_pagetables.c  |   30 +-
 3 files changed, 27 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -459,7 +459,7 @@ static inline bool is_hypervisor_range(i
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -472,7 +472,7 @@ static void ptdump_walk_pgd_level_core(s
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -510,13 +510,33 @@ static void ptdump_walk_pgd_level_core(s
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+static void ptdump_walk_user_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_PAGE_TABLE_ISOLATION
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   if (!static_cpu_has_bug(X86_BUG_CPU_SECURE_MODE_PTI))
+   return;
+
+   pr_info("x86/mm: Checking user space page tables\n");
+   pgd = kernel_to_user_pgdp(pgd);
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_user_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)




[patch V149 48/50] x86/mm/dump_pagetables: Check user space page table for WX pages

2017-12-16 Thread Thomas Gleixner
From: Thomas Gleixner 

ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the PAGE_TABLE_ISOLATION user space page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL.

Add the check for the user space page table.

Signed-off-by: Thomas Gleixner 
Signed-off-by: Ingo Molnar 
Cc: Andy Lutomirski 
Cc: Boris Ostrovsky 
Cc: Borislav Petkov 
Cc: Brian Gerst 
Cc: Dave Hansen 
Cc: David Laight 
Cc: Denys Vlasenko 
Cc: Eduardo Valentin 
Cc: Greg KH 
Cc: H. Peter Anvin 
Cc: Josh Poimboeuf 
Cc: Juergen Gross 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Will Deacon 
Cc: aligu...@amazon.com
Cc: daniel.gr...@iaik.tugraz.at
Cc: hu...@google.com
Cc: keesc...@google.com
Cc: linux...@kvack.org
---
 arch/x86/include/asm/pgtable.h |1 +
 arch/x86/mm/debug_pagetables.c |2 +-
 arch/x86/mm/dump_pagetables.c  |   30 +-
 3 files changed, 27 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -459,7 +459,7 @@ static inline bool is_hypervisor_range(i
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -472,7 +472,7 @@ static void ptdump_walk_pgd_level_core(s
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -510,13 +510,33 @@ static void ptdump_walk_pgd_level_core(s
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+static void ptdump_walk_user_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_PAGE_TABLE_ISOLATION
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   if (!static_cpu_has_bug(X86_BUG_CPU_SECURE_MODE_PTI))
+   return;
+
+   pr_info("x86/mm: Checking user space page tables\n");
+   pgd = kernel_to_user_pgdp(pgd);
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_user_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)




[kernel-hardening][PATCH v6 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-08 Thread Jinbum Park
Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

v2 :
Fix a sender name of mail header, there was an mistake.
(from "jinb.park" to Jinbum Park)
Contents of patch-set are perfectly same.

v3 :
Take advantage of the existing pg_level and bits arrays
to check ro, nx prot.

v4 :
Add boolean for ro_bit, nx_bit into prot_bits
to point ro_bit, nx_bit in pg_level.
This change is suggested by Laura Abbott.

v5 :
No changes of code.
Just add Tested-by, Reviewed-by from Laura Abbott.

v6 :
USe SPDX ids in ptdump.h
Add Reviewed-by from Kees Cook.

jinb.park (3):
  arm: mm: dump: make page table dumping reusable
  arm: mm: dump: make the page table dumping seq_file optional
  arm: mm: dump: add checking for writable and executable pages

 arch/arm/Kconfig.debug|  33 -
 arch/arm/include/asm/ptdump.h |  43 
 arch/arm/mm/Makefile  |   3 +-
 arch/arm/mm/dump.c| 151 +-
 arch/arm/mm/init.c|   2 +
 arch/arm/mm/ptdump_debugfs.c  |  34 ++
 6 files changed, 219 insertions(+), 47 deletions(-)
 create mode 100644 arch/arm/include/asm/ptdump.h
 create mode 100644 arch/arm/mm/ptdump_debugfs.c

-- 
1.9.1



[kernel-hardening][PATCH v6 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-08 Thread Jinbum Park
Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

v2 :
Fix a sender name of mail header, there was an mistake.
(from "jinb.park" to Jinbum Park)
Contents of patch-set are perfectly same.

v3 :
Take advantage of the existing pg_level and bits arrays
to check ro, nx prot.

v4 :
Add boolean for ro_bit, nx_bit into prot_bits
to point ro_bit, nx_bit in pg_level.
This change is suggested by Laura Abbott.

v5 :
No changes of code.
Just add Tested-by, Reviewed-by from Laura Abbott.

v6 :
USe SPDX ids in ptdump.h
Add Reviewed-by from Kees Cook.

jinb.park (3):
  arm: mm: dump: make page table dumping reusable
  arm: mm: dump: make the page table dumping seq_file optional
  arm: mm: dump: add checking for writable and executable pages

 arch/arm/Kconfig.debug|  33 -
 arch/arm/include/asm/ptdump.h |  43 
 arch/arm/mm/Makefile  |   3 +-
 arch/arm/mm/dump.c| 151 +-
 arch/arm/mm/init.c|   2 +
 arch/arm/mm/ptdump_debugfs.c  |  34 ++
 6 files changed, 219 insertions(+), 47 deletions(-)
 create mode 100644 arch/arm/include/asm/ptdump.h
 create mode 100644 arch/arm/mm/ptdump_debugfs.c

-- 
1.9.1



Re: [kernel-hardening][PATCH v4 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-07 Thread Kees Cook
On Wed, Dec 6, 2017 at 2:23 AM, Jinbum Park <jinb.pa...@gmail.com> wrote:
> Hi,
>
> Page table dumping code for arm64-x86 is reusable,
> and they have function for WX page checking.
> But arm doesn't have that.
>
> This path series are to makes ptdump reusable,
> and add WX page checking for arm.
> This is heavily based on arm64 version.
>
> v2 :
> Fix a sender name of mail header, there was an mistake.
> (from "jinb.park" to Jinbum Park)
> Contents of patch-set are perfectly same.
>
> v3 :
> Take advantage of the existing pg_level and bits arrays
> to check ro, nx prot.
>
> v4 :
> Add boolean for ro_bit, nx_bit into prot_bits
> to point ro_bit, nx_bit in pg_level.
> This change is suggested by Laura Abbott.
>
> jinb.park (3):
>   arm: mm: dump: make page table dumping reusable
>   arm: mm: dump: make the page table dumping seq_file optional
>   arm: mm: dump: add checking for writable and executable pages
>
>  arch/arm/Kconfig.debug|  33 -
>  arch/arm/include/asm/ptdump.h |  56 
>  arch/arm/mm/Makefile  |   3 +-
>  arch/arm/mm/dump.c| 151 
> +-
>  arch/arm/mm/init.c|   2 +
>  arch/arm/mm/ptdump_debugfs.c  |  34 ++
>  6 files changed, 232 insertions(+), 47 deletions(-)
>  create mode 100644 arch/arm/include/asm/ptdump.h
>  create mode 100644 arch/arm/mm/ptdump_debugfs.c

Please consider this series:

Reviewed-by: Kees Cook <keesc...@chromium.org>

With Laura's review, this is probably ready to put into the ARM patch tracker.

-Kees

-- 
Kees Cook
Pixel Security


Re: [kernel-hardening][PATCH v4 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-07 Thread Kees Cook
On Wed, Dec 6, 2017 at 2:23 AM, Jinbum Park  wrote:
> Hi,
>
> Page table dumping code for arm64-x86 is reusable,
> and they have function for WX page checking.
> But arm doesn't have that.
>
> This path series are to makes ptdump reusable,
> and add WX page checking for arm.
> This is heavily based on arm64 version.
>
> v2 :
> Fix a sender name of mail header, there was an mistake.
> (from "jinb.park" to Jinbum Park)
> Contents of patch-set are perfectly same.
>
> v3 :
> Take advantage of the existing pg_level and bits arrays
> to check ro, nx prot.
>
> v4 :
> Add boolean for ro_bit, nx_bit into prot_bits
> to point ro_bit, nx_bit in pg_level.
> This change is suggested by Laura Abbott.
>
> jinb.park (3):
>   arm: mm: dump: make page table dumping reusable
>   arm: mm: dump: make the page table dumping seq_file optional
>   arm: mm: dump: add checking for writable and executable pages
>
>  arch/arm/Kconfig.debug|  33 -
>  arch/arm/include/asm/ptdump.h |  56 
>  arch/arm/mm/Makefile  |   3 +-
>  arch/arm/mm/dump.c| 151 
> +-
>  arch/arm/mm/init.c|   2 +
>  arch/arm/mm/ptdump_debugfs.c  |  34 ++
>  6 files changed, 232 insertions(+), 47 deletions(-)
>  create mode 100644 arch/arm/include/asm/ptdump.h
>  create mode 100644 arch/arm/mm/ptdump_debugfs.c

Please consider this series:

Reviewed-by: Kees Cook 

With Laura's review, this is probably ready to put into the ARM patch tracker.

-Kees

-- 
Kees Cook
Pixel Security


[kernel-hardening][PATCH v5 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-07 Thread Jinbum Park
Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

v2 :
Fix a sender name of mail header, there was an mistake.
(from "jinb.park" to Jinbum Park)
Contents of patch-set are perfectly same.

v3 :
Take advantage of the existing pg_level and bits arrays
to check ro, nx prot.

v4 :
Add boolean for ro_bit, nx_bit into prot_bits
to point ro_bit, nx_bit in pg_level.
This change is suggested by Laura Abbott.

v5 : 
No changes of code.
Just add Tested-by, Reviewed-by from Laura Abbott.

jinb.park (3):
  arm: mm: dump: make page table dumping reusable
  arm: mm: dump: make the page table dumping seq_file optional
  arm: mm: dump: add checking for writable and executable pages

 arch/arm/Kconfig.debug|  33 -
 arch/arm/include/asm/ptdump.h |  56 
 arch/arm/mm/Makefile  |   3 +-
 arch/arm/mm/dump.c| 151 +-
 arch/arm/mm/init.c|   2 +
 arch/arm/mm/ptdump_debugfs.c  |  34 ++
 6 files changed, 232 insertions(+), 47 deletions(-)
 create mode 100644 arch/arm/include/asm/ptdump.h
 create mode 100644 arch/arm/mm/ptdump_debugfs.c

-- 
1.9.1



[kernel-hardening][PATCH v5 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-07 Thread Jinbum Park
Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

v2 :
Fix a sender name of mail header, there was an mistake.
(from "jinb.park" to Jinbum Park)
Contents of patch-set are perfectly same.

v3 :
Take advantage of the existing pg_level and bits arrays
to check ro, nx prot.

v4 :
Add boolean for ro_bit, nx_bit into prot_bits
to point ro_bit, nx_bit in pg_level.
This change is suggested by Laura Abbott.

v5 : 
No changes of code.
Just add Tested-by, Reviewed-by from Laura Abbott.

jinb.park (3):
  arm: mm: dump: make page table dumping reusable
  arm: mm: dump: make the page table dumping seq_file optional
  arm: mm: dump: add checking for writable and executable pages

 arch/arm/Kconfig.debug|  33 -
 arch/arm/include/asm/ptdump.h |  56 
 arch/arm/mm/Makefile  |   3 +-
 arch/arm/mm/dump.c| 151 +-
 arch/arm/mm/init.c|   2 +
 arch/arm/mm/ptdump_debugfs.c  |  34 ++
 6 files changed, 232 insertions(+), 47 deletions(-)
 create mode 100644 arch/arm/include/asm/ptdump.h
 create mode 100644 arch/arm/mm/ptdump_debugfs.c

-- 
1.9.1



Re: [kernel-hardening][PATCH v4 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-06 Thread Laura Abbott

On 12/06/2017 02:23 AM, Jinbum Park wrote:

Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

v2 :
Fix a sender name of mail header, there was an mistake.
(from "jinb.park" to Jinbum Park)
Contents of patch-set are perfectly same.

v3 :
Take advantage of the existing pg_level and bits arrays
to check ro, nx prot.

v4 :
Add boolean for ro_bit, nx_bit into prot_bits
to point ro_bit, nx_bit in pg_level.
This change is suggested by Laura Abbott.

jinb.park (3):
   arm: mm: dump: make page table dumping reusable
   arm: mm: dump: make the page table dumping seq_file optional
   arm: mm: dump: add checking for writable and executable pages

  arch/arm/Kconfig.debug|  33 -
  arch/arm/include/asm/ptdump.h |  56 
  arch/arm/mm/Makefile  |   3 +-
  arch/arm/mm/dump.c| 151 +-
  arch/arm/mm/init.c|   2 +
  arch/arm/mm/ptdump_debugfs.c  |  34 ++
  6 files changed, 232 insertions(+), 47 deletions(-)
  create mode 100644 arch/arm/include/asm/ptdump.h
  create mode 100644 arch/arm/mm/ptdump_debugfs.c



You can add

Tested-by: Laura Abbott <labb...@redhat.com>
Reviewed-by: Laura Abbott <labb...@redhat.com>


Re: [kernel-hardening][PATCH v4 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-06 Thread Laura Abbott

On 12/06/2017 02:23 AM, Jinbum Park wrote:

Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

v2 :
Fix a sender name of mail header, there was an mistake.
(from "jinb.park" to Jinbum Park)
Contents of patch-set are perfectly same.

v3 :
Take advantage of the existing pg_level and bits arrays
to check ro, nx prot.

v4 :
Add boolean for ro_bit, nx_bit into prot_bits
to point ro_bit, nx_bit in pg_level.
This change is suggested by Laura Abbott.

jinb.park (3):
   arm: mm: dump: make page table dumping reusable
   arm: mm: dump: make the page table dumping seq_file optional
   arm: mm: dump: add checking for writable and executable pages

  arch/arm/Kconfig.debug|  33 -
  arch/arm/include/asm/ptdump.h |  56 
  arch/arm/mm/Makefile  |   3 +-
  arch/arm/mm/dump.c| 151 +-
  arch/arm/mm/init.c|   2 +
  arch/arm/mm/ptdump_debugfs.c  |  34 ++
  6 files changed, 232 insertions(+), 47 deletions(-)
  create mode 100644 arch/arm/include/asm/ptdump.h
  create mode 100644 arch/arm/mm/ptdump_debugfs.c



You can add

Tested-by: Laura Abbott 
Reviewed-by: Laura Abbott 


[kernel-hardening][PATCH v4 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-06 Thread Jinbum Park
Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

v2 :
Fix a sender name of mail header, there was an mistake.
(from "jinb.park" to Jinbum Park)
Contents of patch-set are perfectly same.

v3 :
Take advantage of the existing pg_level and bits arrays
to check ro, nx prot.

v4 :
Add boolean for ro_bit, nx_bit into prot_bits
to point ro_bit, nx_bit in pg_level.
This change is suggested by Laura Abbott.

jinb.park (3):
  arm: mm: dump: make page table dumping reusable
  arm: mm: dump: make the page table dumping seq_file optional
  arm: mm: dump: add checking for writable and executable pages

 arch/arm/Kconfig.debug|  33 -
 arch/arm/include/asm/ptdump.h |  56 
 arch/arm/mm/Makefile  |   3 +-
 arch/arm/mm/dump.c| 151 +-
 arch/arm/mm/init.c|   2 +
 arch/arm/mm/ptdump_debugfs.c  |  34 ++
 6 files changed, 232 insertions(+), 47 deletions(-)
 create mode 100644 arch/arm/include/asm/ptdump.h
 create mode 100644 arch/arm/mm/ptdump_debugfs.c

-- 
1.9.1



[kernel-hardening][PATCH v4 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-06 Thread Jinbum Park
Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

v2 :
Fix a sender name of mail header, there was an mistake.
(from "jinb.park" to Jinbum Park)
Contents of patch-set are perfectly same.

v3 :
Take advantage of the existing pg_level and bits arrays
to check ro, nx prot.

v4 :
Add boolean for ro_bit, nx_bit into prot_bits
to point ro_bit, nx_bit in pg_level.
This change is suggested by Laura Abbott.

jinb.park (3):
  arm: mm: dump: make page table dumping reusable
  arm: mm: dump: make the page table dumping seq_file optional
  arm: mm: dump: add checking for writable and executable pages

 arch/arm/Kconfig.debug|  33 -
 arch/arm/include/asm/ptdump.h |  56 
 arch/arm/mm/Makefile  |   3 +-
 arch/arm/mm/dump.c| 151 +-
 arch/arm/mm/init.c|   2 +
 arch/arm/mm/ptdump_debugfs.c  |  34 ++
 6 files changed, 232 insertions(+), 47 deletions(-)
 create mode 100644 arch/arm/include/asm/ptdump.h
 create mode 100644 arch/arm/mm/ptdump_debugfs.c

-- 
1.9.1



Re: [kernel-hardening][PATCH v3 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-05 Thread Laura Abbott

On 12/04/2017 06:24 AM, Jinbum Park wrote:

Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

v2 :
Fix a sender name of mail header, there was an mistake.
(from "jinb.park" to Jinbum Park)
Contents of patch-set are perfectly same.

v3 :
Take advantage of the existing pg_level and bits arrays
to check ro, nx prot.

jinb.park (3):
   arm: mm: dump: make page table dumping reusable
   arm: mm: dump: make the page table dumping seq_file optional
   arm: mm: dump: add checking for writable and executable pages

  arch/arm/Kconfig.debug|  33 +-
  arch/arm/include/asm/ptdump.h |  56 
  arch/arm/mm/Makefile  |   3 +-
  arch/arm/mm/dump.c| 144 +-
  arch/arm/mm/init.c|   2 +
  arch/arm/mm/ptdump_debugfs.c  |  34 ++
  6 files changed, 226 insertions(+), 46 deletions(-)
  create mode 100644 arch/arm/include/asm/ptdump.h
  create mode 100644 arch/arm/mm/ptdump_debugfs.c



This detects the issue fixed by 400eeffaffc7 ("ARM: 8722/1: mm:
make STRICT_KERNEL_RWX effective for LPAE"). I'll give it another
test after the next version.

Thanks,
Laura


Re: [kernel-hardening][PATCH v3 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-05 Thread Laura Abbott

On 12/04/2017 06:24 AM, Jinbum Park wrote:

Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

v2 :
Fix a sender name of mail header, there was an mistake.
(from "jinb.park" to Jinbum Park)
Contents of patch-set are perfectly same.

v3 :
Take advantage of the existing pg_level and bits arrays
to check ro, nx prot.

jinb.park (3):
   arm: mm: dump: make page table dumping reusable
   arm: mm: dump: make the page table dumping seq_file optional
   arm: mm: dump: add checking for writable and executable pages

  arch/arm/Kconfig.debug|  33 +-
  arch/arm/include/asm/ptdump.h |  56 
  arch/arm/mm/Makefile  |   3 +-
  arch/arm/mm/dump.c| 144 +-
  arch/arm/mm/init.c|   2 +
  arch/arm/mm/ptdump_debugfs.c  |  34 ++
  6 files changed, 226 insertions(+), 46 deletions(-)
  create mode 100644 arch/arm/include/asm/ptdump.h
  create mode 100644 arch/arm/mm/ptdump_debugfs.c



This detects the issue fixed by 400eeffaffc7 ("ARM: 8722/1: mm:
make STRICT_KERNEL_RWX effective for LPAE"). I'll give it another
test after the next version.

Thanks,
Laura


Re: [kernel-hardening][PATCH v3 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-05 Thread Kees Cook
On Mon, Dec 4, 2017 at 6:24 AM, Jinbum Park <jinb.pa...@gmail.com> wrote:
> Hi,
>
> Page table dumping code for arm64-x86 is reusable,
> and they have function for WX page checking.
> But arm doesn't have that.
>
> This path series are to makes ptdump reusable,
> and add WX page checking for arm.
> This is heavily based on arm64 version.

Thanks for working on this! I sent along a few nits.

-Kees

>
> v2 :
> Fix a sender name of mail header, there was an mistake.
> (from "jinb.park" to Jinbum Park)
> Contents of patch-set are perfectly same.
>
> v3 :
> Take advantage of the existing pg_level and bits arrays
> to check ro, nx prot.
>
> jinb.park (3):
>   arm: mm: dump: make page table dumping reusable
>   arm: mm: dump: make the page table dumping seq_file optional
>   arm: mm: dump: add checking for writable and executable pages
>
>  arch/arm/Kconfig.debug|  33 +-
>  arch/arm/include/asm/ptdump.h |  56 
>  arch/arm/mm/Makefile  |   3 +-
>  arch/arm/mm/dump.c| 144 
> +-
>  arch/arm/mm/init.c|   2 +
>  arch/arm/mm/ptdump_debugfs.c  |  34 ++
>  6 files changed, 226 insertions(+), 46 deletions(-)
>  create mode 100644 arch/arm/include/asm/ptdump.h
>  create mode 100644 arch/arm/mm/ptdump_debugfs.c
>
> --
> 1.9.1
>



-- 
Kees Cook
Pixel Security


Re: [kernel-hardening][PATCH v3 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-05 Thread Kees Cook
On Mon, Dec 4, 2017 at 6:24 AM, Jinbum Park  wrote:
> Hi,
>
> Page table dumping code for arm64-x86 is reusable,
> and they have function for WX page checking.
> But arm doesn't have that.
>
> This path series are to makes ptdump reusable,
> and add WX page checking for arm.
> This is heavily based on arm64 version.

Thanks for working on this! I sent along a few nits.

-Kees

>
> v2 :
> Fix a sender name of mail header, there was an mistake.
> (from "jinb.park" to Jinbum Park)
> Contents of patch-set are perfectly same.
>
> v3 :
> Take advantage of the existing pg_level and bits arrays
> to check ro, nx prot.
>
> jinb.park (3):
>   arm: mm: dump: make page table dumping reusable
>   arm: mm: dump: make the page table dumping seq_file optional
>   arm: mm: dump: add checking for writable and executable pages
>
>  arch/arm/Kconfig.debug|  33 +-
>  arch/arm/include/asm/ptdump.h |  56 
>  arch/arm/mm/Makefile  |   3 +-
>  arch/arm/mm/dump.c| 144 
> +-
>  arch/arm/mm/init.c|   2 +
>  arch/arm/mm/ptdump_debugfs.c  |  34 ++
>  6 files changed, 226 insertions(+), 46 deletions(-)
>  create mode 100644 arch/arm/include/asm/ptdump.h
>  create mode 100644 arch/arm/mm/ptdump_debugfs.c
>
> --
> 1.9.1
>



-- 
Kees Cook
Pixel Security


[patch 59/60] x86/mm/dump_pagetables: Check user space page table for WX pages

2017-12-04 Thread Thomas Gleixner
From: Thomas Gleixner <t...@linutronix.de>

ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the KERNEL_PAGE_TABLE_ISOLATION user space page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL.

Add the check for the user space page table.

Signed-off-by: Thomas Gleixner <t...@linutronix.de>
Cc: Rik van Riel <r...@redhat.com>
Cc: keesc...@google.com
Cc: Denys Vlasenko <dvlas...@redhat.com>
Cc: moritz.l...@iaik.tugraz.at
Cc: linux...@kvack.org
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Brian Gerst <brge...@gmail.com>
Cc: Dave Hansen <dave.han...@linux.intel.com>
Cc: hu...@google.com
Cc: daniel.gr...@iaik.tugraz.at
Cc: Borislav Petkov <b...@alien8.de>
Cc: Andy Lutomirski <l...@kernel.org>
Cc: Josh Poimboeuf <jpoim...@redhat.com>
Cc: michael.schw...@iaik.tugraz.at
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: richard.fell...@student.tugraz.at

---
 arch/x86/include/asm/pgtable.h |1 +
 arch/x86/mm/debug_pagetables.c |2 +-
 arch/x86/mm/dump_pagetables.c  |   30 +-
 3 files changed, 27 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -447,7 +447,7 @@ static inline bool is_hypervisor_range(i
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -460,7 +460,7 @@ static void ptdump_walk_pgd_level_core(s
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -498,13 +498,33 @@ static void ptdump_walk_pgd_level_core(s
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+static void ptdump_walk_user_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_KERNEL_PAGE_TABLE_ISOLATION
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   if (!static_cpu_has_bug(X86_BUG_CPU_SECURE_MODE_KPTI))
+   return;
+
+   pr_info("x86/mm: Checking user space page tables\n");
+   pgd = kernel_to_user_pgdp(pgd);
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_user_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)




[patch 59/60] x86/mm/dump_pagetables: Check user space page table for WX pages

2017-12-04 Thread Thomas Gleixner
From: Thomas Gleixner 

ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the KERNEL_PAGE_TABLE_ISOLATION user space page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL.

Add the check for the user space page table.

Signed-off-by: Thomas Gleixner 
Cc: Rik van Riel 
Cc: keesc...@google.com
Cc: Denys Vlasenko 
Cc: moritz.l...@iaik.tugraz.at
Cc: linux...@kvack.org
Cc: Peter Zijlstra 
Cc: Brian Gerst 
Cc: Dave Hansen 
Cc: hu...@google.com
Cc: daniel.gr...@iaik.tugraz.at
Cc: Borislav Petkov 
Cc: Andy Lutomirski 
Cc: Josh Poimboeuf 
Cc: michael.schw...@iaik.tugraz.at
Cc: Linus Torvalds 
Cc: richard.fell...@student.tugraz.at

---
 arch/x86/include/asm/pgtable.h |1 +
 arch/x86/mm/debug_pagetables.c |2 +-
 arch/x86/mm/dump_pagetables.c  |   30 +-
 3 files changed, 27 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -447,7 +447,7 @@ static inline bool is_hypervisor_range(i
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -460,7 +460,7 @@ static void ptdump_walk_pgd_level_core(s
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -498,13 +498,33 @@ static void ptdump_walk_pgd_level_core(s
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+static void ptdump_walk_user_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_KERNEL_PAGE_TABLE_ISOLATION
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   if (!static_cpu_has_bug(X86_BUG_CPU_SECURE_MODE_KPTI))
+   return;
+
+   pr_info("x86/mm: Checking user space page tables\n");
+   pgd = kernel_to_user_pgdp(pgd);
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_user_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)




[kernel-hardening][PATCH v3 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-04 Thread Jinbum Park
Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

v2 :
Fix a sender name of mail header, there was an mistake.
(from "jinb.park" to Jinbum Park)
Contents of patch-set are perfectly same.

v3 :
Take advantage of the existing pg_level and bits arrays
to check ro, nx prot.

jinb.park (3):
  arm: mm: dump: make page table dumping reusable
  arm: mm: dump: make the page table dumping seq_file optional
  arm: mm: dump: add checking for writable and executable pages

 arch/arm/Kconfig.debug|  33 +-
 arch/arm/include/asm/ptdump.h |  56 
 arch/arm/mm/Makefile  |   3 +-
 arch/arm/mm/dump.c| 144 +-
 arch/arm/mm/init.c|   2 +
 arch/arm/mm/ptdump_debugfs.c  |  34 ++
 6 files changed, 226 insertions(+), 46 deletions(-)
 create mode 100644 arch/arm/include/asm/ptdump.h
 create mode 100644 arch/arm/mm/ptdump_debugfs.c

-- 
1.9.1



[kernel-hardening][PATCH v3 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-04 Thread Jinbum Park
Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

v2 :
Fix a sender name of mail header, there was an mistake.
(from "jinb.park" to Jinbum Park)
Contents of patch-set are perfectly same.

v3 :
Take advantage of the existing pg_level and bits arrays
to check ro, nx prot.

jinb.park (3):
  arm: mm: dump: make page table dumping reusable
  arm: mm: dump: make the page table dumping seq_file optional
  arm: mm: dump: add checking for writable and executable pages

 arch/arm/Kconfig.debug|  33 +-
 arch/arm/include/asm/ptdump.h |  56 
 arch/arm/mm/Makefile  |   3 +-
 arch/arm/mm/dump.c| 144 +-
 arch/arm/mm/init.c|   2 +
 arch/arm/mm/ptdump_debugfs.c  |  34 ++
 6 files changed, 226 insertions(+), 46 deletions(-)
 create mode 100644 arch/arm/include/asm/ptdump.h
 create mode 100644 arch/arm/mm/ptdump_debugfs.c

-- 
1.9.1



[kernel-hardening][PATCH v2 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-01 Thread Jinbum Park
Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

v2 :
Fix a sender name of mail header, there was an mistake.
(from "jinb.park" to Jinbum Park)
Contents of patch-set are perfectly same.

Jinbum Park (3):
  arm: mm: dump: make page table dumping reusable
  arm: mm: dump: make the page table dumping seq_file optional
  arm: mm: dump: add checking for writable and executable pages

 arch/arm/Kconfig.debug|  33 +++-
 arch/arm/include/asm/ptdump.h |  56 ++
 arch/arm/mm/Makefile  |   3 +-
 arch/arm/mm/dump.c| 171 +++---
 arch/arm/mm/init.c|   2 +
 arch/arm/mm/ptdump_debugfs.c  |  34 +
 6 files changed, 253 insertions(+), 46 deletions(-)
 create mode 100644 arch/arm/include/asm/ptdump.h
 create mode 100644 arch/arm/mm/ptdump_debugfs.c

-- 
1.9.1



[kernel-hardening][PATCH v2 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-01 Thread Jinbum Park
Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

v2 :
Fix a sender name of mail header, there was an mistake.
(from "jinb.park" to Jinbum Park)
Contents of patch-set are perfectly same.

Jinbum Park (3):
  arm: mm: dump: make page table dumping reusable
  arm: mm: dump: make the page table dumping seq_file optional
  arm: mm: dump: add checking for writable and executable pages

 arch/arm/Kconfig.debug|  33 +++-
 arch/arm/include/asm/ptdump.h |  56 ++
 arch/arm/mm/Makefile  |   3 +-
 arch/arm/mm/dump.c| 171 +++---
 arch/arm/mm/init.c|   2 +
 arch/arm/mm/ptdump_debugfs.c  |  34 +
 6 files changed, 253 insertions(+), 46 deletions(-)
 create mode 100644 arch/arm/include/asm/ptdump.h
 create mode 100644 arch/arm/mm/ptdump_debugfs.c

-- 
1.9.1



[kernel-hardening][PATCH 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-01 Thread jinb.park
Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

Jinbum Park (3):
  arm: mm: dump: make page table dumping reusable
  arm: mm: dump: make the page table dumping seq_file optional
  arm: mm: dump: add checking for writable and executable pages

 arch/arm/Kconfig.debug|  33 +++-
 arch/arm/include/asm/ptdump.h |  56 ++
 arch/arm/mm/Makefile  |   3 +-
 arch/arm/mm/dump.c| 171 +++---
 arch/arm/mm/init.c|   2 +
 arch/arm/mm/ptdump_debugfs.c  |  34 +
 6 files changed, 253 insertions(+), 46 deletions(-)
 create mode 100644 arch/arm/include/asm/ptdump.h
 create mode 100644 arch/arm/mm/ptdump_debugfs.c

-- 
1.9.1



[kernel-hardening][PATCH 0/3] arm: Makes ptdump resuable and add WX page checking

2017-12-01 Thread jinb.park
Hi,

Page table dumping code for arm64-x86 is reusable,
and they have function for WX page checking.
But arm doesn't have that.

This path series are to makes ptdump reusable,
and add WX page checking for arm.
This is heavily based on arm64 version.

Jinbum Park (3):
  arm: mm: dump: make page table dumping reusable
  arm: mm: dump: make the page table dumping seq_file optional
  arm: mm: dump: add checking for writable and executable pages

 arch/arm/Kconfig.debug|  33 +++-
 arch/arm/include/asm/ptdump.h |  56 ++
 arch/arm/mm/Makefile  |   3 +-
 arch/arm/mm/dump.c| 171 +++---
 arch/arm/mm/init.c|   2 +
 arch/arm/mm/ptdump_debugfs.c  |  34 +
 6 files changed, 253 insertions(+), 46 deletions(-)
 create mode 100644 arch/arm/include/asm/ptdump.h
 create mode 100644 arch/arm/mm/ptdump_debugfs.c

-- 
1.9.1



Re: [patch V2 3/5] x86/dump_pagetables: Check KAISER shadow page table for WX pages

2017-11-27 Thread Dave Hansen
On 11/26/2017 03:14 PM, Thomas Gleixner wrote:
> +void ptdump_walk_shadow_pgd_level_checkwx(void)
> +{
> +#ifdef CONFIG_KAISER
> + pgd_t *pgd = (pgd_t *) _top_pgt;
> +
> + pr_info("x86/mm: Checking shadow page tables\n");
> + pgd += PTRS_PER_PGD;
> + ptdump_walk_pgd_level_core(NULL, pgd, true, false);
> +#endif
>  }

We have the kernel_to_shadow_pgdp() function to use instead of "pgd +=
PTRS_PER_PGD;".  Should it be used instead?

Otherwise, looks good to me.


Re: [patch V2 3/5] x86/dump_pagetables: Check KAISER shadow page table for WX pages

2017-11-27 Thread Dave Hansen
On 11/26/2017 03:14 PM, Thomas Gleixner wrote:
> +void ptdump_walk_shadow_pgd_level_checkwx(void)
> +{
> +#ifdef CONFIG_KAISER
> + pgd_t *pgd = (pgd_t *) _top_pgt;
> +
> + pr_info("x86/mm: Checking shadow page tables\n");
> + pgd += PTRS_PER_PGD;
> + ptdump_walk_pgd_level_core(NULL, pgd, true, false);
> +#endif
>  }

We have the kernel_to_shadow_pgdp() function to use instead of "pgd +=
PTRS_PER_PGD;".  Should it be used instead?

Otherwise, looks good to me.


[PATCH 21/24] x86/mm/dump_pagetables: Check Kaiser shadow page table for WX pages

2017-11-27 Thread Ingo Molnar
From: Thomas Gleixner <t...@linutronix.de>

ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the Kaiser shadow page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL.
Add the check for the shadow page table.

Signed-off-by: Thomas Gleixner <t...@linutronix.de>
Cc: Andy Lutomirski <l...@kernel.org>
Cc: Borislav Petkov <b...@alien8.de>
Cc: Brian Gerst <brge...@gmail.com>
Cc: Dave Hansen <dave.han...@linux.intel.com>
Cc: Denys Vlasenko <dvlas...@redhat.com>
Cc: Josh Poimboeuf <jpoim...@redhat.com>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Rik van Riel <r...@redhat.com>
Cc: daniel.gr...@iaik.tugraz.at
Cc: hu...@google.com
Cc: keesc...@google.com
Cc: linux...@kvack.org
Cc: michael.schw...@iaik.tugraz.at
Cc: moritz.l...@iaik.tugraz.at
Cc: richard.fell...@student.tugraz.at
Link: http://lkml.kernel.org/r/20171126232414.481903...@linutronix.de
Signed-off-by: Ingo Molnar <mi...@kernel.org>
---
 arch/x86/include/asm/pgtable.h |  1 +
 arch/x86/mm/debug_pagetables.c |  2 +-
 arch/x86/mm/dump_pagetables.c  | 27 ++-
 3 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 9cceaf6c0405..75d1dc090072 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD];
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c
index bfcffdf6c577..9b627b7eabd4 100644
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 5e3ac6fe6c9e..535ed1fe4897 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -447,7 +447,7 @@ static inline bool is_hypervisor_range(int idx)
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -460,7 +460,7 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, 
pgd_t *pgd,
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -498,13 +498,30 @@ static void ptdump_walk_pgd_level_core(struct seq_file 
*m, pgd_t *pgd,
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+void ptdump_walk_shadow_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_KAISER
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   pr_info("x86/mm: Checking shadow page tables\n");
+   pgd += PTRS_PER_PGD;
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_shadow_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)
-- 
2.14.1



[PATCH 21/24] x86/mm/dump_pagetables: Check Kaiser shadow page table for WX pages

2017-11-27 Thread Ingo Molnar
From: Thomas Gleixner 

ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the Kaiser shadow page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL.
Add the check for the shadow page table.

Signed-off-by: Thomas Gleixner 
Cc: Andy Lutomirski 
Cc: Borislav Petkov 
Cc: Brian Gerst 
Cc: Dave Hansen 
Cc: Denys Vlasenko 
Cc: Josh Poimboeuf 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Rik van Riel 
Cc: daniel.gr...@iaik.tugraz.at
Cc: hu...@google.com
Cc: keesc...@google.com
Cc: linux...@kvack.org
Cc: michael.schw...@iaik.tugraz.at
Cc: moritz.l...@iaik.tugraz.at
Cc: richard.fell...@student.tugraz.at
Link: http://lkml.kernel.org/r/20171126232414.481903...@linutronix.de
Signed-off-by: Ingo Molnar 
---
 arch/x86/include/asm/pgtable.h |  1 +
 arch/x86/mm/debug_pagetables.c |  2 +-
 arch/x86/mm/dump_pagetables.c  | 27 ++-
 3 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 9cceaf6c0405..75d1dc090072 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD];
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c
index bfcffdf6c577..9b627b7eabd4 100644
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index 5e3ac6fe6c9e..535ed1fe4897 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -447,7 +447,7 @@ static inline bool is_hypervisor_range(int idx)
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -460,7 +460,7 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, 
pgd_t *pgd,
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -498,13 +498,30 @@ static void ptdump_walk_pgd_level_core(struct seq_file 
*m, pgd_t *pgd,
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+void ptdump_walk_shadow_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_KAISER
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   pr_info("x86/mm: Checking shadow page tables\n");
+   pgd += PTRS_PER_PGD;
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_shadow_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)
-- 
2.14.1



[patch V2 3/5] x86/dump_pagetables: Check KAISER shadow page table for WX pages

2017-11-26 Thread Thomas Gleixner
ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the KAISER shadow page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL. 
Add the check for the shadow page table.

Signed-off-by: Thomas Gleixner <t...@linutronix.de>
---
 arch/x86/include/asm/pgtable.h |1 +
 arch/x86/mm/debug_pagetables.c |2 +-
 arch/x86/mm/dump_pagetables.c  |   27 ++-
 3 files changed, 24 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -447,7 +447,7 @@ static inline bool is_hypervisor_range(i
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -460,7 +460,7 @@ static void ptdump_walk_pgd_level_core(s
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -498,13 +498,30 @@ static void ptdump_walk_pgd_level_core(s
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+void ptdump_walk_shadow_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_KAISER
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   pr_info("x86/mm: Checking shadow page tables\n");
+   pgd += PTRS_PER_PGD;
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_shadow_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)




[patch V2 3/5] x86/dump_pagetables: Check KAISER shadow page table for WX pages

2017-11-26 Thread Thomas Gleixner
ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the KAISER shadow page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL. 
Add the check for the shadow page table.

Signed-off-by: Thomas Gleixner 
---
 arch/x86/include/asm/pgtable.h |1 +
 arch/x86/mm/debug_pagetables.c |2 +-
 arch/x86/mm/dump_pagetables.c  |   27 ++-
 3 files changed, 24 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -447,7 +447,7 @@ static inline bool is_hypervisor_range(i
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -460,7 +460,7 @@ static void ptdump_walk_pgd_level_core(s
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -498,13 +498,30 @@ static void ptdump_walk_pgd_level_core(s
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+void ptdump_walk_shadow_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_KAISER
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   pr_info("x86/mm: Checking shadow page tables\n");
+   pgd += PTRS_PER_PGD;
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_shadow_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)




[patch 2/4] x86/dump_pagetables: Check KAISER shadow page table for WX pages

2017-11-26 Thread Thomas Gleixner
ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the KAISER shadow page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL. 
Add the check for the shadow page table.

Signed-off-by: Thomas Gleixner <t...@linutronix.de>
---
 arch/x86/include/asm/pgtable.h |1 +
 arch/x86/mm/debug_pagetables.c |2 +-
 arch/x86/mm/dump_pagetables.c  |   27 ++-
 3 files changed, 24 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -447,7 +447,7 @@ static inline bool is_hypervisor_range(i
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -460,7 +460,7 @@ static void ptdump_walk_pgd_level_core(s
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -498,13 +498,30 @@ static void ptdump_walk_pgd_level_core(s
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+void ptdump_walk_shadow_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_KAISER
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   pr_info("x86/mm: Checking shadow page tables\n");
+   pgd += PTRS_PER_PGD;
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_shadow_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)




[patch 2/4] x86/dump_pagetables: Check KAISER shadow page table for WX pages

2017-11-26 Thread Thomas Gleixner
ptdump_walk_pgd_level_checkwx() checks the kernel page table for WX pages,
but does not check the KAISER shadow page table.

Restructure the code so that dmesg output is selected by an explicit
argument and not implicit via checking the pgd argument for !NULL. 
Add the check for the shadow page table.

Signed-off-by: Thomas Gleixner 
---
 arch/x86/include/asm/pgtable.h |1 +
 arch/x86/mm/debug_pagetables.c |2 +-
 arch/x86/mm/dump_pagetables.c  |   27 ++-
 3 files changed, 24 insertions(+), 6 deletions(-)

--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -28,6 +28,7 @@ extern pgd_t early_top_pgt[PTRS_PER_PGD]
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd);
 void ptdump_walk_pgd_level_checkwx(void);
 
 #ifdef CONFIG_DEBUG_WX
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -5,7 +5,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-   ptdump_walk_pgd_level(m, NULL);
+   ptdump_walk_pgd_level_debugfs(m, NULL);
return 0;
 }
 
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -447,7 +447,7 @@ static inline bool is_hypervisor_range(i
 }
 
 static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
-  bool checkwx)
+  bool checkwx, bool dmesg)
 {
 #ifdef CONFIG_X86_64
pgd_t *start = (pgd_t *) _top_pgt;
@@ -460,7 +460,7 @@ static void ptdump_walk_pgd_level_core(s
 
if (pgd) {
start = pgd;
-   st.to_dmesg = true;
+   st.to_dmesg = dmesg;
}
 
st.check_wx = checkwx;
@@ -498,13 +498,30 @@ static void ptdump_walk_pgd_level_core(s
 
 void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
 {
-   ptdump_walk_pgd_level_core(m, pgd, false);
+   ptdump_walk_pgd_level_core(m, pgd, false, true);
+}
+
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd)
+{
+   ptdump_walk_pgd_level_core(m, pgd, false, false);
+}
+EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
+
+void ptdump_walk_shadow_pgd_level_checkwx(void)
+{
+#ifdef CONFIG_KAISER
+   pgd_t *pgd = (pgd_t *) _top_pgt;
+
+   pr_info("x86/mm: Checking shadow page tables\n");
+   pgd += PTRS_PER_PGD;
+   ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+#endif
 }
-EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level);
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-   ptdump_walk_pgd_level_core(NULL, NULL, true);
+   ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+   ptdump_walk_shadow_pgd_level_checkwx();
 }
 
 static int __init pt_dump_init(void)




[RFC v4 05/10] S.A.R.A. WX Protection

2017-11-21 Thread Salvatore Mesoraca
Introduction of S.A.R.A. WX Protection.
It aims to improve user-space programs security by applying:
- W^X enforcement
- W!->X (once writable never executable) mprotect restriction
- Executable MMAP prevention

All of the above features can be enabled or disabled both system wide
or on a per executable basis through the use of configuration.
W^X enforcement works by blocking any memory allocation or mprotect
invocation with both the WRITE and the EXEC flags enabled.
W!->X restriction works by preventing any mprotect invocation that makes
executable any page that is flagged VM_MAYWRITE.
This feature can be configured separately for stack, heap and other
allocations.
Executable MMAP prevention works by preventing any new executable
allocation after the dynamic libraries have been loaded. It works under the
assumption that, when the dynamic libraries have been finished loading, the
RELRO section will be marked read only.

Parts of WX Protection are inspired by some of the features available in
PaX according to my understanding of the code. Changes or omissions from
the original code are mine and don't reflect the original grsecurity/PaX
code.

Signed-off-by: Salvatore Mesoraca <s.mesorac...@gmail.com>
---
 security/sara/Kconfig  |  74 
 security/sara/Makefile |   1 +
 security/sara/include/utils.h  |  11 +
 security/sara/include/wxprot.h |  27 ++
 security/sara/main.c   |   6 +
 security/sara/wxprot.c | 741 +
 6 files changed, 860 insertions(+)
 create mode 100644 security/sara/include/wxprot.h
 create mode 100644 security/sara/wxprot.c

diff --git a/security/sara/Kconfig b/security/sara/Kconfig
index 0456220..62dfe4f 100644
--- a/security/sara/Kconfig
+++ b/security/sara/Kconfig
@@ -38,3 +38,77 @@ config SECURITY_SARA_NO_RUNTIME_ENABLE
 
  If unsure, answer Y.
 
+config SECURITY_SARA_WXPROT
+   bool "WX Protection: W^X and W!->X protections"
+   depends on SECURITY_SARA
+   default y
+   help
+ WX Protection aims to improve user-space programs security by 
applying:
+   - W^X memory restriction
+   - W!->X (once writable never executable) mprotect restriction
+   - Executable MMAP prevention
+ See Documentation/admin-guide/LSM/SARA.rst. for further information.
+
+ If unsure, answer Y.
+
+choice
+   prompt "Default action for W^X and W!->X protections"
+   depends on SECURITY_SARA
+   depends on SECURITY_SARA_WXPROT
+   default SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+
+help
+     Choose the default behaviour of WX Protection when no config
+ rule matches or no rule is loaded.
+ For further information on available flags and their meaning
+ see Documentation/admin-guide/LSM/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+   bool "Protections enabled but not enforced."
+   help
+ All features enabled except "Executable MMAP prevention",
+ verbose reporting, but no actual enforce: it just complains.
+ Its numeric value is 0x3f, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
+   bool "Full protection, verbose."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced with verbose reporting.
+ Its numeric value is 0x2f, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE
+   bool "Full protection, quiet."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced quietly.
+ Its numeric value is 0xf, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_NONE
+   bool "No protection at all."
+   help
+ All features disabled.
+ Its numeric value is 0, for more information see
+     Documentation/admin-guide/LSM/SARA.rst.
+endchoice
+
+config SECURITY_SARA_WXPROT_DISABLED
+   bool "WX protection will be disabled at boot."
+   depends on SECURITY_SARA_WXPROT
+   default n
+   help
+ If you say Y here WX protection won't be enabled at startup. You can
+ override this option via user-space utilities or at boot time via
+ "sara.wxprot_enabled=[0|1]" kernel parameter.
+
+ If unsure, answer N.
+
+config SECURITY_SARA_WXPROT

[RFC v4 05/10] S.A.R.A. WX Protection

2017-11-21 Thread Salvatore Mesoraca
Introduction of S.A.R.A. WX Protection.
It aims to improve user-space programs security by applying:
- W^X enforcement
- W!->X (once writable never executable) mprotect restriction
- Executable MMAP prevention

All of the above features can be enabled or disabled both system wide
or on a per executable basis through the use of configuration.
W^X enforcement works by blocking any memory allocation or mprotect
invocation with both the WRITE and the EXEC flags enabled.
W!->X restriction works by preventing any mprotect invocation that makes
executable any page that is flagged VM_MAYWRITE.
This feature can be configured separately for stack, heap and other
allocations.
Executable MMAP prevention works by preventing any new executable
allocation after the dynamic libraries have been loaded. It works under the
assumption that, when the dynamic libraries have been finished loading, the
RELRO section will be marked read only.

Parts of WX Protection are inspired by some of the features available in
PaX according to my understanding of the code. Changes or omissions from
the original code are mine and don't reflect the original grsecurity/PaX
code.

Signed-off-by: Salvatore Mesoraca 
---
 security/sara/Kconfig  |  74 
 security/sara/Makefile |   1 +
 security/sara/include/utils.h  |  11 +
 security/sara/include/wxprot.h |  27 ++
 security/sara/main.c   |   6 +
 security/sara/wxprot.c | 741 +
 6 files changed, 860 insertions(+)
 create mode 100644 security/sara/include/wxprot.h
 create mode 100644 security/sara/wxprot.c

diff --git a/security/sara/Kconfig b/security/sara/Kconfig
index 0456220..62dfe4f 100644
--- a/security/sara/Kconfig
+++ b/security/sara/Kconfig
@@ -38,3 +38,77 @@ config SECURITY_SARA_NO_RUNTIME_ENABLE
 
  If unsure, answer Y.
 
+config SECURITY_SARA_WXPROT
+   bool "WX Protection: W^X and W!->X protections"
+   depends on SECURITY_SARA
+   default y
+       help
+ WX Protection aims to improve user-space programs security by 
applying:
+   - W^X memory restriction
+   - W!->X (once writable never executable) mprotect restriction
+   - Executable MMAP prevention
+ See Documentation/admin-guide/LSM/SARA.rst. for further information.
+
+ If unsure, answer Y.
+
+choice
+   prompt "Default action for W^X and W!->X protections"
+   depends on SECURITY_SARA
+   depends on SECURITY_SARA_WXPROT
+   default SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+
+help
+     Choose the default behaviour of WX Protection when no config
+ rule matches or no rule is loaded.
+ For further information on available flags and their meaning
+ see Documentation/admin-guide/LSM/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+   bool "Protections enabled but not enforced."
+   help
+ All features enabled except "Executable MMAP prevention",
+ verbose reporting, but no actual enforce: it just complains.
+ Its numeric value is 0x3f, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
+   bool "Full protection, verbose."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced with verbose reporting.
+ Its numeric value is 0x2f, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE
+   bool "Full protection, quiet."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced quietly.
+ Its numeric value is 0xf, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_NONE
+   bool "No protection at all."
+   help
+ All features disabled.
+ Its numeric value is 0, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+endchoice
+
+config SECURITY_SARA_WXPROT_DISABLED
+   bool "WX protection will be disabled at boot."
+   depends on SECURITY_SARA_WXPROT
+   default n
+   help
+ If you say Y here WX protection won't be enabled at startup. You can
+ override this option via user-space utilities or at boot time via
+ "sara.wxprot_enabled=[0|1]" kernel parameter.
+
+ If unsure, answer N.
+
+config SECURITY_SARA_WXPROT_DEFAU

[RFC v4 09/10] S.A.R.A. WX Protection procattr interface

2017-11-21 Thread Salvatore Mesoraca
This allow threads to get current WX Protection flags for themselves or
for other threads (if they have CAP_MAC_ADMIN).
It also allow a thread to set itself flags to a stricter set of rules than
the current one.
Via a new wxprot flag (SARA_WXP_FORCE_WXORX) is it possible to ask the
kernel to rescan the memory and remove the VM_WRITE flag from any area
that is marked both writable and executable.
Protections that prevent the runtime creation of executable code
can be troublesome for all those programs that actually need to do it
e.g. programs shipping with a JIT compiler built-in.
This feature can be use to run the JIT compiler with few restrictions while
enforcing full WX Protection in the rest of the program.
To simplify access to this interface a CC0 licensed library is available
here: https://github.com/smeso/libsara

Signed-off-by: Salvatore Mesoraca <s.mesorac...@gmail.com>
---
 security/sara/wxprot.c | 150 +
 1 file changed, 150 insertions(+)

diff --git a/security/sara/wxprot.c b/security/sara/wxprot.c
index 68203f2..c14ad27 100644
--- a/security/sara/wxprot.c
+++ b/security/sara/wxprot.c
@@ -12,6 +12,7 @@
 #ifdef CONFIG_SECURITY_SARA_WXPROT
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -39,6 +40,7 @@
 #define SARA_WXP_COMPLAIN  0x0010
 #define SARA_WXP_VERBOSE   0x0020
 #define SARA_WXP_MMAP  0x0040
+#define SARA_WXP_FORCE_WXORX   0x0080
 #define SARA_WXP_EMUTRAMP  0x0100
 #define SARA_WXP_TRANSFER  0x0200
 #define SARA_WXP_NONE  0x
@@ -487,6 +489,152 @@ static int sara_pagefault_handler(struct pt_regs *regs,
 }
 #endif
 
+static int sara_getprocattr(struct task_struct *p, char *name, char **value)
+{
+   int ret;
+   u16 flags;
+   char *buf;
+
+   ret = -EINVAL;
+   if (strcmp(name, "wxprot") != 0)
+   goto out;
+
+   ret = -EACCES;
+   if (unlikely(current != p &&
+!capable(CAP_MAC_ADMIN)))
+   goto out;
+
+   ret = -ENOMEM;
+   buf = kzalloc(8, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto out;
+
+   if (!sara_enabled || !wxprot_enabled) {
+   flags = 0x0;
+   } else {
+   rcu_read_lock();
+   flags = get_sara_wxp_flags(__task_cred(p));
+   rcu_read_unlock();
+   }
+
+   snprintf(buf, 8, "0x%04x\n", flags);
+   ret = strlen(buf);
+   *value = buf;
+
+out:
+   return ret;
+}
+
+static int sara_setprocattr(const char *name, void *value, size_t size)
+{
+   int ret;
+   struct vm_area_struct *vma;
+   struct cred *new = prepare_creds();
+   u16 cur_flags;
+   u16 req_flags;
+   char *buf = NULL;
+
+   ret = -EINVAL;
+   if (!sara_enabled || !wxprot_enabled)
+   goto error;
+   if (unlikely(new == NULL))
+   return -ENOMEM;
+   if (strcmp(name, "wxprot") != 0)
+   goto error;
+   if (unlikely(value == NULL || size == 0 || size > 7))
+   goto error;
+   ret = -ENOMEM;
+   buf = kmalloc(size+1, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto error;
+   buf[size] = '\0';
+   memcpy(buf, value, size);
+   ret = -EINVAL;
+   if (unlikely(strlen(buf) != size))
+   goto error;
+   if (unlikely(kstrtou16(buf, 0, _flags) != 0))
+   goto error;
+   /*
+* SARA_WXP_FORCE_WXORX is a procattr only flag with a special
+* meaning and it isn't recognized by are_flags_valid
+*/
+   if (unlikely(!are_flags_valid(req_flags & ~SARA_WXP_FORCE_WXORX)))
+   goto error;
+   /*
+* Extra checks on requested flags:
+*   - SARA_WXP_FORCE_WXORX requires SARA_WXP_WXORX
+*   - SARA_WXP_MMAP can only be activated if the program
+* has a relro section
+*   - COMPLAIN mode can only be requested if it was already
+* on (procattr can only be used to make protection stricter)
+*   - EMUTRAMP can only be activated if it was already on or
+* if MPROTECT and WXORX weren't already on (procattr can
+* only be used to make protection stricter)
+*   - VERBOSITY request is ignored
+*/
+   if (unlikely(req_flags & SARA_WXP_FORCE_WXORX &&
+!(req_flags & SARA_WXP_WXORX)))
+   goto error;
+   if (unlikely(!get_current_sara_relro_page_found() &&
+req_flags & SARA_WXP_MMAP))
+   goto error;
+   cur_flags = get_current_sara_wxp_flags();
+   if (unlikely((req_flags & SARA_WXP_COMPLAIN) &&
+!(cur_flags & SARA_WXP_COMPLAIN)))
+   goto error;
+   if (unlikely((req_flags & SARA_WXP_EMUTRAMP) &&
+!(cur_flags & SARA_WXP_EMUTRA

[RFC v4 09/10] S.A.R.A. WX Protection procattr interface

2017-11-21 Thread Salvatore Mesoraca
This allow threads to get current WX Protection flags for themselves or
for other threads (if they have CAP_MAC_ADMIN).
It also allow a thread to set itself flags to a stricter set of rules than
the current one.
Via a new wxprot flag (SARA_WXP_FORCE_WXORX) is it possible to ask the
kernel to rescan the memory and remove the VM_WRITE flag from any area
that is marked both writable and executable.
Protections that prevent the runtime creation of executable code
can be troublesome for all those programs that actually need to do it
e.g. programs shipping with a JIT compiler built-in.
This feature can be use to run the JIT compiler with few restrictions while
enforcing full WX Protection in the rest of the program.
To simplify access to this interface a CC0 licensed library is available
here: https://github.com/smeso/libsara

Signed-off-by: Salvatore Mesoraca 
---
 security/sara/wxprot.c | 150 +
 1 file changed, 150 insertions(+)

diff --git a/security/sara/wxprot.c b/security/sara/wxprot.c
index 68203f2..c14ad27 100644
--- a/security/sara/wxprot.c
+++ b/security/sara/wxprot.c
@@ -12,6 +12,7 @@
 #ifdef CONFIG_SECURITY_SARA_WXPROT
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -39,6 +40,7 @@
 #define SARA_WXP_COMPLAIN  0x0010
 #define SARA_WXP_VERBOSE   0x0020
 #define SARA_WXP_MMAP  0x0040
+#define SARA_WXP_FORCE_WXORX   0x0080
 #define SARA_WXP_EMUTRAMP  0x0100
 #define SARA_WXP_TRANSFER  0x0200
 #define SARA_WXP_NONE  0x
@@ -487,6 +489,152 @@ static int sara_pagefault_handler(struct pt_regs *regs,
 }
 #endif
 
+static int sara_getprocattr(struct task_struct *p, char *name, char **value)
+{
+   int ret;
+   u16 flags;
+   char *buf;
+
+   ret = -EINVAL;
+   if (strcmp(name, "wxprot") != 0)
+   goto out;
+
+   ret = -EACCES;
+   if (unlikely(current != p &&
+!capable(CAP_MAC_ADMIN)))
+   goto out;
+
+   ret = -ENOMEM;
+   buf = kzalloc(8, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto out;
+
+   if (!sara_enabled || !wxprot_enabled) {
+   flags = 0x0;
+   } else {
+   rcu_read_lock();
+   flags = get_sara_wxp_flags(__task_cred(p));
+   rcu_read_unlock();
+   }
+
+   snprintf(buf, 8, "0x%04x\n", flags);
+   ret = strlen(buf);
+   *value = buf;
+
+out:
+   return ret;
+}
+
+static int sara_setprocattr(const char *name, void *value, size_t size)
+{
+   int ret;
+   struct vm_area_struct *vma;
+   struct cred *new = prepare_creds();
+   u16 cur_flags;
+   u16 req_flags;
+   char *buf = NULL;
+
+   ret = -EINVAL;
+   if (!sara_enabled || !wxprot_enabled)
+   goto error;
+   if (unlikely(new == NULL))
+   return -ENOMEM;
+   if (strcmp(name, "wxprot") != 0)
+   goto error;
+   if (unlikely(value == NULL || size == 0 || size > 7))
+   goto error;
+   ret = -ENOMEM;
+   buf = kmalloc(size+1, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto error;
+   buf[size] = '\0';
+   memcpy(buf, value, size);
+   ret = -EINVAL;
+   if (unlikely(strlen(buf) != size))
+   goto error;
+   if (unlikely(kstrtou16(buf, 0, _flags) != 0))
+   goto error;
+   /*
+* SARA_WXP_FORCE_WXORX is a procattr only flag with a special
+* meaning and it isn't recognized by are_flags_valid
+*/
+   if (unlikely(!are_flags_valid(req_flags & ~SARA_WXP_FORCE_WXORX)))
+   goto error;
+   /*
+* Extra checks on requested flags:
+*   - SARA_WXP_FORCE_WXORX requires SARA_WXP_WXORX
+*   - SARA_WXP_MMAP can only be activated if the program
+* has a relro section
+*   - COMPLAIN mode can only be requested if it was already
+* on (procattr can only be used to make protection stricter)
+*   - EMUTRAMP can only be activated if it was already on or
+* if MPROTECT and WXORX weren't already on (procattr can
+* only be used to make protection stricter)
+*   - VERBOSITY request is ignored
+*/
+   if (unlikely(req_flags & SARA_WXP_FORCE_WXORX &&
+!(req_flags & SARA_WXP_WXORX)))
+   goto error;
+   if (unlikely(!get_current_sara_relro_page_found() &&
+req_flags & SARA_WXP_MMAP))
+   goto error;
+   cur_flags = get_current_sara_wxp_flags();
+   if (unlikely((req_flags & SARA_WXP_COMPLAIN) &&
+!(cur_flags & SARA_WXP_COMPLAIN)))
+   goto error;
+   if (unlikely((req_flags & SARA_WXP_EMUTRAMP) &&
+!(cur_flags & SARA_WXP_EMUTRAMP) &&
+   

[RFC v3 5/9] S.A.R.A. WX Protection

2017-09-11 Thread Salvatore Mesoraca
Introduction of S.A.R.A. WX Protection.
It aims to improve user-space programs security by applying:
- W^X enforcement
- W!->X (once writable never executable) mprotect restriction
- Executable MMAP prevention

All of the above features can be enabled or disabled both system wide
or on a per executable basis through the use of configuration.
W^X enforcement works by blocking any memory allocation or mprotect
invocation with both the WRITE and the EXEC flags enabled.
W!->X restriction works by preventing any mprotect invocation that makes
executable any page that is flagged VM_MAYWRITE.
This feature can be configured separately for stack, heap and other
allocations.
Executable MMAP prevention works by preventing any new executable
allocation after the dynamic libraries have been loaded. It works under the
assumption that, when the dynamic libraries have been finished loading, the
RELRO section will be marked read only.

Parts of WX Protection are inspired by some of the features available in
PaX according to my understanding of the code. Changes or omissions from
the original code are mine and don't reflect the original grsecurity/PaX
code.

Signed-off-by: Salvatore Mesoraca <s.mesorac...@gmail.com>
---
 security/sara/Kconfig  |  75 +
 security/sara/Makefile |   1 +
 security/sara/include/utils.h  |  11 +
 security/sara/include/wxprot.h |  27 ++
 security/sara/main.c   |   6 +
 security/sara/wxprot.c | 683 +
 6 files changed, 803 insertions(+)
 create mode 100644 security/sara/include/wxprot.h
 create mode 100644 security/sara/wxprot.c

diff --git a/security/sara/Kconfig b/security/sara/Kconfig
index 978fc48..3ae2ecd 100644
--- a/security/sara/Kconfig
+++ b/security/sara/Kconfig
@@ -40,4 +40,79 @@ config SECURITY_SARA_NO_RUNTIME_ENABLE
 
  If unsure, answer Y.
 
+config SECURITY_SARA_WXPROT
+   bool "WX Protection: W^X and W!->X protections"
+   depends on SECURITY_SARA
+   default y
+   help
+ WX Protection aims to improve user-space programs security by 
applying:
+   - W^X memory restriction
+   - W!->X (once writable never executable) mprotect restriction
+   - Executable MMAP prevention
+ See Documentation/admin-guide/LSM/SARA.rst. for further information.
+
+ If unsure, answer Y.
+
+choice
+   prompt "Default action for W^X and W!->X protections"
+   depends on SECURITY_SARA
+   depends on SECURITY_SARA_WXPROT
+   default SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+
+help
+     Choose the default behaviour of WX Protection when no config
+ rule matches or no rule is loaded.
+ For further information on available flags and their meaning
+ see Documentation/admin-guide/LSM/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+   bool "Protections enabled but not enforced."
+   help
+ All features enabled except "Executable MMAP prevention",
+ verbose reporting, but no actual enforce: it just complains.
+ Its numeric value is 0x3f, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
+   bool "Full protection, verbose."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced with verbose reporting.
+ Its numeric value is 0x2f, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE
+   bool "Full protection, quiet."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced quietly.
+ Its numeric value is 0xf, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_NONE
+   bool "No protection at all."
+   help
+ All features disabled.
+ Its numeric value is 0, for more information see
+     Documentation/admin-guide/LSM/SARA.rst.
+endchoice
+
+config SECURITY_SARA_WXPROT_DISABLED
+   bool "WX protection will be disabled at boot."
+   depends on SECURITY_SARA_WXPROT
+   default n
+   help
+ If you say Y here WX protection won't be enabled at startup. You can
+ override this option via user-space utilities or at boot time via
+ "sara_wxprot=[0|1]" kernel parameter.
+
+ If unsure, answer N.
+
+config SECURITY_SARA_WXPROT

[RFC v3 5/9] S.A.R.A. WX Protection

2017-09-11 Thread Salvatore Mesoraca
Introduction of S.A.R.A. WX Protection.
It aims to improve user-space programs security by applying:
- W^X enforcement
- W!->X (once writable never executable) mprotect restriction
- Executable MMAP prevention

All of the above features can be enabled or disabled both system wide
or on a per executable basis through the use of configuration.
W^X enforcement works by blocking any memory allocation or mprotect
invocation with both the WRITE and the EXEC flags enabled.
W!->X restriction works by preventing any mprotect invocation that makes
executable any page that is flagged VM_MAYWRITE.
This feature can be configured separately for stack, heap and other
allocations.
Executable MMAP prevention works by preventing any new executable
allocation after the dynamic libraries have been loaded. It works under the
assumption that, when the dynamic libraries have been finished loading, the
RELRO section will be marked read only.

Parts of WX Protection are inspired by some of the features available in
PaX according to my understanding of the code. Changes or omissions from
the original code are mine and don't reflect the original grsecurity/PaX
code.

Signed-off-by: Salvatore Mesoraca 
---
 security/sara/Kconfig  |  75 +
 security/sara/Makefile |   1 +
 security/sara/include/utils.h  |  11 +
 security/sara/include/wxprot.h |  27 ++
 security/sara/main.c   |   6 +
 security/sara/wxprot.c | 683 +
 6 files changed, 803 insertions(+)
 create mode 100644 security/sara/include/wxprot.h
 create mode 100644 security/sara/wxprot.c

diff --git a/security/sara/Kconfig b/security/sara/Kconfig
index 978fc48..3ae2ecd 100644
--- a/security/sara/Kconfig
+++ b/security/sara/Kconfig
@@ -40,4 +40,79 @@ config SECURITY_SARA_NO_RUNTIME_ENABLE
 
  If unsure, answer Y.
 
+config SECURITY_SARA_WXPROT
+   bool "WX Protection: W^X and W!->X protections"
+   depends on SECURITY_SARA
+   default y
+       help
+ WX Protection aims to improve user-space programs security by 
applying:
+   - W^X memory restriction
+   - W!->X (once writable never executable) mprotect restriction
+   - Executable MMAP prevention
+ See Documentation/admin-guide/LSM/SARA.rst. for further information.
+
+ If unsure, answer Y.
+
+choice
+   prompt "Default action for W^X and W!->X protections"
+   depends on SECURITY_SARA
+   depends on SECURITY_SARA_WXPROT
+   default SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+
+help
+     Choose the default behaviour of WX Protection when no config
+ rule matches or no rule is loaded.
+ For further information on available flags and their meaning
+ see Documentation/admin-guide/LSM/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+   bool "Protections enabled but not enforced."
+   help
+ All features enabled except "Executable MMAP prevention",
+ verbose reporting, but no actual enforce: it just complains.
+ Its numeric value is 0x3f, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
+   bool "Full protection, verbose."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced with verbose reporting.
+ Its numeric value is 0x2f, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE
+   bool "Full protection, quiet."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced quietly.
+ Its numeric value is 0xf, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_NONE
+   bool "No protection at all."
+   help
+ All features disabled.
+ Its numeric value is 0, for more information see
+ Documentation/admin-guide/LSM/SARA.rst.
+endchoice
+
+config SECURITY_SARA_WXPROT_DISABLED
+   bool "WX protection will be disabled at boot."
+   depends on SECURITY_SARA_WXPROT
+   default n
+   help
+ If you say Y here WX protection won't be enabled at startup. You can
+ override this option via user-space utilities or at boot time via
+ "sara_wxprot=[0|1]" kernel parameter.
+
+ If unsure, answer N.
+
+config SECURITY_SARA_WXPROT_DEFAU

[RFC v3 9/9] S.A.R.A. WX Protection procattr interface

2017-09-11 Thread Salvatore Mesoraca
This allow threads to get current WX Protection flags for themselves or
for other threads (if they have CAP_MAC_ADMIN).
It also allow a thread to set itself flags to a stricter set of rules than
the current one.
Via a new wxprot flag (SARA_WXP_FORCE_WXORX) is it possible to ask the
kernel to rescan the memory and remove the VM_WRITE flag from any area
that is marked both writable and executable.
Protections that prevent the runtime creation of executable code
can be troublesome for all those programs that actually need to do it
e.g. programs shipping with a JIT compiler built-in.
This feature can be use to run the JIT compiler with few restrictions while
enforcing full WX Protection in the rest of the program.
To simplify access to this interface a CC0 licensed library is available
here: https://github.com/smeso/libsara

Signed-off-by: Salvatore Mesoraca <s.mesorac...@gmail.com>
---
 security/sara/wxprot.c | 150 +
 1 file changed, 150 insertions(+)

diff --git a/security/sara/wxprot.c b/security/sara/wxprot.c
index d360833..afc4e13 100644
--- a/security/sara/wxprot.c
+++ b/security/sara/wxprot.c
@@ -12,6 +12,7 @@
 #ifdef CONFIG_SECURITY_SARA_WXPROT
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -43,6 +44,7 @@
 #define SARA_WXP_COMPLAIN  0x0010
 #define SARA_WXP_VERBOSE   0x0020
 #define SARA_WXP_MMAP  0x0040
+#define SARA_WXP_FORCE_WXORX   0x0080
 #define SARA_WXP_EMUTRAMP  0x0100
 #define SARA_WXP_TRANSFER  0x0200
 #define SARA_WXP_NONE  0x
@@ -540,6 +542,152 @@ static inline int sara_pagefault_handler_x86_64(struct 
pt_regs *regs)
 
 #endif /* CONFIG_SECURITY_SARA_WXPROT_EMUTRAMP */
 
+static int sara_getprocattr(struct task_struct *p, char *name, char **value)
+{
+   int ret;
+   u16 flags;
+   char *buf;
+
+   ret = -EINVAL;
+   if (strcmp(name, "wxprot") != 0)
+   goto out;
+
+   ret = -EACCES;
+   if (unlikely(current != p &&
+!capable(CAP_MAC_ADMIN)))
+   goto out;
+
+   ret = -ENOMEM;
+   buf = kzalloc(8, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto out;
+
+   if (!sara_enabled || !wxprot_enabled) {
+   flags = 0x0;
+   } else {
+   rcu_read_lock();
+   flags = get_sara_wxp_flags(__task_cred(p));
+   rcu_read_unlock();
+   }
+
+   snprintf(buf, 8, "0x%04x\n", flags);
+   ret = strlen(buf);
+   *value = buf;
+
+out:
+   return ret;
+}
+
+static int sara_setprocattr(const char *name, void *value, size_t size)
+{
+   int ret;
+   struct vm_area_struct *vma;
+   struct cred *new = prepare_creds();
+   u16 cur_flags;
+   u16 req_flags;
+   char *buf = NULL;
+
+   ret = -EINVAL;
+   if (!sara_enabled || !wxprot_enabled)
+   goto error;
+   if (unlikely(new == NULL))
+   return -ENOMEM;
+   if (strcmp(name, "wxprot") != 0)
+   goto error;
+   if (unlikely(value == NULL || size == 0 || size > 7))
+   goto error;
+   ret = -ENOMEM;
+   buf = kmalloc(size+1, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto error;
+   buf[size] = '\0';
+   memcpy(buf, value, size);
+   ret = -EINVAL;
+   if (unlikely(strlen(buf) != size))
+   goto error;
+   if (unlikely(kstrtou16(buf, 16, _flags) != 0))
+   goto error;
+   /*
+* SARA_WXP_FORCE_WXORX is a procattr only flag with a special
+* meaning and it isn't recognized by are_flags_valid
+*/
+   if (unlikely(!are_flags_valid(req_flags & ~SARA_WXP_FORCE_WXORX)))
+   goto error;
+   /*
+* Extra checks on requested flags:
+*   - SARA_WXP_FORCE_WXORX requires SARA_WXP_WXORX
+*   - SARA_WXP_MMAP can only be activated if the program
+* has a relro section
+*   - COMPLAIN mode can only be requested if it was already
+* on (procattr can only be used to make protection stricter)
+*   - EMUTRAMP can only be activated if it was already on or
+* if MPROTECT and WXORX weren't already on (procattr can
+* only be used to make protection stricter)
+*   - VERBOSITY request is ignored
+*/
+   if (unlikely(req_flags & SARA_WXP_FORCE_WXORX &&
+!(req_flags & SARA_WXP_WXORX)))
+   goto error;
+   if (unlikely(!get_current_sara_relro_page_found() &&
+req_flags & SARA_WXP_MMAP))
+   goto error;
+   cur_flags = get_current_sara_wxp_flags();
+   if (unlikely((req_flags & SARA_WXP_COMPLAIN) &&
+!(cur_flags & SARA_WXP_COMPLAIN)))
+   goto error;
+   if (unlikely((req_flags & SARA_WXP_EM

[RFC v3 9/9] S.A.R.A. WX Protection procattr interface

2017-09-11 Thread Salvatore Mesoraca
This allow threads to get current WX Protection flags for themselves or
for other threads (if they have CAP_MAC_ADMIN).
It also allow a thread to set itself flags to a stricter set of rules than
the current one.
Via a new wxprot flag (SARA_WXP_FORCE_WXORX) is it possible to ask the
kernel to rescan the memory and remove the VM_WRITE flag from any area
that is marked both writable and executable.
Protections that prevent the runtime creation of executable code
can be troublesome for all those programs that actually need to do it
e.g. programs shipping with a JIT compiler built-in.
This feature can be use to run the JIT compiler with few restrictions while
enforcing full WX Protection in the rest of the program.
To simplify access to this interface a CC0 licensed library is available
here: https://github.com/smeso/libsara

Signed-off-by: Salvatore Mesoraca 
---
 security/sara/wxprot.c | 150 +
 1 file changed, 150 insertions(+)

diff --git a/security/sara/wxprot.c b/security/sara/wxprot.c
index d360833..afc4e13 100644
--- a/security/sara/wxprot.c
+++ b/security/sara/wxprot.c
@@ -12,6 +12,7 @@
 #ifdef CONFIG_SECURITY_SARA_WXPROT
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -43,6 +44,7 @@
 #define SARA_WXP_COMPLAIN  0x0010
 #define SARA_WXP_VERBOSE   0x0020
 #define SARA_WXP_MMAP  0x0040
+#define SARA_WXP_FORCE_WXORX   0x0080
 #define SARA_WXP_EMUTRAMP  0x0100
 #define SARA_WXP_TRANSFER  0x0200
 #define SARA_WXP_NONE  0x
@@ -540,6 +542,152 @@ static inline int sara_pagefault_handler_x86_64(struct 
pt_regs *regs)
 
 #endif /* CONFIG_SECURITY_SARA_WXPROT_EMUTRAMP */
 
+static int sara_getprocattr(struct task_struct *p, char *name, char **value)
+{
+   int ret;
+   u16 flags;
+   char *buf;
+
+   ret = -EINVAL;
+   if (strcmp(name, "wxprot") != 0)
+   goto out;
+
+   ret = -EACCES;
+   if (unlikely(current != p &&
+!capable(CAP_MAC_ADMIN)))
+   goto out;
+
+   ret = -ENOMEM;
+   buf = kzalloc(8, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto out;
+
+   if (!sara_enabled || !wxprot_enabled) {
+   flags = 0x0;
+   } else {
+   rcu_read_lock();
+   flags = get_sara_wxp_flags(__task_cred(p));
+   rcu_read_unlock();
+   }
+
+   snprintf(buf, 8, "0x%04x\n", flags);
+   ret = strlen(buf);
+   *value = buf;
+
+out:
+   return ret;
+}
+
+static int sara_setprocattr(const char *name, void *value, size_t size)
+{
+   int ret;
+   struct vm_area_struct *vma;
+   struct cred *new = prepare_creds();
+   u16 cur_flags;
+   u16 req_flags;
+   char *buf = NULL;
+
+   ret = -EINVAL;
+   if (!sara_enabled || !wxprot_enabled)
+   goto error;
+   if (unlikely(new == NULL))
+   return -ENOMEM;
+   if (strcmp(name, "wxprot") != 0)
+   goto error;
+   if (unlikely(value == NULL || size == 0 || size > 7))
+   goto error;
+   ret = -ENOMEM;
+   buf = kmalloc(size+1, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto error;
+   buf[size] = '\0';
+   memcpy(buf, value, size);
+   ret = -EINVAL;
+   if (unlikely(strlen(buf) != size))
+   goto error;
+   if (unlikely(kstrtou16(buf, 16, _flags) != 0))
+   goto error;
+   /*
+* SARA_WXP_FORCE_WXORX is a procattr only flag with a special
+* meaning and it isn't recognized by are_flags_valid
+*/
+   if (unlikely(!are_flags_valid(req_flags & ~SARA_WXP_FORCE_WXORX)))
+   goto error;
+   /*
+* Extra checks on requested flags:
+*   - SARA_WXP_FORCE_WXORX requires SARA_WXP_WXORX
+*   - SARA_WXP_MMAP can only be activated if the program
+* has a relro section
+*   - COMPLAIN mode can only be requested if it was already
+* on (procattr can only be used to make protection stricter)
+*   - EMUTRAMP can only be activated if it was already on or
+* if MPROTECT and WXORX weren't already on (procattr can
+* only be used to make protection stricter)
+*   - VERBOSITY request is ignored
+*/
+   if (unlikely(req_flags & SARA_WXP_FORCE_WXORX &&
+!(req_flags & SARA_WXP_WXORX)))
+   goto error;
+   if (unlikely(!get_current_sara_relro_page_found() &&
+req_flags & SARA_WXP_MMAP))
+   goto error;
+   cur_flags = get_current_sara_wxp_flags();
+   if (unlikely((req_flags & SARA_WXP_COMPLAIN) &&
+!(cur_flags & SARA_WXP_COMPLAIN)))
+   goto error;
+   if (unlikely((req_flags & SARA_WXP_EMUTRAMP) &&
+   

Re: [RFC v2 5/9] S.A.R.A. WX Protection

2017-06-29 Thread Salvatore Mesoraca
2017-06-28 1:04 GMT+02:00 Kees Cook :
> On Thu, Jun 15, 2017 at 9:42 AM, Salvatore Mesoraca
>  wrote:
>> +static int sara_check_vmflags(vm_flags_t vm_flags)
>> +{
>> +   u16 sara_wxp_flags = get_current_sara_wxp_flags();
>> +
>> +   if (sara_enabled && wxprot_enabled) {
>> +   if (sara_wxp_flags & SARA_WXP_WXORX &&
>> +   vm_flags & VM_WRITE &&
>> +   vm_flags & VM_EXEC) {
>> +   if ((sara_wxp_flags & SARA_WXP_VERBOSE))
>> +   pr_wxp("W^X");
>> +   if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
>> +   return -EPERM;
>> +   }
>> +   if (sara_wxp_flags & SARA_WXP_MMAP &&
>> +   (vm_flags & VM_EXEC ||
>> +(!(vm_flags & VM_MAYWRITE) && (vm_flags & VM_MAYEXEC))) 
>> &&
>> +   get_current_sara_mmap_blocked()) {
>> +   if ((sara_wxp_flags & SARA_WXP_VERBOSE))
>> +   pr_wxp("executable mmap");
>> +   if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
>> +   return -EPERM;
>> +   }
>> +   }
>
> Given the subtle differences between these various if blocks (here and
> in the other hook), I think it would be nice to have some beefy
> comments here to describe specifically what's being checked (and why).
> It'll help others review this code, and help validate code against
> intent.
>
> I would also try to minimize the written code by creating a macro for
> a repeated pattern here:
>
>> +   if ((sara_wxp_flags & SARA_WXP_VERBOSE))
>> +   pr_wxp("mprotect on file mmap");
>> +   if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
>> +   return -EACCES;
>
> These four lines are repeated several times with only the const char *
> and return value changing. Perhaps something like:
>
> #define sara_return(err, msg) do { \
>if ((sara_wxp_flags & SARA_WXP_VERBOSE)) \
>pr_wxp(err); \
>if (!(sara_wxp_flags & SARA_WXP_COMPLAIN)) \
>return -err; \
> } while (0)
>
> Then each if block turns into something quite easier to parse:
>
>if (sara_wxp_flags & SARA_WXP_WXORX &&
>vm_flags & VM_WRITE &&
>vm_flags & VM_EXEC)
>sara_return(EPERM, "W^X");

I absolutely agree with all of the above. These issues will be addressed in v3.
Thank you for your contribution.

Salvatore


Re: [RFC v2 5/9] S.A.R.A. WX Protection

2017-06-29 Thread Salvatore Mesoraca
2017-06-28 1:04 GMT+02:00 Kees Cook :
> On Thu, Jun 15, 2017 at 9:42 AM, Salvatore Mesoraca
>  wrote:
>> +static int sara_check_vmflags(vm_flags_t vm_flags)
>> +{
>> +   u16 sara_wxp_flags = get_current_sara_wxp_flags();
>> +
>> +   if (sara_enabled && wxprot_enabled) {
>> +   if (sara_wxp_flags & SARA_WXP_WXORX &&
>> +   vm_flags & VM_WRITE &&
>> +   vm_flags & VM_EXEC) {
>> +   if ((sara_wxp_flags & SARA_WXP_VERBOSE))
>> +   pr_wxp("W^X");
>> +   if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
>> +   return -EPERM;
>> +   }
>> +   if (sara_wxp_flags & SARA_WXP_MMAP &&
>> +   (vm_flags & VM_EXEC ||
>> +(!(vm_flags & VM_MAYWRITE) && (vm_flags & VM_MAYEXEC))) 
>> &&
>> +   get_current_sara_mmap_blocked()) {
>> +   if ((sara_wxp_flags & SARA_WXP_VERBOSE))
>> +   pr_wxp("executable mmap");
>> +   if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
>> +   return -EPERM;
>> +   }
>> +   }
>
> Given the subtle differences between these various if blocks (here and
> in the other hook), I think it would be nice to have some beefy
> comments here to describe specifically what's being checked (and why).
> It'll help others review this code, and help validate code against
> intent.
>
> I would also try to minimize the written code by creating a macro for
> a repeated pattern here:
>
>> +   if ((sara_wxp_flags & SARA_WXP_VERBOSE))
>> +   pr_wxp("mprotect on file mmap");
>> +   if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
>> +   return -EACCES;
>
> These four lines are repeated several times with only the const char *
> and return value changing. Perhaps something like:
>
> #define sara_return(err, msg) do { \
>if ((sara_wxp_flags & SARA_WXP_VERBOSE)) \
>pr_wxp(err); \
>if (!(sara_wxp_flags & SARA_WXP_COMPLAIN)) \
>return -err; \
> } while (0)
>
> Then each if block turns into something quite easier to parse:
>
>if (sara_wxp_flags & SARA_WXP_WXORX &&
>vm_flags & VM_WRITE &&
>vm_flags & VM_EXEC)
>sara_return(EPERM, "W^X");

I absolutely agree with all of the above. These issues will be addressed in v3.
Thank you for your contribution.

Salvatore


Re: [RFC v2 5/9] S.A.R.A. WX Protection

2017-06-27 Thread Kees Cook
On Thu, Jun 15, 2017 at 9:42 AM, Salvatore Mesoraca
 wrote:
> +static int sara_check_vmflags(vm_flags_t vm_flags)
> +{
> +   u16 sara_wxp_flags = get_current_sara_wxp_flags();
> +
> +   if (sara_enabled && wxprot_enabled) {
> +   if (sara_wxp_flags & SARA_WXP_WXORX &&
> +   vm_flags & VM_WRITE &&
> +   vm_flags & VM_EXEC) {
> +   if ((sara_wxp_flags & SARA_WXP_VERBOSE))
> +   pr_wxp("W^X");
> +   if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
> +   return -EPERM;
> +   }
> +   if (sara_wxp_flags & SARA_WXP_MMAP &&
> +   (vm_flags & VM_EXEC ||
> +(!(vm_flags & VM_MAYWRITE) && (vm_flags & VM_MAYEXEC))) 
> &&
> +   get_current_sara_mmap_blocked()) {
> +   if ((sara_wxp_flags & SARA_WXP_VERBOSE))
> +   pr_wxp("executable mmap");
> +   if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
> +   return -EPERM;
> +   }
> +   }

Given the subtle differences between these various if blocks (here and
in the other hook), I think it would be nice to have some beefy
comments here to describe specifically what's being checked (and why).
It'll help others review this code, and help validate code against
intent.

I would also try to minimize the written code by creating a macro for
a repeated pattern here:

> +   if ((sara_wxp_flags & SARA_WXP_VERBOSE))
> +   pr_wxp("mprotect on file mmap");
> +   if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
> +   return -EACCES;

These four lines are repeated several times with only the const char *
and return value changing. Perhaps something like:

#define sara_return(err, msg) do { \
   if ((sara_wxp_flags & SARA_WXP_VERBOSE)) \
   pr_wxp(err); \
   if (!(sara_wxp_flags & SARA_WXP_COMPLAIN)) \
   return -err; \
} while (0)

Then each if block turns into something quite easier to parse:

   if (sara_wxp_flags & SARA_WXP_WXORX &&
   vm_flags & VM_WRITE &&
   vm_flags & VM_EXEC)
   sara_return(EPERM, "W^X");


-Kees

-- 
Kees Cook
Pixel Security


Re: [RFC v2 5/9] S.A.R.A. WX Protection

2017-06-27 Thread Kees Cook
On Thu, Jun 15, 2017 at 9:42 AM, Salvatore Mesoraca
 wrote:
> +static int sara_check_vmflags(vm_flags_t vm_flags)
> +{
> +   u16 sara_wxp_flags = get_current_sara_wxp_flags();
> +
> +   if (sara_enabled && wxprot_enabled) {
> +   if (sara_wxp_flags & SARA_WXP_WXORX &&
> +   vm_flags & VM_WRITE &&
> +   vm_flags & VM_EXEC) {
> +   if ((sara_wxp_flags & SARA_WXP_VERBOSE))
> +   pr_wxp("W^X");
> +   if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
> +   return -EPERM;
> +   }
> +   if (sara_wxp_flags & SARA_WXP_MMAP &&
> +   (vm_flags & VM_EXEC ||
> +(!(vm_flags & VM_MAYWRITE) && (vm_flags & VM_MAYEXEC))) 
> &&
> +   get_current_sara_mmap_blocked()) {
> +   if ((sara_wxp_flags & SARA_WXP_VERBOSE))
> +   pr_wxp("executable mmap");
> +   if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
> +   return -EPERM;
> +   }
> +   }

Given the subtle differences between these various if blocks (here and
in the other hook), I think it would be nice to have some beefy
comments here to describe specifically what's being checked (and why).
It'll help others review this code, and help validate code against
intent.

I would also try to minimize the written code by creating a macro for
a repeated pattern here:

> +   if ((sara_wxp_flags & SARA_WXP_VERBOSE))
> +   pr_wxp("mprotect on file mmap");
> +   if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
> +   return -EACCES;

These four lines are repeated several times with only the const char *
and return value changing. Perhaps something like:

#define sara_return(err, msg) do { \
   if ((sara_wxp_flags & SARA_WXP_VERBOSE)) \
   pr_wxp(err); \
   if (!(sara_wxp_flags & SARA_WXP_COMPLAIN)) \
   return -err; \
} while (0)

Then each if block turns into something quite easier to parse:

   if (sara_wxp_flags & SARA_WXP_WXORX &&
   vm_flags & VM_WRITE &&
   vm_flags & VM_EXEC)
   sara_return(EPERM, "W^X");


-Kees

-- 
Kees Cook
Pixel Security


[RFC v2 5/9] S.A.R.A. WX Protection

2017-06-15 Thread Salvatore Mesoraca
Introduction of S.A.R.A. WX Protection.
It aims to improve user-space programs security by applying:
- W^X enforcement
- W!->X (once writable never executable) mprotect restriction
- Executable MMAP prevention

All of the above features can be enabled or disabled both system wide
or on a per executable basis through the use of configuration.
W^X enforcement works by blocking any memory allocation or mprotect
invocation with both the WRITE and the EXEC flags enabled.
W!->X restriction works by preventing any mprotect invocation that makes
executable any page that is flagged VM_MAYWRITE.
This feature can be configured separately for stack, heap and other
allocations.
Executable MMAP prevention works by preventing any new executable
allocation after the dynamic libraries have been loaded. It works under the
assumption that, when the dynamic libraries have been finished loading, the
RELRO section will be marked read only.

Parts of WX Protection are inspired by some of the features available in
PaX.

Signed-off-by: Salvatore Mesoraca <s.mesorac...@gmail.com>
---
 security/sara/Kconfig  |  75 +
 security/sara/Makefile |   1 +
 security/sara/include/wxprot.h |  27 ++
 security/sara/main.c   |   6 +
 security/sara/wxprot.c | 646 +
 5 files changed, 755 insertions(+)
 create mode 100644 security/sara/include/wxprot.h
 create mode 100644 security/sara/wxprot.c

diff --git a/security/sara/Kconfig b/security/sara/Kconfig
index 5b61020..6c74069 100644
--- a/security/sara/Kconfig
+++ b/security/sara/Kconfig
@@ -39,4 +39,79 @@ config SECURITY_SARA_NO_RUNTIME_ENABLE
 
  If unsure, answer Y.
 
+config SECURITY_SARA_WXPROT
+   bool "WX Protection: W^X and W!->X protections"
+   depends on SECURITY_SARA
+   default y
+   help
+ WX Protection aims to improve user-space programs security by 
applying:
+   - W^X memory restriction
+   - W!->X (once writable never executable) mprotect restriction
+   - Executable MMAP prevention
+ See Documentation/security/SARA.rst. for further information.
+
+ If unsure, answer Y.
+
+choice
+   prompt "Default action for W^X and W!->X protections"
+   depends on SECURITY_SARA
+   depends on SECURITY_SARA_WXPROT
+   default SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+
+help
+     Choose the default behaviour of WX Protection when no config
+ rule matches or no rule is loaded.
+ For further information on available flags and their meaning
+ see Documentation/security/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+   bool "Protections enabled but not enforced."
+   help
+ All features enabled except "Executable MMAP prevention",
+ verbose reporting, but no actual enforce: it just complains.
+ Its numeric value is 0x3f, for more information see
+ Documentation/security/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
+   bool "Full protection, verbose."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced with verbose reporting.
+ Its numeric value is 0x2f, for more information see
+ Documentation/security/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE
+   bool "Full protection, quiet."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced quietly.
+ Its numeric value is 0xf, for more information see
+ Documentation/security/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_NONE
+   bool "No protection at all."
+   help
+ All features disabled.
+ Its numeric value is 0, for more information see
+     Documentation/security/SARA.rst.
+endchoice
+
+config SECURITY_SARA_WXPROT_DISABLED
+   bool "WX protection will be disabled at boot."
+   depends on SECURITY_SARA_WXPROT
+   default n
+   help
+ If you say Y here WX protection won't be enabled at startup. You can
+ override this option via user-space utilities or at boot time via
+ "sara_wxprot=[0|1]" kernel parameter.
+
+ If unsure, answer N.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS
+   hex
+   default "0x3f" if 
SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+   default "0x2f" if SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
+   default "0xf" if SECURI

[RFC v2 5/9] S.A.R.A. WX Protection

2017-06-15 Thread Salvatore Mesoraca
Introduction of S.A.R.A. WX Protection.
It aims to improve user-space programs security by applying:
- W^X enforcement
- W!->X (once writable never executable) mprotect restriction
- Executable MMAP prevention

All of the above features can be enabled or disabled both system wide
or on a per executable basis through the use of configuration.
W^X enforcement works by blocking any memory allocation or mprotect
invocation with both the WRITE and the EXEC flags enabled.
W!->X restriction works by preventing any mprotect invocation that makes
executable any page that is flagged VM_MAYWRITE.
This feature can be configured separately for stack, heap and other
allocations.
Executable MMAP prevention works by preventing any new executable
allocation after the dynamic libraries have been loaded. It works under the
assumption that, when the dynamic libraries have been finished loading, the
RELRO section will be marked read only.

Parts of WX Protection are inspired by some of the features available in
PaX.

Signed-off-by: Salvatore Mesoraca 
---
 security/sara/Kconfig  |  75 +
 security/sara/Makefile |   1 +
 security/sara/include/wxprot.h |  27 ++
 security/sara/main.c   |   6 +
 security/sara/wxprot.c | 646 +
 5 files changed, 755 insertions(+)
 create mode 100644 security/sara/include/wxprot.h
 create mode 100644 security/sara/wxprot.c

diff --git a/security/sara/Kconfig b/security/sara/Kconfig
index 5b61020..6c74069 100644
--- a/security/sara/Kconfig
+++ b/security/sara/Kconfig
@@ -39,4 +39,79 @@ config SECURITY_SARA_NO_RUNTIME_ENABLE
 
  If unsure, answer Y.
 
+config SECURITY_SARA_WXPROT
+   bool "WX Protection: W^X and W!->X protections"
+   depends on SECURITY_SARA
+   default y
+       help
+ WX Protection aims to improve user-space programs security by 
applying:
+   - W^X memory restriction
+   - W!->X (once writable never executable) mprotect restriction
+   - Executable MMAP prevention
+ See Documentation/security/SARA.rst. for further information.
+
+ If unsure, answer Y.
+
+choice
+   prompt "Default action for W^X and W!->X protections"
+   depends on SECURITY_SARA
+   depends on SECURITY_SARA_WXPROT
+   default SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+
+help
+     Choose the default behaviour of WX Protection when no config
+ rule matches or no rule is loaded.
+ For further information on available flags and their meaning
+ see Documentation/security/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+   bool "Protections enabled but not enforced."
+   help
+ All features enabled except "Executable MMAP prevention",
+ verbose reporting, but no actual enforce: it just complains.
+ Its numeric value is 0x3f, for more information see
+ Documentation/security/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
+   bool "Full protection, verbose."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced with verbose reporting.
+ Its numeric value is 0x2f, for more information see
+ Documentation/security/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE
+   bool "Full protection, quiet."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced quietly.
+ Its numeric value is 0xf, for more information see
+ Documentation/security/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_NONE
+   bool "No protection at all."
+   help
+ All features disabled.
+ Its numeric value is 0, for more information see
+     Documentation/security/SARA.rst.
+endchoice
+
+config SECURITY_SARA_WXPROT_DISABLED
+   bool "WX protection will be disabled at boot."
+   depends on SECURITY_SARA_WXPROT
+   default n
+   help
+ If you say Y here WX protection won't be enabled at startup. You can
+ override this option via user-space utilities or at boot time via
+ "sara_wxprot=[0|1]" kernel parameter.
+
+ If unsure, answer N.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS
+   hex
+   default "0x3f" if 
SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+   default "0x2f" if SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
+   default "0xf" if SECURITY_SARA_WXPROT_DEFAULT_FLA

[RFC v2 9/9] S.A.R.A. WX Protection procattr interface

2017-06-15 Thread Salvatore Mesoraca
This allow threads to get current WX Protection flags for themselves or
for other threads (if they have CAP_MAC_ADMIN).
It also allow a thread to set itself flags to a stricter set of rules than
the current one.
Via a new wxprot flag (SARA_WXP_FORCE_WXORX) is it possible to ask the
kernel to rescan the memory and remove the VM_WRITE flag from any area
that is marked both writable and executable.
Protections that prevent the runtime creation of executable code
can be troublesome for all those programs that actually need to do it
e.g. programs shipping with a JIT compiler built-in.
This feature can be use to run the JIT compiler with few restrictions while
enforcing full WX Protection in the rest of the program.
To simplify access to this interface a CC0 licensed library is available
here: https://github.com/smeso/libsara

Signed-off-by: Salvatore Mesoraca <s.mesorac...@gmail.com>
---
 security/sara/wxprot.c | 124 +
 1 file changed, 124 insertions(+)

diff --git a/security/sara/wxprot.c b/security/sara/wxprot.c
index 38c86be..0939591 100644
--- a/security/sara/wxprot.c
+++ b/security/sara/wxprot.c
@@ -12,6 +12,7 @@
 #ifdef CONFIG_SECURITY_SARA_WXPROT
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -42,6 +43,7 @@
 #define SARA_WXP_COMPLAIN  0x0010
 #define SARA_WXP_VERBOSE   0x0020
 #define SARA_WXP_MMAP  0x0040
+#define SARA_WXP_FORCE_WXORX   0x0080
 #define SARA_WXP_EMUTRAMP  0x0100
 #define SARA_WXP_TRANSFER  0x0200
 #define SARA_WXP_NONE  0x
@@ -503,6 +505,126 @@ static inline int sara_pagefault_handler_x86_64(struct 
pt_regs *regs)
 
 #endif /* CONFIG_SECURITY_SARA_WXPROT_EMUTRAMP */
 
+static int sara_getprocattr(struct task_struct *p, char *name, char **value)
+{
+   int ret;
+   u16 flags;
+   char *buf;
+
+   ret = -EINVAL;
+   if (strcmp(name, "wxprot") != 0)
+   goto out;
+
+   ret = -EACCES;
+   if (unlikely(current != p &&
+!capable(CAP_MAC_ADMIN)))
+   goto out;
+
+   ret = -ENOMEM;
+   buf = kzalloc(8, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto out;
+
+   if (!sara_enabled || !wxprot_enabled) {
+   flags = 0x0;
+   } else {
+   rcu_read_lock();
+   flags = get_sara_wxp_flags(__task_cred(p));
+   rcu_read_unlock();
+   }
+
+   snprintf(buf, 8, "0x%04x\n", flags);
+   ret = strlen(buf);
+   *value = buf;
+
+out:
+   return ret;
+}
+
+static int sara_setprocattr(const char *name, void *value, size_t size)
+{
+   int ret;
+   struct vm_area_struct *vma;
+   struct cred *new = prepare_creds();
+   u16 cur_flags;
+   u16 req_flags;
+   char *buf = NULL;
+
+   ret = -EINVAL;
+   if (!sara_enabled || !wxprot_enabled)
+   goto error;
+   if (unlikely(new == NULL))
+   return -ENOMEM;
+   if (strcmp(name, "wxprot") != 0)
+   goto error;
+   if (unlikely(value == NULL || size == 0 || size > 7))
+   goto error;
+   ret = -ENOMEM;
+   buf = kmalloc(size+1, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto error;
+   buf[size] = '\0';
+   memcpy(buf, value, size);
+   ret = -EINVAL;
+   if (unlikely(strlen(buf) != size))
+   goto error;
+   if (unlikely(kstrtou16(buf, 16, _flags) != 0))
+   goto error;
+   if (unlikely(!are_flags_valid(req_flags & ~SARA_WXP_FORCE_WXORX)))
+   goto error;
+   if (unlikely(req_flags & SARA_WXP_FORCE_WXORX &&
+!(req_flags & SARA_WXP_WXORX)))
+   goto error;
+   if (unlikely(!get_current_sara_relro_page_found() &&
+req_flags & SARA_WXP_MMAP))
+   goto error;
+   cur_flags = get_current_sara_wxp_flags();
+   if (unlikely((req_flags & SARA_WXP_COMPLAIN) &&
+!(cur_flags & SARA_WXP_COMPLAIN)))
+   goto error;
+   if (unlikely((req_flags & SARA_WXP_EMUTRAMP) &&
+!(cur_flags & SARA_WXP_EMUTRAMP) &&
+(cur_flags & (SARA_WXP_MPROTECT |
+  SARA_WXP_WXORX
+   goto error;
+   if (cur_flags & SARA_WXP_VERBOSE)
+   req_flags |= SARA_WXP_VERBOSE;
+   else
+   req_flags &= ~SARA_WXP_VERBOSE;
+   if (unlikely(cur_flags & (req_flags ^ cur_flags) &
+~(SARA_WXP_COMPLAIN|SARA_WXP_EMUTRAMP)))
+   goto error;
+   ret = -EINTR;
+   if (req_flags & SARA_WXP_FORCE_WXORX) {
+   if (down_write_killable(>mm->mmap_sem))
+   goto error;
+   for (vma = current->mm->mmap; vma; vma = vma->

[RFC v2 9/9] S.A.R.A. WX Protection procattr interface

2017-06-15 Thread Salvatore Mesoraca
This allow threads to get current WX Protection flags for themselves or
for other threads (if they have CAP_MAC_ADMIN).
It also allow a thread to set itself flags to a stricter set of rules than
the current one.
Via a new wxprot flag (SARA_WXP_FORCE_WXORX) is it possible to ask the
kernel to rescan the memory and remove the VM_WRITE flag from any area
that is marked both writable and executable.
Protections that prevent the runtime creation of executable code
can be troublesome for all those programs that actually need to do it
e.g. programs shipping with a JIT compiler built-in.
This feature can be use to run the JIT compiler with few restrictions while
enforcing full WX Protection in the rest of the program.
To simplify access to this interface a CC0 licensed library is available
here: https://github.com/smeso/libsara

Signed-off-by: Salvatore Mesoraca 
---
 security/sara/wxprot.c | 124 +
 1 file changed, 124 insertions(+)

diff --git a/security/sara/wxprot.c b/security/sara/wxprot.c
index 38c86be..0939591 100644
--- a/security/sara/wxprot.c
+++ b/security/sara/wxprot.c
@@ -12,6 +12,7 @@
 #ifdef CONFIG_SECURITY_SARA_WXPROT
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -42,6 +43,7 @@
 #define SARA_WXP_COMPLAIN  0x0010
 #define SARA_WXP_VERBOSE   0x0020
 #define SARA_WXP_MMAP  0x0040
+#define SARA_WXP_FORCE_WXORX   0x0080
 #define SARA_WXP_EMUTRAMP  0x0100
 #define SARA_WXP_TRANSFER  0x0200
 #define SARA_WXP_NONE  0x
@@ -503,6 +505,126 @@ static inline int sara_pagefault_handler_x86_64(struct 
pt_regs *regs)
 
 #endif /* CONFIG_SECURITY_SARA_WXPROT_EMUTRAMP */
 
+static int sara_getprocattr(struct task_struct *p, char *name, char **value)
+{
+   int ret;
+   u16 flags;
+   char *buf;
+
+   ret = -EINVAL;
+   if (strcmp(name, "wxprot") != 0)
+   goto out;
+
+   ret = -EACCES;
+   if (unlikely(current != p &&
+!capable(CAP_MAC_ADMIN)))
+   goto out;
+
+   ret = -ENOMEM;
+   buf = kzalloc(8, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto out;
+
+   if (!sara_enabled || !wxprot_enabled) {
+   flags = 0x0;
+   } else {
+   rcu_read_lock();
+   flags = get_sara_wxp_flags(__task_cred(p));
+   rcu_read_unlock();
+   }
+
+   snprintf(buf, 8, "0x%04x\n", flags);
+   ret = strlen(buf);
+   *value = buf;
+
+out:
+   return ret;
+}
+
+static int sara_setprocattr(const char *name, void *value, size_t size)
+{
+   int ret;
+   struct vm_area_struct *vma;
+   struct cred *new = prepare_creds();
+   u16 cur_flags;
+   u16 req_flags;
+   char *buf = NULL;
+
+   ret = -EINVAL;
+   if (!sara_enabled || !wxprot_enabled)
+   goto error;
+   if (unlikely(new == NULL))
+   return -ENOMEM;
+   if (strcmp(name, "wxprot") != 0)
+   goto error;
+   if (unlikely(value == NULL || size == 0 || size > 7))
+   goto error;
+   ret = -ENOMEM;
+   buf = kmalloc(size+1, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto error;
+   buf[size] = '\0';
+   memcpy(buf, value, size);
+   ret = -EINVAL;
+   if (unlikely(strlen(buf) != size))
+   goto error;
+   if (unlikely(kstrtou16(buf, 16, _flags) != 0))
+   goto error;
+   if (unlikely(!are_flags_valid(req_flags & ~SARA_WXP_FORCE_WXORX)))
+   goto error;
+   if (unlikely(req_flags & SARA_WXP_FORCE_WXORX &&
+!(req_flags & SARA_WXP_WXORX)))
+   goto error;
+   if (unlikely(!get_current_sara_relro_page_found() &&
+req_flags & SARA_WXP_MMAP))
+   goto error;
+   cur_flags = get_current_sara_wxp_flags();
+   if (unlikely((req_flags & SARA_WXP_COMPLAIN) &&
+!(cur_flags & SARA_WXP_COMPLAIN)))
+   goto error;
+   if (unlikely((req_flags & SARA_WXP_EMUTRAMP) &&
+!(cur_flags & SARA_WXP_EMUTRAMP) &&
+(cur_flags & (SARA_WXP_MPROTECT |
+  SARA_WXP_WXORX
+   goto error;
+   if (cur_flags & SARA_WXP_VERBOSE)
+   req_flags |= SARA_WXP_VERBOSE;
+   else
+   req_flags &= ~SARA_WXP_VERBOSE;
+   if (unlikely(cur_flags & (req_flags ^ cur_flags) &
+~(SARA_WXP_COMPLAIN|SARA_WXP_EMUTRAMP)))
+   goto error;
+   ret = -EINTR;
+   if (req_flags & SARA_WXP_FORCE_WXORX) {
+   if (down_write_killable(>mm->mmap_sem))
+   goto error;
+   for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
+

[PATCH 11/11] S.A.R.A. WX Protection procattr interface

2017-06-12 Thread Salvatore Mesoraca
This allow processes to get current WX Protection flags for themselves or
for other processes of the same user.
It also allow a process to set itself flags to a stricter set of rules than
the current one.
Via a new wxprot flag (SARA_WXP_FORCE_WXORX) is it possible to ask the
kernel to rescan the process memory and remove the VM_WRITE flag from any
area that is marked both writable and executable.
Protections that prevent the runtime creation of executable code
can be troublesome for all those programs that actually need to do it
e.g. programs shipping with a JIT compiler built-in.
Given that it's possible to segregate the part that runs untrusted
code from the rest through a fork, this feature can be use to run the JIT
compiler with few restrictions while enforcing full WX Protection in the
rest of the program.
To simplify access to this interface a CC0 licensed library is available
here: https://github.com/smeso/saralib

Signed-off-by: Salvatore Mesoraca <s.mesorac...@gmail.com>
---
 security/sara/wxprot.c | 123 +
 1 file changed, 123 insertions(+)

diff --git a/security/sara/wxprot.c b/security/sara/wxprot.c
index 44e42be..00cd22c 100644
--- a/security/sara/wxprot.c
+++ b/security/sara/wxprot.c
@@ -40,6 +40,7 @@
 #define SARA_WXP_COMPLAIN  0x0010
 #define SARA_WXP_VERBOSE   0x0020
 #define SARA_WXP_MMAP  0x0040
+#define SARA_WXP_FORCE_WXORX   0x0080
 #define SARA_WXP_EMUTRAMP  0x0100
 #define SARA_WXP_TRANSFER  0x0200
 #define SARA_WXP_NONE  0x
@@ -496,6 +497,126 @@ static inline int sara_pagefault_handler_x86_64(struct 
pt_regs *regs)
 
 #endif /* CONFIG_SECURITY_SARA_WXPROT_EMUTRAMP */
 
+static int sara_getprocattr(struct task_struct *p, char *name, char **value)
+{
+   int ret;
+   u16 flags;
+   char *buf;
+
+   ret = -EINVAL;
+   if (strcmp(name, "wxprot") != 0)
+   goto out;
+
+   ret = -EACCES;
+   if (unlikely(current != p &&
+current_euid().val))
+   goto out;
+
+   ret = -ENOMEM;
+   buf = kzalloc(8, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto out;
+
+   if (!sara_enabled || !wxprot_enabled) {
+   flags = 0x0;
+   } else {
+   rcu_read_lock();
+   flags = get_sara_wxp_flags(__task_cred(p));
+   rcu_read_unlock();
+   }
+
+   snprintf(buf, 8, "0x%04x\n", flags);
+   ret = strlen(buf);
+   *value = buf;
+
+out:
+   return ret;
+}
+
+static int sara_setprocattr(const char *name, void *value, size_t size)
+{
+   int ret;
+   struct vm_area_struct *vma;
+   struct cred *new = prepare_creds();
+   u16 cur_flags;
+   u16 req_flags;
+   char *buf = NULL;
+
+   ret = -EINVAL;
+   if (!sara_enabled || !wxprot_enabled)
+   goto error;
+   if (unlikely(new == NULL))
+   return -ENOMEM;
+   if (strcmp(name, "wxprot") != 0)
+   goto error;
+   if (unlikely(value == NULL || size == 0 || size > 7))
+   goto error;
+   ret = -ENOMEM;
+   buf = kmalloc(size+1, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto error;
+   buf[size] = '\0';
+   memcpy(buf, value, size);
+   ret = -EINVAL;
+   if (unlikely(strlen(buf) != size))
+   goto error;
+   if (unlikely(kstrtou16(buf, 16, _flags) != 0))
+   goto error;
+   if (unlikely(!are_flags_valid(req_flags & ~SARA_WXP_FORCE_WXORX)))
+   goto error;
+   if (unlikely(req_flags & SARA_WXP_FORCE_WXORX &&
+!(req_flags & SARA_WXP_WXORX)))
+   goto error;
+   if (unlikely(!get_current_sara_relro_page_found() &&
+req_flags & SARA_WXP_MMAP))
+   goto error;
+   cur_flags = get_current_sara_wxp_flags();
+   if (unlikely((req_flags & SARA_WXP_COMPLAIN) &&
+!(cur_flags & SARA_WXP_COMPLAIN)))
+   goto error;
+   if (unlikely((req_flags & SARA_WXP_EMUTRAMP) &&
+!(cur_flags & SARA_WXP_EMUTRAMP) &&
+(cur_flags & (SARA_WXP_MPROTECT |
+  SARA_WXP_WXORX
+   goto error;
+   if (cur_flags & SARA_WXP_VERBOSE)
+   req_flags |= SARA_WXP_VERBOSE;
+   else
+   req_flags &= ~SARA_WXP_VERBOSE;
+   if (unlikely(cur_flags & (req_flags ^ cur_flags) &
+~(SARA_WXP_COMPLAIN|SARA_WXP_EMUTRAMP)))
+   goto error;
+   ret = -EINTR;
+   if (req_flags & SARA_WXP_FORCE_WXORX) {
+   if (down_write_killable(>mm->mmap_sem))
+   goto error;
+   for (vma = current->mm->mmap; vma; vma = vma->vm_next) 

[PATCH 07/11] S.A.R.A. WX Protection

2017-06-12 Thread Salvatore Mesoraca
Introduction of S.A.R.A. WX Protection.
It aims to improve user-space programs security by applying:
- W^X enforcement
- W!->X (once writable never executable) mprotect restriction
- Executable MMAP prevention

All of the above features can be enabled or disabled both system wide
or on a per executable basis through the use of configuration.
W^X enforcement works by blocking any memory allocation or mprotect
invocation with both the WRITE and the EXEC flags enabled.
W!->X restriction works by preventing any mprotect invocation that makes
executable any page that is flagged VM_MAYWRITE.
This feature can be configured separately for stack, heap and other
allocations.
Executable MMAP prevention works by preventing any new executable
allocation after the dynamic libraries have been loaded. It works under the
assumption that, when the dynamic libraries have been finished loading, the
RELRO section will be marked read only.

Parts of WX Protection are inspired by some of the features available in
PaX.

Signed-off-by: Salvatore Mesoraca <s.mesorac...@gmail.com>
---
 security/sara/Kconfig  |  75 +
 security/sara/Makefile |   1 +
 security/sara/include/wxprot.h |  27 ++
 security/sara/main.c   |   6 +
 security/sara/wxprot.c | 642 +
 5 files changed, 751 insertions(+)
 create mode 100644 security/sara/include/wxprot.h
 create mode 100644 security/sara/wxprot.c

diff --git a/security/sara/Kconfig b/security/sara/Kconfig
index 01ff246..cb49f20 100644
--- a/security/sara/Kconfig
+++ b/security/sara/Kconfig
@@ -80,4 +80,79 @@ config SECURITY_SARA_USB_FILTERING_DISABLED
 
  If unsure, answer N.
 
+config SECURITY_SARA_WXPROT
+   bool "WX Protection: W^X and W!->X protections"
+   depends on SECURITY_SARA
+   default y
+   help
+ WX Protection aims to improve user-space programs security by 
applying:
+   - W^X memory restriction
+   - W!->X (once writable never executable) mprotect restriction
+   - Executable MMAP prevention
+ See Documentation/security/SARA.rst. for further information.
+
+ If unsure, answer Y.
+
+choice
+   prompt "Default action for W^X and W!->X protections"
+   depends on SECURITY_SARA
+   depends on SECURITY_SARA_WXPROT
+   default SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+
+help
+     Choose the default behaviour of WX Protection when no config
+ rule matches or no rule is loaded.
+ For further information on available flags and their meaning
+ see Documentation/security/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+   bool "Protections enabled but not enforced."
+   help
+ All features enabled except "Executable MMAP prevention",
+ verbose reporting, but no actual enforce: it just complains.
+ Its numeric value is 0x3f, for more information see
+ Documentation/security/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
+   bool "Full protection, verbose."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced with verbose reporting.
+ Its numeric value is 0x2f, for more information see
+ Documentation/security/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE
+   bool "Full protection, quiet."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced quietly.
+ Its numeric value is 0xf, for more information see
+ Documentation/security/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_NONE
+   bool "No protection at all."
+   help
+ All features disabled.
+ Its numeric value is 0, for more information see
+     Documentation/security/SARA.rst.
+endchoice
+
+config SECURITY_SARA_WXPROT_DISABLED
+   bool "WX protection will be disabled at boot."
+   depends on SECURITY_SARA_WXPROT
+   default n
+   help
+ If you say Y here WX protection won't be enabled at startup. You can
+ override this option via user-space utilities or at boot time via
+ "sara_wxprot=[0|1]" kernel parameter.
+
+ If unsure, answer N.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS
+   hex
+   default "0x3f" if 
SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+   default "0x2f" if SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
+   default "0xf" 

[PATCH 11/11] S.A.R.A. WX Protection procattr interface

2017-06-12 Thread Salvatore Mesoraca
This allow processes to get current WX Protection flags for themselves or
for other processes of the same user.
It also allow a process to set itself flags to a stricter set of rules than
the current one.
Via a new wxprot flag (SARA_WXP_FORCE_WXORX) is it possible to ask the
kernel to rescan the process memory and remove the VM_WRITE flag from any
area that is marked both writable and executable.
Protections that prevent the runtime creation of executable code
can be troublesome for all those programs that actually need to do it
e.g. programs shipping with a JIT compiler built-in.
Given that it's possible to segregate the part that runs untrusted
code from the rest through a fork, this feature can be use to run the JIT
compiler with few restrictions while enforcing full WX Protection in the
rest of the program.
To simplify access to this interface a CC0 licensed library is available
here: https://github.com/smeso/saralib

Signed-off-by: Salvatore Mesoraca 
---
 security/sara/wxprot.c | 123 +
 1 file changed, 123 insertions(+)

diff --git a/security/sara/wxprot.c b/security/sara/wxprot.c
index 44e42be..00cd22c 100644
--- a/security/sara/wxprot.c
+++ b/security/sara/wxprot.c
@@ -40,6 +40,7 @@
 #define SARA_WXP_COMPLAIN  0x0010
 #define SARA_WXP_VERBOSE   0x0020
 #define SARA_WXP_MMAP  0x0040
+#define SARA_WXP_FORCE_WXORX   0x0080
 #define SARA_WXP_EMUTRAMP  0x0100
 #define SARA_WXP_TRANSFER  0x0200
 #define SARA_WXP_NONE  0x
@@ -496,6 +497,126 @@ static inline int sara_pagefault_handler_x86_64(struct 
pt_regs *regs)
 
 #endif /* CONFIG_SECURITY_SARA_WXPROT_EMUTRAMP */
 
+static int sara_getprocattr(struct task_struct *p, char *name, char **value)
+{
+   int ret;
+   u16 flags;
+   char *buf;
+
+   ret = -EINVAL;
+   if (strcmp(name, "wxprot") != 0)
+   goto out;
+
+   ret = -EACCES;
+   if (unlikely(current != p &&
+current_euid().val))
+   goto out;
+
+   ret = -ENOMEM;
+   buf = kzalloc(8, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto out;
+
+   if (!sara_enabled || !wxprot_enabled) {
+   flags = 0x0;
+   } else {
+   rcu_read_lock();
+   flags = get_sara_wxp_flags(__task_cred(p));
+   rcu_read_unlock();
+   }
+
+   snprintf(buf, 8, "0x%04x\n", flags);
+   ret = strlen(buf);
+   *value = buf;
+
+out:
+   return ret;
+}
+
+static int sara_setprocattr(const char *name, void *value, size_t size)
+{
+   int ret;
+   struct vm_area_struct *vma;
+   struct cred *new = prepare_creds();
+   u16 cur_flags;
+   u16 req_flags;
+   char *buf = NULL;
+
+   ret = -EINVAL;
+   if (!sara_enabled || !wxprot_enabled)
+   goto error;
+   if (unlikely(new == NULL))
+   return -ENOMEM;
+   if (strcmp(name, "wxprot") != 0)
+   goto error;
+   if (unlikely(value == NULL || size == 0 || size > 7))
+   goto error;
+   ret = -ENOMEM;
+   buf = kmalloc(size+1, GFP_KERNEL);
+   if (unlikely(buf == NULL))
+   goto error;
+   buf[size] = '\0';
+   memcpy(buf, value, size);
+   ret = -EINVAL;
+   if (unlikely(strlen(buf) != size))
+   goto error;
+   if (unlikely(kstrtou16(buf, 16, _flags) != 0))
+   goto error;
+   if (unlikely(!are_flags_valid(req_flags & ~SARA_WXP_FORCE_WXORX)))
+   goto error;
+   if (unlikely(req_flags & SARA_WXP_FORCE_WXORX &&
+!(req_flags & SARA_WXP_WXORX)))
+   goto error;
+   if (unlikely(!get_current_sara_relro_page_found() &&
+req_flags & SARA_WXP_MMAP))
+   goto error;
+   cur_flags = get_current_sara_wxp_flags();
+   if (unlikely((req_flags & SARA_WXP_COMPLAIN) &&
+!(cur_flags & SARA_WXP_COMPLAIN)))
+   goto error;
+   if (unlikely((req_flags & SARA_WXP_EMUTRAMP) &&
+!(cur_flags & SARA_WXP_EMUTRAMP) &&
+(cur_flags & (SARA_WXP_MPROTECT |
+  SARA_WXP_WXORX
+   goto error;
+   if (cur_flags & SARA_WXP_VERBOSE)
+   req_flags |= SARA_WXP_VERBOSE;
+   else
+   req_flags &= ~SARA_WXP_VERBOSE;
+   if (unlikely(cur_flags & (req_flags ^ cur_flags) &
+~(SARA_WXP_COMPLAIN|SARA_WXP_EMUTRAMP)))
+   goto error;
+   ret = -EINTR;
+   if (req_flags & SARA_WXP_FORCE_WXORX) {
+   if (down_write_killable(>mm->mmap_sem))
+   goto error;
+   for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
+

[PATCH 07/11] S.A.R.A. WX Protection

2017-06-12 Thread Salvatore Mesoraca
Introduction of S.A.R.A. WX Protection.
It aims to improve user-space programs security by applying:
- W^X enforcement
- W!->X (once writable never executable) mprotect restriction
- Executable MMAP prevention

All of the above features can be enabled or disabled both system wide
or on a per executable basis through the use of configuration.
W^X enforcement works by blocking any memory allocation or mprotect
invocation with both the WRITE and the EXEC flags enabled.
W!->X restriction works by preventing any mprotect invocation that makes
executable any page that is flagged VM_MAYWRITE.
This feature can be configured separately for stack, heap and other
allocations.
Executable MMAP prevention works by preventing any new executable
allocation after the dynamic libraries have been loaded. It works under the
assumption that, when the dynamic libraries have been finished loading, the
RELRO section will be marked read only.

Parts of WX Protection are inspired by some of the features available in
PaX.

Signed-off-by: Salvatore Mesoraca 
---
 security/sara/Kconfig  |  75 +
 security/sara/Makefile |   1 +
 security/sara/include/wxprot.h |  27 ++
 security/sara/main.c   |   6 +
 security/sara/wxprot.c | 642 +
 5 files changed, 751 insertions(+)
 create mode 100644 security/sara/include/wxprot.h
 create mode 100644 security/sara/wxprot.c

diff --git a/security/sara/Kconfig b/security/sara/Kconfig
index 01ff246..cb49f20 100644
--- a/security/sara/Kconfig
+++ b/security/sara/Kconfig
@@ -80,4 +80,79 @@ config SECURITY_SARA_USB_FILTERING_DISABLED
 
  If unsure, answer N.
 
+config SECURITY_SARA_WXPROT
+   bool "WX Protection: W^X and W!->X protections"
+   depends on SECURITY_SARA
+   default y
+       help
+ WX Protection aims to improve user-space programs security by 
applying:
+   - W^X memory restriction
+   - W!->X (once writable never executable) mprotect restriction
+   - Executable MMAP prevention
+ See Documentation/security/SARA.rst. for further information.
+
+ If unsure, answer Y.
+
+choice
+   prompt "Default action for W^X and W!->X protections"
+   depends on SECURITY_SARA
+   depends on SECURITY_SARA_WXPROT
+   default SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+
+help
+     Choose the default behaviour of WX Protection when no config
+ rule matches or no rule is loaded.
+ For further information on available flags and their meaning
+ see Documentation/security/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+   bool "Protections enabled but not enforced."
+   help
+ All features enabled except "Executable MMAP prevention",
+ verbose reporting, but no actual enforce: it just complains.
+ Its numeric value is 0x3f, for more information see
+ Documentation/security/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
+   bool "Full protection, verbose."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced with verbose reporting.
+ Its numeric value is 0x2f, for more information see
+ Documentation/security/SARA.rst.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE
+   bool "Full protection, quiet."
+   help
+ All features enabled except "Executable MMAP prevention".
+ The enabled features will be enforced quietly.
+ Its numeric value is 0xf, for more information see
+ Documentation/security/SARA.rst.
+
+   config SECURITY_SARA_WXPROT_DEFAULT_FLAGS_NONE
+   bool "No protection at all."
+   help
+ All features disabled.
+ Its numeric value is 0, for more information see
+     Documentation/security/SARA.rst.
+endchoice
+
+config SECURITY_SARA_WXPROT_DISABLED
+   bool "WX protection will be disabled at boot."
+   depends on SECURITY_SARA_WXPROT
+   default n
+   help
+ If you say Y here WX protection won't be enabled at startup. You can
+ override this option via user-space utilities or at boot time via
+ "sara_wxprot=[0|1]" kernel parameter.
+
+ If unsure, answer N.
+
+config SECURITY_SARA_WXPROT_DEFAULT_FLAGS
+   hex
+   default "0x3f" if 
SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_COMPLAIN_VERBOSE
+   default "0x2f" if SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE_VERBOSE
+   default "0xf" if SECURITY_SARA_WXPROT_DEFAU

Re: [kernel-hardening] Re: [PATCHv4 0/4] WX checking for arm64

2016-11-07 Thread Ard Biesheuvel
On 7 November 2016 at 19:49, Mark Rutland  wrote:
> On Mon, Nov 07, 2016 at 03:38:02PM +, Mark Rutland wrote:
>> On Sun, Oct 30, 2016 at 03:03:07PM +, Catalin Marinas wrote:
>> > On Thu, Oct 27, 2016 at 09:27:30AM -0700, Laura Abbott wrote:
>> > > Laura Abbott (4):
>> > >   arm64: dump: Make ptdump debugfs a separate option
>> > >   arm64: dump: Make the page table dumping seq_file optional
>> > >   arm64: dump: Remove max_addr
>> > >   arm64: dump: Add checking for writable and exectuable pages
>> >
>> > Queued for 4.10. Thanks.
>>
>> Catalin mentioned to me that he saw some KASAN splats when testing; it
>> looks like need a fixup something like the below.
>
> As an aside, it looks like any ptdump usage when KASAN is enabled takes
> several minutes, which at boot time looks like a hang.
>
> AFAICT, this is because KASAN allocates *huge* VA ranges (4TB+) worth of
> zeroed shadow memory at pte granularity (reusing the same pmd, pud,
> tables), and the ptdump code dutifully walks this with, with the added
> KASAN instrumentation overhead.
>
> I'll try to dig into that tomorrow; I suspect/hope it's not necessary to
> keep all of that mapped.
>

I have noticed that in the past, but I see how this delay at boot time
is an issue. However, I don't think there is a huge cost involved in
terms of memory footprint: AFAIK, the same PMD/PTE/kasan zero page are
mapped over and over across the range.


Re: [kernel-hardening] Re: [PATCHv4 0/4] WX checking for arm64

2016-11-07 Thread Ard Biesheuvel
On 7 November 2016 at 19:49, Mark Rutland  wrote:
> On Mon, Nov 07, 2016 at 03:38:02PM +, Mark Rutland wrote:
>> On Sun, Oct 30, 2016 at 03:03:07PM +, Catalin Marinas wrote:
>> > On Thu, Oct 27, 2016 at 09:27:30AM -0700, Laura Abbott wrote:
>> > > Laura Abbott (4):
>> > >   arm64: dump: Make ptdump debugfs a separate option
>> > >   arm64: dump: Make the page table dumping seq_file optional
>> > >   arm64: dump: Remove max_addr
>> > >   arm64: dump: Add checking for writable and exectuable pages
>> >
>> > Queued for 4.10. Thanks.
>>
>> Catalin mentioned to me that he saw some KASAN splats when testing; it
>> looks like need a fixup something like the below.
>
> As an aside, it looks like any ptdump usage when KASAN is enabled takes
> several minutes, which at boot time looks like a hang.
>
> AFAICT, this is because KASAN allocates *huge* VA ranges (4TB+) worth of
> zeroed shadow memory at pte granularity (reusing the same pmd, pud,
> tables), and the ptdump code dutifully walks this with, with the added
> KASAN instrumentation overhead.
>
> I'll try to dig into that tomorrow; I suspect/hope it's not necessary to
> keep all of that mapped.
>

I have noticed that in the past, but I see how this delay at boot time
is an issue. However, I don't think there is a huge cost involved in
terms of memory footprint: AFAIK, the same PMD/PTE/kasan zero page are
mapped over and over across the range.


Re: [kernel-hardening] Re: [PATCHv4 0/4] WX checking for arm64

2016-11-07 Thread Mark Rutland
On Mon, Nov 07, 2016 at 03:38:02PM +, Mark Rutland wrote:
> On Sun, Oct 30, 2016 at 03:03:07PM +, Catalin Marinas wrote:
> > On Thu, Oct 27, 2016 at 09:27:30AM -0700, Laura Abbott wrote:
> > > Laura Abbott (4):
> > >   arm64: dump: Make ptdump debugfs a separate option
> > >   arm64: dump: Make the page table dumping seq_file optional
> > >   arm64: dump: Remove max_addr
> > >   arm64: dump: Add checking for writable and exectuable pages
> > 
> > Queued for 4.10. Thanks.
> 
> Catalin mentioned to me that he saw some KASAN splats when testing; it
> looks like need a fixup something like the below.

As an aside, it looks like any ptdump usage when KASAN is enabled takes
several minutes, which at boot time looks like a hang.

AFAICT, this is because KASAN allocates *huge* VA ranges (4TB+) worth of
zeroed shadow memory at pte granularity (reusing the same pmd, pud,
tables), and the ptdump code dutifully walks this with, with the added
KASAN instrumentation overhead.

I'll try to dig into that tomorrow; I suspect/hope it's not necessary to
keep all of that mapped.

Thanks,
Mark.


Re: [kernel-hardening] Re: [PATCHv4 0/4] WX checking for arm64

2016-11-07 Thread Mark Rutland
On Mon, Nov 07, 2016 at 03:38:02PM +, Mark Rutland wrote:
> On Sun, Oct 30, 2016 at 03:03:07PM +, Catalin Marinas wrote:
> > On Thu, Oct 27, 2016 at 09:27:30AM -0700, Laura Abbott wrote:
> > > Laura Abbott (4):
> > >   arm64: dump: Make ptdump debugfs a separate option
> > >   arm64: dump: Make the page table dumping seq_file optional
> > >   arm64: dump: Remove max_addr
> > >   arm64: dump: Add checking for writable and exectuable pages
> > 
> > Queued for 4.10. Thanks.
> 
> Catalin mentioned to me that he saw some KASAN splats when testing; it
> looks like need a fixup something like the below.

As an aside, it looks like any ptdump usage when KASAN is enabled takes
several minutes, which at boot time looks like a hang.

AFAICT, this is because KASAN allocates *huge* VA ranges (4TB+) worth of
zeroed shadow memory at pte granularity (reusing the same pmd, pud,
tables), and the ptdump code dutifully walks this with, with the added
KASAN instrumentation overhead.

I'll try to dig into that tomorrow; I suspect/hope it's not necessary to
keep all of that mapped.

Thanks,
Mark.


Re: [PATCHv4 0/4] WX checking for arm64

2016-11-07 Thread Catalin Marinas
On Mon, Nov 07, 2016 at 08:26:34AM -0800, Laura Abbott wrote:
> On 11/07/2016 07:38 AM, Mark Rutland wrote:
> >From 06fef1ad1138d0808eec770e64458a350941bd2d Mon Sep 17 00:00:00 2001
> >From: Mark Rutland 
> >Date: Mon, 7 Nov 2016 15:24:40 +
> >Subject: [PATCH] Fix KASAN splats with DEBUG_WX
[...]
> Acked-by: Laura Abbott 

Thanks. I'll queue the patch on top of the others.

-- 
Catalin


Re: [PATCHv4 0/4] WX checking for arm64

2016-11-07 Thread Catalin Marinas
On Mon, Nov 07, 2016 at 08:26:34AM -0800, Laura Abbott wrote:
> On 11/07/2016 07:38 AM, Mark Rutland wrote:
> >From 06fef1ad1138d0808eec770e64458a350941bd2d Mon Sep 17 00:00:00 2001
> >From: Mark Rutland 
> >Date: Mon, 7 Nov 2016 15:24:40 +
> >Subject: [PATCH] Fix KASAN splats with DEBUG_WX
[...]
> Acked-by: Laura Abbott 

Thanks. I'll queue the patch on top of the others.

-- 
Catalin


Re: [PATCHv4 0/4] WX checking for arm64

2016-11-07 Thread Laura Abbott

On 11/07/2016 07:38 AM, Mark Rutland wrote:

On Sun, Oct 30, 2016 at 03:03:07PM +, Catalin Marinas wrote:

On Thu, Oct 27, 2016 at 09:27:30AM -0700, Laura Abbott wrote:

Laura Abbott (4):
  arm64: dump: Make ptdump debugfs a separate option
  arm64: dump: Make the page table dumping seq_file optional
  arm64: dump: Remove max_addr
  arm64: dump: Add checking for writable and exectuable pages


Queued for 4.10. Thanks.


Catalin mentioned to me that he saw some KASAN splats when testing; it
looks like need a fixup something like the below.

Apologies for not having spotted this when testing!

Thanks,
Mark.

>8
From 06fef1ad1138d0808eec770e64458a350941bd2d Mon Sep 17 00:00:00 2001
From: Mark Rutland <mark.rutl...@arm.com>
Date: Mon, 7 Nov 2016 15:24:40 +
Subject: [PATCH] Fix KASAN splats with DEBUG_WX

Booting a kernel built with both CONFIG_KASAN and CONFIG_DEBUG_WX
results in a stream of KASAN splats for stack-out-of-bounds accesses,
e.g.

==
BUG: KASAN: stack-out-of-bounds in note_page+0xd8/0x650 at addr 8009364ebdd0
Read of size 8 by task swapper/0/1
page:7e0024d93ac0 count:0 mapcount:0 mapping:  (null) index:0x0
flags: 0x4000()
page dumped because: kasan: bad access detected
CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.9.0-rc3-4-g25f7267 #77
Hardware name: ARM Juno development board (r1) (DT)
Call trace:
[] dump_backtrace+0x0/0x278
[] show_stack+0x14/0x20
[] dump_stack+0xa4/0xc8
[] kasan_report_error+0x4a8/0x4d0
[] kasan_report+0x40/0x48
[] __asan_load8+0x84/0x98
[] note_page+0xd8/0x650
[] walk_pgd.isra.1+0x114/0x220
[] ptdump_check_wx+0xa8/0x118
[] mark_rodata_ro+0x90/0xd0
[] kernel_init+0x28/0x110
[] ret_from_fork+0x10/0x50
Memory state around the buggy address:
 8009364ebc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 8009364ebd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

8009364ebd80: 00 00 00 00 f1 f1 f1 f1 00 00 f4 f4 f2 f2 f2 f2

 ^
 8009364ebe00: 00 00 00 00 00 00 00 00 f3 f3 f3 f3 00 00 00 00
 8009364ebe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
==

... this happens because note_page assumes that the marker array has at
least two elements (the latter of which may be the terminator), but the
marker array for ptdump_check_wx only contains one element. Thus we
dereference some garbage on the stack when looking at
marker[1].start_address.

Given we don't need the markers for the WX checks, we could modify
note_page to allow for a NULL marker array, but for now it's simpler to
add an entry to the ptdump_check_wx marker array, so let's do that. As
it's somewhat confusing to have two identical entries, we add an initial
entry with a start address of zero.

Reported-by: Catalin Marinas <catalin.mari...@arm.com>
Signed-off-by: Mark Rutland <mark.rutl...@arm.com>
---
 arch/arm64/mm/dump.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c
index ef8aca8..ca74a2a 100644
--- a/arch/arm64/mm/dump.c
+++ b/arch/arm64/mm/dump.c
@@ -383,6 +383,7 @@ void ptdump_check_wx(void)
struct pg_state st = {
.seq = NULL,
.marker = (struct addr_marker[]) {
+   { 0, NULL},
{ -1, NULL},
},
.check_wx = true,



Acked-by: Laura Abbott <labb...@redhat.com>


Re: [PATCHv4 0/4] WX checking for arm64

2016-11-07 Thread Laura Abbott

On 11/07/2016 07:38 AM, Mark Rutland wrote:

On Sun, Oct 30, 2016 at 03:03:07PM +, Catalin Marinas wrote:

On Thu, Oct 27, 2016 at 09:27:30AM -0700, Laura Abbott wrote:

Laura Abbott (4):
  arm64: dump: Make ptdump debugfs a separate option
  arm64: dump: Make the page table dumping seq_file optional
  arm64: dump: Remove max_addr
  arm64: dump: Add checking for writable and exectuable pages


Queued for 4.10. Thanks.


Catalin mentioned to me that he saw some KASAN splats when testing; it
looks like need a fixup something like the below.

Apologies for not having spotted this when testing!

Thanks,
Mark.

>8
From 06fef1ad1138d0808eec770e64458a350941bd2d Mon Sep 17 00:00:00 2001
From: Mark Rutland 
Date: Mon, 7 Nov 2016 15:24:40 +
Subject: [PATCH] Fix KASAN splats with DEBUG_WX

Booting a kernel built with both CONFIG_KASAN and CONFIG_DEBUG_WX
results in a stream of KASAN splats for stack-out-of-bounds accesses,
e.g.

==
BUG: KASAN: stack-out-of-bounds in note_page+0xd8/0x650 at addr 8009364ebdd0
Read of size 8 by task swapper/0/1
page:7e0024d93ac0 count:0 mapcount:0 mapping:  (null) index:0x0
flags: 0x4000()
page dumped because: kasan: bad access detected
CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.9.0-rc3-4-g25f7267 #77
Hardware name: ARM Juno development board (r1) (DT)
Call trace:
[] dump_backtrace+0x0/0x278
[] show_stack+0x14/0x20
[] dump_stack+0xa4/0xc8
[] kasan_report_error+0x4a8/0x4d0
[] kasan_report+0x40/0x48
[] __asan_load8+0x84/0x98
[] note_page+0xd8/0x650
[] walk_pgd.isra.1+0x114/0x220
[] ptdump_check_wx+0xa8/0x118
[] mark_rodata_ro+0x90/0xd0
[] kernel_init+0x28/0x110
[] ret_from_fork+0x10/0x50
Memory state around the buggy address:
 8009364ebc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 8009364ebd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

8009364ebd80: 00 00 00 00 f1 f1 f1 f1 00 00 f4 f4 f2 f2 f2 f2

 ^
 8009364ebe00: 00 00 00 00 00 00 00 00 f3 f3 f3 f3 00 00 00 00
 8009364ebe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
==

... this happens because note_page assumes that the marker array has at
least two elements (the latter of which may be the terminator), but the
marker array for ptdump_check_wx only contains one element. Thus we
dereference some garbage on the stack when looking at
marker[1].start_address.

Given we don't need the markers for the WX checks, we could modify
note_page to allow for a NULL marker array, but for now it's simpler to
add an entry to the ptdump_check_wx marker array, so let's do that. As
it's somewhat confusing to have two identical entries, we add an initial
entry with a start address of zero.

Reported-by: Catalin Marinas 
Signed-off-by: Mark Rutland 
---
 arch/arm64/mm/dump.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c
index ef8aca8..ca74a2a 100644
--- a/arch/arm64/mm/dump.c
+++ b/arch/arm64/mm/dump.c
@@ -383,6 +383,7 @@ void ptdump_check_wx(void)
struct pg_state st = {
.seq = NULL,
.marker = (struct addr_marker[]) {
+   { 0, NULL},
{ -1, NULL},
},
.check_wx = true,



Acked-by: Laura Abbott 


Re: [PATCHv4 0/4] WX checking for arm64

2016-11-07 Thread Mark Rutland
On Sun, Oct 30, 2016 at 03:03:07PM +, Catalin Marinas wrote:
> On Thu, Oct 27, 2016 at 09:27:30AM -0700, Laura Abbott wrote:
> > Laura Abbott (4):
> >   arm64: dump: Make ptdump debugfs a separate option
> >   arm64: dump: Make the page table dumping seq_file optional
> >   arm64: dump: Remove max_addr
> >   arm64: dump: Add checking for writable and exectuable pages
> 
> Queued for 4.10. Thanks.

Catalin mentioned to me that he saw some KASAN splats when testing; it
looks like need a fixup something like the below.

Apologies for not having spotted this when testing!

Thanks,
Mark.

>8
>From 06fef1ad1138d0808eec770e64458a350941bd2d Mon Sep 17 00:00:00 2001
From: Mark Rutland <mark.rutl...@arm.com>
Date: Mon, 7 Nov 2016 15:24:40 +
Subject: [PATCH] Fix KASAN splats with DEBUG_WX

Booting a kernel built with both CONFIG_KASAN and CONFIG_DEBUG_WX
results in a stream of KASAN splats for stack-out-of-bounds accesses,
e.g.

==
BUG: KASAN: stack-out-of-bounds in note_page+0xd8/0x650 at addr 8009364ebdd0
Read of size 8 by task swapper/0/1
page:7e0024d93ac0 count:0 mapcount:0 mapping:  (null) index:0x0
flags: 0x4000()
page dumped because: kasan: bad access detected
CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.9.0-rc3-4-g25f7267 #77
Hardware name: ARM Juno development board (r1) (DT)
Call trace:
[] dump_backtrace+0x0/0x278
[] show_stack+0x14/0x20
[] dump_stack+0xa4/0xc8
[] kasan_report_error+0x4a8/0x4d0
[] kasan_report+0x40/0x48
[] __asan_load8+0x84/0x98
[] note_page+0xd8/0x650
[] walk_pgd.isra.1+0x114/0x220
[] ptdump_check_wx+0xa8/0x118
[] mark_rodata_ro+0x90/0xd0
[] kernel_init+0x28/0x110
[] ret_from_fork+0x10/0x50
Memory state around the buggy address:
 8009364ebc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 8009364ebd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>8009364ebd80: 00 00 00 00 f1 f1 f1 f1 00 00 f4 f4 f2 f2 f2 f2
 ^
 8009364ebe00: 00 00 00 00 00 00 00 00 f3 f3 f3 f3 00 00 00 00
 8009364ebe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
==

... this happens because note_page assumes that the marker array has at
least two elements (the latter of which may be the terminator), but the
marker array for ptdump_check_wx only contains one element. Thus we
dereference some garbage on the stack when looking at
marker[1].start_address.

Given we don't need the markers for the WX checks, we could modify
note_page to allow for a NULL marker array, but for now it's simpler to
add an entry to the ptdump_check_wx marker array, so let's do that. As
it's somewhat confusing to have two identical entries, we add an initial
entry with a start address of zero.

Reported-by: Catalin Marinas <catalin.mari...@arm.com>
Signed-off-by: Mark Rutland <mark.rutl...@arm.com>
---
 arch/arm64/mm/dump.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c
index ef8aca8..ca74a2a 100644
--- a/arch/arm64/mm/dump.c
+++ b/arch/arm64/mm/dump.c
@@ -383,6 +383,7 @@ void ptdump_check_wx(void)
struct pg_state st = {
.seq = NULL,
.marker = (struct addr_marker[]) {
+   { 0, NULL},
{ -1, NULL},
},
.check_wx = true,
-- 
1.9.1



Re: [PATCHv4 0/4] WX checking for arm64

2016-11-07 Thread Mark Rutland
On Sun, Oct 30, 2016 at 03:03:07PM +, Catalin Marinas wrote:
> On Thu, Oct 27, 2016 at 09:27:30AM -0700, Laura Abbott wrote:
> > Laura Abbott (4):
> >   arm64: dump: Make ptdump debugfs a separate option
> >   arm64: dump: Make the page table dumping seq_file optional
> >   arm64: dump: Remove max_addr
> >   arm64: dump: Add checking for writable and exectuable pages
> 
> Queued for 4.10. Thanks.

Catalin mentioned to me that he saw some KASAN splats when testing; it
looks like need a fixup something like the below.

Apologies for not having spotted this when testing!

Thanks,
Mark.

>8
>From 06fef1ad1138d0808eec770e64458a350941bd2d Mon Sep 17 00:00:00 2001
From: Mark Rutland 
Date: Mon, 7 Nov 2016 15:24:40 +
Subject: [PATCH] Fix KASAN splats with DEBUG_WX

Booting a kernel built with both CONFIG_KASAN and CONFIG_DEBUG_WX
results in a stream of KASAN splats for stack-out-of-bounds accesses,
e.g.

==
BUG: KASAN: stack-out-of-bounds in note_page+0xd8/0x650 at addr 8009364ebdd0
Read of size 8 by task swapper/0/1
page:7e0024d93ac0 count:0 mapcount:0 mapping:  (null) index:0x0
flags: 0x4000()
page dumped because: kasan: bad access detected
CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.9.0-rc3-4-g25f7267 #77
Hardware name: ARM Juno development board (r1) (DT)
Call trace:
[] dump_backtrace+0x0/0x278
[] show_stack+0x14/0x20
[] dump_stack+0xa4/0xc8
[] kasan_report_error+0x4a8/0x4d0
[] kasan_report+0x40/0x48
[] __asan_load8+0x84/0x98
[] note_page+0xd8/0x650
[] walk_pgd.isra.1+0x114/0x220
[] ptdump_check_wx+0xa8/0x118
[] mark_rodata_ro+0x90/0xd0
[] kernel_init+0x28/0x110
[] ret_from_fork+0x10/0x50
Memory state around the buggy address:
 8009364ebc80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 8009364ebd00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>8009364ebd80: 00 00 00 00 f1 f1 f1 f1 00 00 f4 f4 f2 f2 f2 f2
 ^
 8009364ebe00: 00 00 00 00 00 00 00 00 f3 f3 f3 f3 00 00 00 00
 8009364ebe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
==

... this happens because note_page assumes that the marker array has at
least two elements (the latter of which may be the terminator), but the
marker array for ptdump_check_wx only contains one element. Thus we
dereference some garbage on the stack when looking at
marker[1].start_address.

Given we don't need the markers for the WX checks, we could modify
note_page to allow for a NULL marker array, but for now it's simpler to
add an entry to the ptdump_check_wx marker array, so let's do that. As
it's somewhat confusing to have two identical entries, we add an initial
entry with a start address of zero.

Reported-by: Catalin Marinas 
Signed-off-by: Mark Rutland 
---
 arch/arm64/mm/dump.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/mm/dump.c b/arch/arm64/mm/dump.c
index ef8aca8..ca74a2a 100644
--- a/arch/arm64/mm/dump.c
+++ b/arch/arm64/mm/dump.c
@@ -383,6 +383,7 @@ void ptdump_check_wx(void)
struct pg_state st = {
.seq = NULL,
.marker = (struct addr_marker[]) {
+   { 0, NULL},
{ -1, NULL},
},
.check_wx = true,
-- 
1.9.1



Re: [PATCHv4 0/4] WX checking for arm64

2016-10-30 Thread Catalin Marinas
On Thu, Oct 27, 2016 at 09:27:30AM -0700, Laura Abbott wrote:
> Laura Abbott (4):
>   arm64: dump: Make ptdump debugfs a separate option
>   arm64: dump: Make the page table dumping seq_file optional
>   arm64: dump: Remove max_addr
>   arm64: dump: Add checking for writable and exectuable pages

Queued for 4.10. Thanks.

-- 
Catalin


Re: [PATCHv4 0/4] WX checking for arm64

2016-10-30 Thread Catalin Marinas
On Thu, Oct 27, 2016 at 09:27:30AM -0700, Laura Abbott wrote:
> Laura Abbott (4):
>   arm64: dump: Make ptdump debugfs a separate option
>   arm64: dump: Make the page table dumping seq_file optional
>   arm64: dump: Remove max_addr
>   arm64: dump: Add checking for writable and exectuable pages

Queued for 4.10. Thanks.

-- 
Catalin


[PATCHv4 0/4] WX checking for arm64

2016-10-27 Thread Laura Abbott
Hi,

This is v4 of the implementation to check for writable and executable pages on
arm64. This version contains a review from Ard and makes the UXN page count
a separate variable. Overall, minor changes.

Thanks,
Laura

Laura Abbott (4):
  arm64: dump: Make ptdump debugfs a separate option
  arm64: dump: Make the page table dumping seq_file optional
  arm64: dump: Remove max_addr
  arm64: dump: Add checking for writable and exectuable pages

 arch/arm64/Kconfig.debug   |  35 -
 arch/arm64/include/asm/ptdump.h|  22 +---
 arch/arm64/mm/Makefile |   3 +-
 arch/arm64/mm/dump.c   | 105 +++--
 arch/arm64/mm/mmu.c|   2 +
 arch/arm64/mm/ptdump_debugfs.c |  31 +++
 drivers/firmware/efi/arm-runtime.c |   4 +-
 7 files changed, 164 insertions(+), 38 deletions(-)
 create mode 100644 arch/arm64/mm/ptdump_debugfs.c

-- 
2.7.4



[PATCHv4 0/4] WX checking for arm64

2016-10-27 Thread Laura Abbott
Hi,

This is v4 of the implementation to check for writable and executable pages on
arm64. This version contains a review from Ard and makes the UXN page count
a separate variable. Overall, minor changes.

Thanks,
Laura

Laura Abbott (4):
  arm64: dump: Make ptdump debugfs a separate option
  arm64: dump: Make the page table dumping seq_file optional
  arm64: dump: Remove max_addr
  arm64: dump: Add checking for writable and exectuable pages

 arch/arm64/Kconfig.debug   |  35 -
 arch/arm64/include/asm/ptdump.h|  22 +---
 arch/arm64/mm/Makefile |   3 +-
 arch/arm64/mm/dump.c   | 105 +++--
 arch/arm64/mm/mmu.c|   2 +
 arch/arm64/mm/ptdump_debugfs.c |  31 +++
 drivers/firmware/efi/arm-runtime.c |   4 +-
 7 files changed, 164 insertions(+), 38 deletions(-)
 create mode 100644 arch/arm64/mm/ptdump_debugfs.c

-- 
2.7.4



[PATCHv3 0/4] WX checking for arm64

2016-10-18 Thread Laura Abbott
Hi,

This is v3 of the implementation to check for writable and executable pages on
arm64. This is a basically a rebase + acks.

Laura Abbott (4):
  arm64: dump: Make ptdump debugfs a separate option
  arm64: dump: Make the page table dumping seq_file optional
  arm64: dump: Remove max_addr
  arm64: dump: Add checking for writable and exectuable pages

 arch/arm64/Kconfig.debug   |  35 -
 arch/arm64/include/asm/ptdump.h|  22 +---
 arch/arm64/mm/Makefile |   3 +-
 arch/arm64/mm/dump.c   | 104 +++--
 arch/arm64/mm/mmu.c|   2 +
 arch/arm64/mm/ptdump_debugfs.c |  31 +++
 drivers/firmware/efi/arm-runtime.c |   5 +-
 7 files changed, 163 insertions(+), 39 deletions(-)
 create mode 100644 arch/arm64/mm/ptdump_debugfs.c

-- 
2.7.4



[PATCHv3 0/4] WX checking for arm64

2016-10-18 Thread Laura Abbott
Hi,

This is v3 of the implementation to check for writable and executable pages on
arm64. This is a basically a rebase + acks.

Laura Abbott (4):
  arm64: dump: Make ptdump debugfs a separate option
  arm64: dump: Make the page table dumping seq_file optional
  arm64: dump: Remove max_addr
  arm64: dump: Add checking for writable and exectuable pages

 arch/arm64/Kconfig.debug   |  35 -
 arch/arm64/include/asm/ptdump.h|  22 +---
 arch/arm64/mm/Makefile |   3 +-
 arch/arm64/mm/dump.c   | 104 +++--
 arch/arm64/mm/mmu.c|   2 +
 arch/arm64/mm/ptdump_debugfs.c |  31 +++
 drivers/firmware/efi/arm-runtime.c |   5 +-
 7 files changed, 163 insertions(+), 39 deletions(-)
 create mode 100644 arch/arm64/mm/ptdump_debugfs.c

-- 
2.7.4



[PATCHv2 0/4] WX checking for arm64

2016-10-12 Thread Laura Abbott
Hi,

This is v2 of the implementation to check for writable and executable pages on
arm64.

Major changes since v1:
- I realized my concerns about initialization and registration were unfounded
  so registration to register page tables with debugfs is simplified.
- New patch to remove max_addr since it was pointed out it was unused.
- Rebased to include changes for the EFI page tables as well.
- Checking is now only done on the init_mm page tables. It was mentioned that
  we should check the hyp page tables as well but that can be follow on work.
- Checking for UXN per suggestion from Mark Rutland.

Laura Abbott (4):
  arm64: dump: Make ptdump debugfs a separate option
  arm64: dump: Make the page table dumping seq_file optional
  arm64: dump: Remove max_addr
  arm64: dump: Add checking for writable and exectuable pages

 arch/arm64/Kconfig.debug   | 34 ++-
 arch/arm64/include/asm/ptdump.h| 22 +++---
 arch/arm64/mm/Makefile |  3 +-
 arch/arm64/mm/dump.c   | 89 ++
 arch/arm64/mm/mmu.c|  2 +
 arch/arm64/mm/ptdump_debugfs.c | 31 +
 drivers/firmware/efi/arm-runtime.c |  5 +--
 7 files changed, 147 insertions(+), 39 deletions(-)
 create mode 100644 arch/arm64/mm/ptdump_debugfs.c

-- 
2.7.4



[PATCHv2 0/4] WX checking for arm64

2016-10-12 Thread Laura Abbott
Hi,

This is v2 of the implementation to check for writable and executable pages on
arm64.

Major changes since v1:
- I realized my concerns about initialization and registration were unfounded
  so registration to register page tables with debugfs is simplified.
- New patch to remove max_addr since it was pointed out it was unused.
- Rebased to include changes for the EFI page tables as well.
- Checking is now only done on the init_mm page tables. It was mentioned that
  we should check the hyp page tables as well but that can be follow on work.
- Checking for UXN per suggestion from Mark Rutland.

Laura Abbott (4):
  arm64: dump: Make ptdump debugfs a separate option
  arm64: dump: Make the page table dumping seq_file optional
  arm64: dump: Remove max_addr
  arm64: dump: Add checking for writable and exectuable pages

 arch/arm64/Kconfig.debug   | 34 ++-
 arch/arm64/include/asm/ptdump.h| 22 +++---
 arch/arm64/mm/Makefile |  3 +-
 arch/arm64/mm/dump.c   | 89 ++
 arch/arm64/mm/mmu.c|  2 +
 arch/arm64/mm/ptdump_debugfs.c | 31 +
 drivers/firmware/efi/arm-runtime.c |  5 +--
 7 files changed, 147 insertions(+), 39 deletions(-)
 create mode 100644 arch/arm64/mm/ptdump_debugfs.c

-- 
2.7.4



Re: [kernel-hardening] [PATCH 0/3] WX Checking for arm64

2016-09-29 Thread Kees Cook
On Thu, Sep 29, 2016 at 2:32 PM, Laura Abbott  wrote:
>
> Hi,
>
> This is an implementation to check for writable and executable pages on arm64.
> This is heavily based on the x86 version which uses the existing page table
> dumping code to do the checking. Some notes:
>
> - The W^X checking is important so this option should become defaut 
> eventually.
>   To make this feasible, the debugfs functionality has been split out as a
>   separate option. I didn't see a good way to make it modular like x86 but
>   an option should be good enough.
> - This checks all page tables registered with ptdump_register. I don't see 
> this
>   being called elsewhere right now though.
> - Once this is merged, I'd like to see about moving DEBUG_WX to the top level
>   instead of having each arch call it in mark_rodata.

Awesome!

Yeah, I think we should take a look at refactoring x86, arm, and arm64
to use a common infrastructure with callbacks. That way other
architectures can gain all these features with just a few callbacks
implemented.

-Kees

>
> Laura Abbott (3):
>   arm64: dump: Make ptdump debugfs a separate option
>   arm64: dump: Make the page table dumping seq_file optional
>   arm64: dump: Add checking for writable and exectuable pages
>
>  arch/arm64/Kconfig.debug| 34 ++-
>  arch/arm64/include/asm/ptdump.h | 25 ++-
>  arch/arm64/mm/Makefile  |  3 +-
>  arch/arm64/mm/dump.c| 92 
> -
>  arch/arm64/mm/mmu.c |  2 +
>  arch/arm64/mm/ptdump_debugfs.c  | 33 +++
>  6 files changed, 157 insertions(+), 32 deletions(-)
>  create mode 100644 arch/arm64/mm/ptdump_debugfs.c
>
> --
> 2.10.0
>



-- 
Kees Cook
Nexus Security


Re: [kernel-hardening] [PATCH 0/3] WX Checking for arm64

2016-09-29 Thread Kees Cook
On Thu, Sep 29, 2016 at 2:32 PM, Laura Abbott  wrote:
>
> Hi,
>
> This is an implementation to check for writable and executable pages on arm64.
> This is heavily based on the x86 version which uses the existing page table
> dumping code to do the checking. Some notes:
>
> - The W^X checking is important so this option should become defaut 
> eventually.
>   To make this feasible, the debugfs functionality has been split out as a
>   separate option. I didn't see a good way to make it modular like x86 but
>   an option should be good enough.
> - This checks all page tables registered with ptdump_register. I don't see 
> this
>   being called elsewhere right now though.
> - Once this is merged, I'd like to see about moving DEBUG_WX to the top level
>   instead of having each arch call it in mark_rodata.

Awesome!

Yeah, I think we should take a look at refactoring x86, arm, and arm64
to use a common infrastructure with callbacks. That way other
architectures can gain all these features with just a few callbacks
implemented.

-Kees

>
> Laura Abbott (3):
>   arm64: dump: Make ptdump debugfs a separate option
>   arm64: dump: Make the page table dumping seq_file optional
>   arm64: dump: Add checking for writable and exectuable pages
>
>  arch/arm64/Kconfig.debug| 34 ++-
>  arch/arm64/include/asm/ptdump.h | 25 ++-
>  arch/arm64/mm/Makefile  |  3 +-
>  arch/arm64/mm/dump.c| 92 
> -
>  arch/arm64/mm/mmu.c |  2 +
>  arch/arm64/mm/ptdump_debugfs.c  | 33 +++
>  6 files changed, 157 insertions(+), 32 deletions(-)
>  create mode 100644 arch/arm64/mm/ptdump_debugfs.c
>
> --
> 2.10.0
>



-- 
Kees Cook
Nexus Security


[PATCH 0/3] WX Checking for arm64

2016-09-29 Thread Laura Abbott

Hi,

This is an implementation to check for writable and executable pages on arm64.
This is heavily based on the x86 version which uses the existing page table
dumping code to do the checking. Some notes:

- The W^X checking is important so this option should become defaut eventually.
  To make this feasible, the debugfs functionality has been split out as a
  separate option. I didn't see a good way to make it modular like x86 but
  an option should be good enough.
- This checks all page tables registered with ptdump_register. I don't see this
  being called elsewhere right now though.
- Once this is merged, I'd like to see about moving DEBUG_WX to the top level
  instead of having each arch call it in mark_rodata.

Laura Abbott (3):
  arm64: dump: Make ptdump debugfs a separate option
  arm64: dump: Make the page table dumping seq_file optional
  arm64: dump: Add checking for writable and exectuable pages

 arch/arm64/Kconfig.debug| 34 ++-
 arch/arm64/include/asm/ptdump.h | 25 ++-
 arch/arm64/mm/Makefile  |  3 +-
 arch/arm64/mm/dump.c| 92 -
 arch/arm64/mm/mmu.c |  2 +
 arch/arm64/mm/ptdump_debugfs.c  | 33 +++
 6 files changed, 157 insertions(+), 32 deletions(-)
 create mode 100644 arch/arm64/mm/ptdump_debugfs.c

-- 
2.10.0



[PATCH 0/3] WX Checking for arm64

2016-09-29 Thread Laura Abbott

Hi,

This is an implementation to check for writable and executable pages on arm64.
This is heavily based on the x86 version which uses the existing page table
dumping code to do the checking. Some notes:

- The W^X checking is important so this option should become defaut eventually.
  To make this feasible, the debugfs functionality has been split out as a
  separate option. I didn't see a good way to make it modular like x86 but
  an option should be good enough.
- This checks all page tables registered with ptdump_register. I don't see this
  being called elsewhere right now though.
- Once this is merged, I'd like to see about moving DEBUG_WX to the top level
  instead of having each arch call it in mark_rodata.

Laura Abbott (3):
  arm64: dump: Make ptdump debugfs a separate option
  arm64: dump: Make the page table dumping seq_file optional
  arm64: dump: Add checking for writable and exectuable pages

 arch/arm64/Kconfig.debug| 34 ++-
 arch/arm64/include/asm/ptdump.h | 25 ++-
 arch/arm64/mm/Makefile  |  3 +-
 arch/arm64/mm/dump.c| 92 -
 arch/arm64/mm/mmu.c |  2 +
 arch/arm64/mm/ptdump_debugfs.c  | 33 +++
 6 files changed, 157 insertions(+), 32 deletions(-)
 create mode 100644 arch/arm64/mm/ptdump_debugfs.c

-- 
2.10.0