linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Salvatore Mesoraca <s.mesoraca16@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: linux-security-module@vger.kernel.org,
	kernel-hardening@lists.openwall.com,
	Salvatore Mesoraca <s.mesoraca16@gmail.com>,
	Brad Spengler <spender@grsecurity.net>,
	PaX Team <pageexec@freemail.hu>,
	Casey Schaufler <casey@schaufler-ca.com>,
	Kees Cook <keescook@chromium.org>,
	James Morris <james.l.morris@oracle.com>,
	"Serge E. Hallyn" <serge@hallyn.com>
Subject: [PATCH 11/11] S.A.R.A. WX Protection procattr interface
Date: Mon, 12 Jun 2017 18:57:00 +0200	[thread overview]
Message-ID: <1497286620-15027-12-git-send-email-s.mesoraca16@gmail.com> (raw)
In-Reply-To: <1497286620-15027-1-git-send-email-s.mesoraca16@gmail.com>

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.mesoraca16@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		0x0000
@@ -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, &req_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(&current->mm->mmap_sem))
+			goto error;
+		for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
+			if (vma->vm_flags & VM_EXEC &&
+			    vma->vm_flags & VM_WRITE) {
+				vma->vm_flags &= ~VM_WRITE;
+				vma_set_page_prot(vma);
+				change_protection(vma,
+						  vma->vm_start,
+						  vma->vm_end,
+						  vma->vm_page_prot,
+						  0,
+						  0);
+			}
+		}
+		up_write(&current->mm->mmap_sem);
+	}
+	get_sara_wxp_flags(new) = req_flags & ~SARA_WXP_FORCE_WXORX;
+	commit_creds(new);
+	ret = size;
+	goto out;
+
+error:
+	abort_creds(new);
+out:
+	kfree(buf);
+	return ret;
+}
+
 static struct security_hook_list wxprot_hooks[] __ro_after_init = {
 	LSM_HOOK_INIT(bprm_set_creds, sara_bprm_set_creds),
 	LSM_HOOK_INIT(check_vmflags, sara_check_vmflags),
@@ -503,6 +624,8 @@ static inline int sara_pagefault_handler_x86_64(struct pt_regs *regs)
 #ifdef CONFIG_SECURITY_SARA_WXPROT_EMUTRAMP
 	LSM_HOOK_INIT(pagefault_handler_x86, sara_pagefault_handler_x86),
 #endif
+	LSM_HOOK_INIT(getprocattr, sara_getprocattr),
+	LSM_HOOK_INIT(setprocattr, sara_setprocattr),
 };
 
 struct binary_config_header {
-- 
1.9.1

  parent reply	other threads:[~2017-06-12 16:59 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-12 16:56 [PATCH 00/11] S.A.R.A. a new stacked LSM Salvatore Mesoraca
2017-06-12 16:56 ` [PATCH 01/11] S.A.R.A. Documentation Salvatore Mesoraca
2017-06-12 17:49   ` [kernel-hardening] " Jann Horn
2017-06-13  7:43     ` Salvatore Mesoraca
2017-06-27 22:51   ` Kees Cook
2017-06-27 22:54     ` Kees Cook
2017-07-04 10:12     ` Salvatore Mesoraca
2017-06-12 16:56 ` [PATCH 02/11] S.A.R.A. framework creation Salvatore Mesoraca
2017-06-12 16:56 ` [PATCH 03/11] Creation of "usb_device_auth" LSM hook Salvatore Mesoraca
2017-06-12 17:35   ` Krzysztof Opasiak
2017-06-13  7:47     ` Salvatore Mesoraca
2017-06-12 19:38   ` Greg Kroah-Hartman
2017-06-13  7:50     ` Salvatore Mesoraca
2017-06-12 21:31   ` Casey Schaufler
2017-06-13  7:51     ` Salvatore Mesoraca
2017-06-13  1:15   ` kbuild test robot
2017-06-13  3:11   ` kbuild test robot
2017-06-12 16:56 ` [PATCH 04/11] S.A.R.A. USB Filtering Salvatore Mesoraca
2017-06-20  7:07   ` Pavel Machek
2017-06-20  7:53     ` Salvatore Mesoraca
2017-06-12 16:56 ` [PATCH 05/11] Creation of "check_vmflags" LSM hook Salvatore Mesoraca
2017-06-12 21:31   ` Casey Schaufler
2017-06-13  7:55     ` Salvatore Mesoraca
2017-06-13  6:34   ` Christoph Hellwig
2017-06-13  7:52     ` Salvatore Mesoraca
2017-06-12 16:56 ` [PATCH 06/11] S.A.R.A. cred blob management Salvatore Mesoraca
2017-06-12 16:56 ` [PATCH 07/11] S.A.R.A. WX Protection Salvatore Mesoraca
2017-06-12 16:56 ` [PATCH 08/11] Creation of "pagefault_handler_x86" LSM hook Salvatore Mesoraca
2017-06-12 17:32   ` Thomas Gleixner
2017-06-13  7:41     ` Salvatore Mesoraca
2017-06-12 16:56 ` [PATCH 09/11] Trampoline emulation Salvatore Mesoraca
2017-06-13  0:02   ` kbuild test robot
2017-06-12 16:56 ` [PATCH 10/11] Allowing for stacking procattr support in S.A.R.A Salvatore Mesoraca
2017-06-12 16:57 ` Salvatore Mesoraca [this message]
2017-07-09 19:35 ` [kernel-hardening] [PATCH 00/11] S.A.R.A. a new stacked LSM Mickaël Salaün
2017-07-10  7:59   ` Salvatore Mesoraca
2017-07-10 23:40     ` Mickaël Salaün
2017-07-11 16:58       ` Salvatore Mesoraca
2017-07-11 17:49         ` Matt Brown
2017-07-11 19:31           ` Mimi Zohar
2017-07-13 12:39             ` Matt Brown
2017-07-13 15:19               ` Mimi Zohar
2017-07-13 19:51                 ` Serge E. Hallyn
2017-07-13 22:33                   ` Matt Brown
2017-07-24  0:58                   ` Casey Schaufler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1497286620-15027-12-git-send-email-s.mesoraca16@gmail.com \
    --to=s.mesoraca16@gmail.com \
    --cc=casey@schaufler-ca.com \
    --cc=james.l.morris@oracle.com \
    --cc=keescook@chromium.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=pageexec@freemail.hu \
    --cc=serge@hallyn.com \
    --cc=spender@grsecurity.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).