Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1663977 > unrolled thread

[PATCH 00/11] S.A.R.A. a new stacked LSM

Started bySalvatore Mesoraca <s.mesoraca16@gmail.com>
First post2017-06-12 19:00 +0200
Last post2017-06-12 19:10 +0200
Articles 5 on this page of 25 — 7 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 00/11] S.A.R.A. a new stacked LSM Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-12 19:00 +0200
    [PATCH 08/11] Creation of "pagefault_handler_x86" LSM hook Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-12 19:00 +0200
      Re: [PATCH 08/11] Creation of "pagefault_handler_x86" LSM hook Thomas Gleixner <tglx@linutronix.de> - 2017-06-12 19:40 +0200
        Re: [PATCH 08/11] Creation of "pagefault_handler_x86" LSM hook Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-13 09:50 +0200
    [PATCH 10/11] Allowing for stacking procattr support in S.A.R.A. Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-12 19:00 +0200
    [PATCH 01/11] S.A.R.A. Documentation Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-12 19:00 +0200
      Re: [kernel-hardening] [PATCH 01/11] S.A.R.A. Documentation Jann Horn <jannh@google.com> - 2017-06-12 19:50 +0200
        Re: [kernel-hardening] [PATCH 01/11] S.A.R.A. Documentation Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-13 09:50 +0200
    [PATCH 09/11] Trampoline emulation Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-12 19:00 +0200
    [PATCH 04/11] S.A.R.A. USB Filtering Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-12 19:00 +0200
    [PATCH 05/11] Creation of "check_vmflags" LSM hook Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-12 19:00 +0200
      Re: [PATCH 05/11] Creation of "check_vmflags" LSM hook Casey Schaufler <casey@schaufler-ca.com> - 2017-06-12 23:40 +0200
        Re: [PATCH 05/11] Creation of "check_vmflags" LSM hook Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-13 10:00 +0200
      Re: [PATCH 05/11] Creation of "check_vmflags" LSM hook Christoph Hellwig <hch@infradead.org> - 2017-06-13 08:40 +0200
        Re: [PATCH 05/11] Creation of "check_vmflags" LSM hook Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-13 10:00 +0200
    [PATCH 02/11] S.A.R.A. framework creation Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-12 19:00 +0200
    [PATCH 03/11] Creation of "usb_device_auth" LSM hook Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-12 19:00 +0200
      Re: [PATCH 03/11] Creation of "usb_device_auth" LSM hook Krzysztof Opasiak <k.opasiak@samsung.com> - 2017-06-12 19:40 +0200
        Re: [PATCH 03/11] Creation of "usb_device_auth" LSM hook Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-13 09:50 +0200
      Re: [PATCH 03/11] Creation of "usb_device_auth" LSM hook Greg Kroah-Hartman <gregkh@linuxfoundation.org> - 2017-06-12 21:40 +0200
        Re: [PATCH 03/11] Creation of "usb_device_auth" LSM hook Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-13 10:00 +0200
      Re: [PATCH 03/11] Creation of "usb_device_auth" LSM hook Casey Schaufler <casey@schaufler-ca.com> - 2017-06-12 23:40 +0200
        Re: [PATCH 03/11] Creation of "usb_device_auth" LSM hook Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-13 10:00 +0200
    [PATCH 07/11] S.A.R.A. WX Protection Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-12 19:00 +0200
    [PATCH 06/11] S.A.R.A. cred blob management Salvatore Mesoraca <s.mesoraca16@gmail.com> - 2017-06-12 19:10 +0200

Page 2 of 2 — ← Prev page 1 [2]


#1664575 — Re: [PATCH 03/11] Creation of "usb_device_auth" LSM hook

FromSalvatore Mesoraca <s.mesoraca16@gmail.com>
Date2017-06-13 10:00 +0200
SubjectRe: [PATCH 03/11] Creation of "usb_device_auth" LSM hook
Message-ID<tROU2-5d9-15@gated-at.bofh.it>
In reply to#1664194
2017-06-12 21:38 GMT+02:00 Greg Kroah-Hartman <gregkh@linuxfoundation.org>:
> No, like Krzysztof said, you can already do this today, just fine, from
> userspace.  I think that support has been there for over a decade now,
> why are you not taking advantage of this already?
> No need to add extra stuff to the kernel at all to do this

Honesty, now that you mention it, I agree with you.
This feature can be implemented in userspace and I'm the first one to
think that what can be implemented in userspace should stay in
userspace.

> sorry you
> implemented all of this for no reason :(

Don't worry, usb filtering is just a small part of this patchset.
Let's hope the rest will end up being more useful. :)

Thank you very much for taking the time to answer me.

[toc] | [prev] | [next] | [standalone]


#1664252 — Re: [PATCH 03/11] Creation of "usb_device_auth" LSM hook

FromCasey Schaufler <casey@schaufler-ca.com>
Date2017-06-12 23:40 +0200
SubjectRe: [PATCH 03/11] Creation of "usb_device_auth" LSM hook
Message-ID<tRFe2-7zG-15@gated-at.bofh.it>
In reply to#1664006
On 6/12/2017 9:56 AM, Salvatore Mesoraca wrote:
> Creation of a new LSM hook that can be used to authorize or deauthorize
> new USB devices via the usb authorization interface.
> The same hook can also prevent the authorization of a USB device via
> "/sys/bus/usb/devices/DEVICE/authorized".
> Using this hook an LSM could provide an higher level of granularity
> than the current authorization interface.
>
> Signed-off-by: Salvatore Mesoraca <s.mesoraca16@gmail.com>
> Cc: linux-usb@vger.kernel.org
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> ---
>  drivers/usb/core/hub.c    | 4 ++++
>  drivers/usb/core/sysfs.c  | 6 +++++-
>  include/linux/lsm_hooks.h | 6 ++++++
>  include/linux/security.h  | 7 +++++++
>  security/security.c       | 5 +++++
>  5 files changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
> index b8bb20d..58be4f0 100644
> --- a/drivers/usb/core/hub.c
> +++ b/drivers/usb/core/hub.c
> @@ -28,6 +28,7 @@
>  #include <linux/mutex.h>
>  #include <linux/random.h>
>  #include <linux/pm_qos.h>
> +#include <linux/security.h>
>  
>  #include <linux/uaccess.h>
>  #include <asm/byteorder.h>
> @@ -4831,6 +4832,9 @@ static void hub_port_connect(struct usb_hub *hub, int port1, u16 portstatus,
>  		if (udev->quirks & USB_QUIRK_DELAY_INIT)
>  			msleep(1000);
>  
> +		if (security_usb_device_auth(udev))
> +			usb_deauthorize_device(udev);
> +
>  		/* consecutive bus-powered hubs aren't reliable; they can
>  		 * violate the voltage drop budget.  if the new child has
>  		 * a "powered" LED, users should notice we didn't enable it
> diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
> index dfc68ed..fce9d39 100644
> --- a/drivers/usb/core/sysfs.c
> +++ b/drivers/usb/core/sysfs.c
> @@ -17,6 +17,7 @@
>  #include <linux/usb.h>
>  #include <linux/usb/quirks.h>
>  #include <linux/of.h>
> +#include <linux/security.h>
>  #include "usb.h"
>  
>  /* Active configuration fields */
> @@ -742,8 +743,11 @@ static ssize_t authorized_store(struct device *dev,
>  		result = -EINVAL;
>  	else if (val == 0)
>  		result = usb_deauthorize_device(usb_dev);
> -	else
> +	else {
> +		if (security_usb_device_auth(usb_dev))
> +			return -EPERM;

Return the error reported by the hook rather than -EPERM.

>  		result = usb_authorize_device(usb_dev);
> +	}
>  	return result < 0 ? result : size;
>  }
>  static DEVICE_ATTR_IGNORE_LOCKDEP(authorized, S_IRUGO | S_IWUSR,
> diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
> index bd274db..cc0937e 100644
> --- a/include/linux/lsm_hooks.h
> +++ b/include/linux/lsm_hooks.h
> @@ -1189,6 +1189,10 @@
>   *	to the @parent process for tracing.
>   *	@parent contains the task_struct structure for debugger process.
>   *	Return 0 if permission is granted.
> + * @usb_device_auth:
> + *	Check if @udev device should be authorized or not.
> + *	@udev contains the usb_device structure for the USB device.
> + *	Return 0 if the device is allowed.
>   * @capget:
>   *	Get the @effective, @inheritable, and @permitted capability sets for
>   *	the @target process.  The hook may also perform permission checking to
> @@ -1352,6 +1356,7 @@
>  	int (*ptrace_access_check)(struct task_struct *child,
>  					unsigned int mode);
>  	int (*ptrace_traceme)(struct task_struct *parent);
> +	int (*usb_device_auth)(const struct usb_device *udev);
>  	int (*capget)(struct task_struct *target, kernel_cap_t *effective,
>  			kernel_cap_t *inheritable, kernel_cap_t *permitted);
>  	int (*capset)(struct cred *new, const struct cred *old,
> @@ -1670,6 +1675,7 @@ struct security_hook_heads {
>  	struct list_head binder_transfer_file;
>  	struct list_head ptrace_access_check;
>  	struct list_head ptrace_traceme;
> +	struct list_head usb_device_auth;
>  	struct list_head capget;
>  	struct list_head capset;
>  	struct list_head capable;
> diff --git a/include/linux/security.h b/include/linux/security.h
> index af675b5..19bc364 100644
> --- a/include/linux/security.h
> +++ b/include/linux/security.h
> @@ -30,6 +30,7 @@
>  #include <linux/string.h>
>  #include <linux/mm.h>
>  #include <linux/fs.h>
> +#include <linux/usb.h>
>  
>  struct linux_binprm;
>  struct cred;
> @@ -196,6 +197,7 @@ int security_binder_transfer_file(struct task_struct *from,
>  				  struct task_struct *to, struct file *file);
>  int security_ptrace_access_check(struct task_struct *child, unsigned int mode);
>  int security_ptrace_traceme(struct task_struct *parent);
> +int security_usb_device_auth(const struct usb_device *udev);
>  int security_capget(struct task_struct *target,
>  		    kernel_cap_t *effective,
>  		    kernel_cap_t *inheritable,
> @@ -434,6 +436,11 @@ static inline int security_ptrace_traceme(struct task_struct *parent)
>  	return cap_ptrace_traceme(parent);
>  }
>  
> +static inline int security_usb_device_auth(const struct usb_device *udev)
> +{
> +	return 0;
> +}
> +
>  static inline int security_capget(struct task_struct *target,
>  				   kernel_cap_t *effective,
>  				   kernel_cap_t *inheritable,
> diff --git a/security/security.c b/security/security.c
> index 42c8028..e390f99 100644
> --- a/security/security.c
> +++ b/security/security.c
> @@ -214,6 +214,11 @@ int security_ptrace_traceme(struct task_struct *parent)
>  	return call_int_hook(ptrace_traceme, 0, parent);
>  }
>  
> +int security_usb_device_auth(const struct usb_device *udev)
> +{
> +	return call_int_hook(usb_device_auth, 0, udev);
> +}
> +
>  int security_capget(struct task_struct *target,
>  		     kernel_cap_t *effective,
>  		     kernel_cap_t *inheritable,

[toc] | [prev] | [next] | [standalone]


#1664578 — Re: [PATCH 03/11] Creation of "usb_device_auth" LSM hook

FromSalvatore Mesoraca <s.mesoraca16@gmail.com>
Date2017-06-13 10:00 +0200
SubjectRe: [PATCH 03/11] Creation of "usb_device_auth" LSM hook
Message-ID<tROU2-5d9-25@gated-at.bofh.it>
In reply to#1664252
2017-06-12 23:31 GMT+02:00 Casey Schaufler <casey@schaufler-ca.com>:
> Return the error reported by the hook rather than -EPERM.

Agreed, anyway this part will be, probably, dropped in
the next version (read Greg and Krzysztof answers).
I'm sorry :(

Thank you very much for the time you spent on this.

[toc] | [prev] | [next] | [standalone]


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

FromSalvatore Mesoraca <s.mesoraca16@gmail.com>
Date2017-06-12 19:00 +0200
Subject[PATCH 07/11] S.A.R.A. WX Protection
Message-ID<tRAR5-4Dh-67@gated-at.bofh.it>
In reply to#1663977
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.mesoraca16@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" if SECURITY_SARA_WXPROT_DEFAULT_FLAGS_ALL_ENFORCE
+	default "0" if SECURITY_SARA_WXPROT_DEFAULT_FLAGS_NONE
+
 endmenu
diff --git a/security/sara/Makefile b/security/sara/Makefile
index 0543390..531b38b 100644
--- a/security/sara/Makefile
+++ b/security/sara/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_SECURITY_SARA) := sara.o
 
 sara-y := main.o securityfs.o utils.o sara_data.o
 sara-$(CONFIG_SECURITY_SARA_USB_FILTERING) += usb_filtering.o
+sara-$(CONFIG_SECURITY_SARA_WXPROT) += wxprot.o
diff --git a/security/sara/include/wxprot.h b/security/sara/include/wxprot.h
new file mode 100644
index 0000000..23b8a7b
--- /dev/null
+++ b/security/sara/include/wxprot.h
@@ -0,0 +1,27 @@
+/*
+ * S.A.R.A. Linux Security Module
+ *
+ * Copyright (C) 2017 Salvatore Mesoraca <s.mesoraca16@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __SARA_WXPROT_H
+#define __SARA_WXPROT_H
+
+#ifdef CONFIG_SECURITY_SARA_WXPROT
+
+#include <linux/init.h>
+int sara_wxprot_init(void) __init;
+
+#else /* CONFIG_SECURITY_SARA_WXPROT */
+inline int sara_wxprot_init(void)
+{
+	return 0;
+}
+#endif /* CONFIG_SECURITY_SARA_WXPROT */
+
+#endif /* __SARA_WXPROT_H */
diff --git a/security/sara/main.c b/security/sara/main.c
index e870c68..7b17167 100644
--- a/security/sara/main.c
+++ b/security/sara/main.c
@@ -17,6 +17,7 @@
 #include "include/sara_data.h"
 #include "include/securityfs.h"
 #include "include/usb_filtering.h"
+#include "include/wxprot.h"
 
 static const int sara_version = SARA_VERSION;
 
@@ -92,6 +93,11 @@ void __init sara_init(void)
 		goto error;
 	}
 
+	if (sara_wxprot_init()) {
+		pr_crit("impossible to initialize WX protections.\n");
+		goto error;
+	}
+
 	pr_debug("initialized.\n");
 
 	if (sara_enabled)
diff --git a/security/sara/wxprot.c b/security/sara/wxprot.c
new file mode 100644
index 0000000..cbeedd3
--- /dev/null
+++ b/security/sara/wxprot.c
@@ -0,0 +1,642 @@
+/*
+ * S.A.R.A. Linux Security Module
+ *
+ * Copyright (C) 2017 Salvatore Mesoraca <s.mesoraca16@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifdef CONFIG_SECURITY_SARA_WXPROT
+
+#include <linux/kref.h>
+#include <linux/lsm_hooks.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/cred.h>
+#include <linux/binfmts.h>
+#include <linux/elf.h>
+#include <linux/spinlock.h>
+
+#include "include/sara.h"
+#include "include/sara_data.h"
+#include "include/utils.h"
+#include "include/securityfs.h"
+#include "include/wxprot.h"
+
+#define SARA_WXPROT_CONFIG_VERSION 0
+
+#define SARA_WXP_HEAP		0x0001
+#define SARA_WXP_STACK		0x0002
+#define SARA_WXP_OTHER		0x0004
+#define SARA_WXP_WXORX		0x0008
+#define SARA_WXP_COMPLAIN	0x0010
+#define SARA_WXP_VERBOSE	0x0020
+#define SARA_WXP_MMAP		0x0040
+#define SARA_WXP_TRANSFER	0x0200
+#define SARA_WXP_NONE		0x0000
+#define SARA_WXP_MPROTECT	(SARA_WXP_HEAP	| \
+				SARA_WXP_STACK	| \
+				SARA_WXP_OTHER)
+#define __SARA_WXP_ALL		(SARA_WXP_MPROTECT	| \
+				SARA_WXP_MMAP		| \
+				SARA_WXP_WXORX		| \
+				SARA_WXP_COMPLAIN	| \
+				SARA_WXP_VERBOSE)
+#define SARA_WXP_ALL		__SARA_WXP_ALL
+
+struct wxprot_rule {
+	char *path;
+	u16 flags;
+	bool exact;
+};
+
+struct wxprot_config_container {
+	u32 rules_size;
+	struct wxprot_rule *rules;
+	size_t buf_len;
+	struct kref refcount;
+	char hash[SARA_CONFIG_HASH_LEN];
+};
+
+static struct wxprot_config_container __rcu *wxprot_config;
+
+static const int wxprot_config_version = SARA_WXPROT_CONFIG_VERSION;
+static bool wxprot_enabled __read_mostly = true;
+static DEFINE_SPINLOCK(wxprot_config_lock);
+
+static u16 default_flags __ro_after_init =
+				CONFIG_SECURITY_SARA_WXPROT_DEFAULT_FLAGS;
+
+static const bool wxprot_emutramp;
+
+#define pr_wxp(MESSAGE) do {					\
+	char *BUF, *PATH;					\
+	PATH = get_current_path(&BUF);				\
+	pr_notice_ratelimited("WXP: %s in '%s' (%d).\n",	\
+			      MESSAGE, PATH, current->pid);	\
+	kvfree(BUF);						\
+} while (0)
+
+static bool are_flags_valid(u16 flags)
+{
+	flags &= ~SARA_WXP_TRANSFER;
+	if (unlikely((flags & SARA_WXP_ALL) != flags))
+		return false;
+	if (unlikely(flags & SARA_WXP_MPROTECT &&
+		     !(flags & SARA_WXP_WXORX)))
+		return false;
+	if (unlikely(flags & (SARA_WXP_COMPLAIN | SARA_WXP_VERBOSE) &&
+		     !(flags & (SARA_WXP_MPROTECT |
+				SARA_WXP_WXORX |
+				SARA_WXP_MMAP))))
+		return false;
+	return true;
+}
+
+static int __init sara_wxprot_enabled_setup(char *str)
+{
+	if (str[0] == '1' && str[1] == '\0')
+		wxprot_enabled = true;
+	else
+		wxprot_enabled = false;
+	return 1;
+}
+__setup("sara_wxprot=", sara_wxprot_enabled_setup);
+
+static int __init sara_wxprot_default_setup(char *str)
+{
+	u16 flags = default_flags;
+
+	if (kstrtou16(str, 0, &flags) != 0 || !are_flags_valid(flags))
+		return 1;
+	default_flags = flags;
+	return 1;
+}
+__setup("sara_wxprot_default_flags=", sara_wxprot_default_setup);
+
+
+/*
+ * MMAP exec restriction
+ */
+#define PT_GNU_RELRO (PT_LOOS + 0x474e552)
+
+union elfh {
+	struct elf32_hdr c32;
+	struct elf64_hdr c64;
+};
+
+union elfp {
+	struct elf32_phdr c32;
+	struct elf64_phdr c64;
+};
+
+#define find_relro_section(ELFH, ELFP, FILE, RELRO, FOUND) do {		\
+	unsigned long i;						\
+	int _tmp;							\
+	if (ELFH.e_type == ET_DYN || ELFH.e_type == ET_EXEC) {		\
+		for (i = 0; i < ELFH.e_phnum; ++i) {			\
+			_tmp = kernel_read(FILE,			\
+				ELFH.e_phoff + i*sizeof(ELFP),		\
+				(char *)&ELFP,				\
+				sizeof(ELFP));				\
+			if (_tmp != sizeof(ELFP))			\
+				break;					\
+			if (ELFP.p_type == PT_GNU_RELRO) {		\
+				RELRO = ELFP.p_offset >> PAGE_SHIFT;	\
+				FOUND = true;				\
+				break;					\
+			}						\
+		}							\
+	}								\
+} while (0)
+
+static int set_relro_page(struct linux_binprm *bprm)
+{
+	union elfh elf_h;
+	union elfp elf_p;
+	unsigned long relro_page = 0;
+	bool relro_page_found = false;
+	int ret;
+
+	ret = kernel_read(bprm->file, 0,
+			(char *)&elf_h,
+			sizeof(elf_h));
+	if (ret == sizeof(elf_h) &&
+	    strncmp(elf_h.c32.e_ident, ELFMAG, SELFMAG) == 0) {
+		if (elf_h.c32.e_ident[EI_CLASS] == ELFCLASS32) {
+			find_relro_section(elf_h.c32,
+					   elf_p.c32,
+					   bprm->file,
+					   relro_page,
+					   relro_page_found);
+		} else if (IS_ENABLED(CONFIG_X86_64) &&
+			   elf_h.c64.e_ident[EI_CLASS] == ELFCLASS64) {
+			find_relro_section(elf_h.c64,
+					   elf_p.c64,
+					   bprm->file,
+					   relro_page,
+					   relro_page_found);
+		}
+	}
+	get_sara_relro_page(bprm->cred) = relro_page;
+	get_sara_relro_page_found(bprm->cred) = relro_page_found;
+	if (relro_page_found)
+		return 0;
+	else
+		return 1;
+}
+
+static inline int is_relro_page(const struct vm_area_struct *vma)
+{
+	if (get_current_sara_relro_page_found() &&
+	    get_current_sara_relro_page() == vma->vm_pgoff)
+		return 1;
+	return 0;
+}
+
+/*
+ * LSM hooks
+ */
+static int sara_bprm_set_creds(struct linux_binprm *bprm)
+{
+	int i;
+	struct wxprot_config_container *c;
+	u16 sara_wxp_flags = default_flags;
+	char *buf = NULL;
+	char *path = NULL;
+
+	sara_wxp_flags = get_sara_wxp_flags(bprm->cred);
+	get_sara_mmap_blocked(bprm->cred) = false;
+	get_sara_relro_page_found(bprm->cred) = false;
+	get_sara_wxp_flags(bprm->cred) = SARA_WXP_NONE;
+
+	if (!sara_enabled || !wxprot_enabled)
+		return 0;
+
+	if (!(sara_wxp_flags & SARA_WXP_TRANSFER)) {
+		sara_wxp_flags = default_flags;
+		path = get_absolute_path(&bprm->file->f_path, &buf);
+		if (IS_ERR(path)) {
+			path = (char *) bprm->interp;
+			if (PTR_ERR(path) == -ENAMETOOLONG)
+				pr_warn_ratelimited("WXP: path too long for '%s'. Default flags will be used.\n",
+						path);
+			else
+				pr_warn_ratelimited("WXP: can't find path for '%s'. Default flags will be used.\n",
+						path);
+			goto skip_flags;
+		}
+		SARA_CONFIG_GET_RCU(c, wxprot_config);
+		for (i = 0; i < c->rules_size; ++i) {
+			if ((c->rules[i].exact &&
+			strcmp(c->rules[i].path, path) == 0) ||
+			(!c->rules[i].exact &&
+			strncmp(c->rules[i].path,
+				path,
+				strlen(c->rules[i].path)) == 0)) {
+				sara_wxp_flags = c->rules[i].flags;
+				/* most specific path always come first */
+				break;
+			}
+		}
+		SARA_CONFIG_PUT_RCU(c);
+	} else
+		path = (char *) bprm->interp;
+
+	if (sara_wxp_flags != default_flags &&
+	    sara_wxp_flags & SARA_WXP_VERBOSE)
+		pr_info_ratelimited("WXP: '%s' run with flags '0x%x'.\n",
+				    path, sara_wxp_flags);
+
+skip_flags:
+	if (set_relro_page(bprm)) {
+		if (sara_wxp_flags & SARA_WXP_VERBOSE &&
+		    sara_wxp_flags & SARA_WXP_MMAP)
+			pr_notice_ratelimited("WXP: failed to find RELRO section in '%s'.\n",
+					      path);
+		sara_wxp_flags &= ~SARA_WXP_MMAP;
+	}
+	kvfree(buf);
+	get_sara_wxp_flags(bprm->cred) = sara_wxp_flags;
+	return 0;
+}
+
+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 1;
+		}
+		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 1;
+		}
+	}
+
+	return 0;
+}
+
+static int sara_file_mprotect(struct vm_area_struct *vma,
+				unsigned long reqprot,
+				unsigned long prot)
+{
+	u16 sara_wxp_flags = get_current_sara_wxp_flags();
+
+	if (!sara_enabled || !wxprot_enabled)
+		return 0;
+
+	if (sara_wxp_flags & SARA_WXP_MPROTECT &&
+	    prot & PROT_EXEC &&
+	    !(vma->vm_flags & VM_EXEC) &&
+	    vma->vm_flags & VM_MAYWRITE) {
+		if ((sara_wxp_flags & SARA_WXP_MPROTECT) == SARA_WXP_MPROTECT &&
+		    !(sara_wxp_flags & SARA_WXP_COMPLAIN) &&
+		    !(sara_wxp_flags & SARA_WXP_VERBOSE))
+			return -EACCES;
+		else if (vma->vm_file) {
+			if (sara_wxp_flags & SARA_WXP_OTHER) {
+				if ((sara_wxp_flags & SARA_WXP_VERBOSE))
+					pr_wxp("mprotect on file mmap");
+				if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
+					return -EACCES;
+			}
+		} else if (vma->vm_start >= vma->vm_mm->start_brk &&
+			vma->vm_end <= vma->vm_mm->brk) {
+			if (sara_wxp_flags & SARA_WXP_HEAP) {
+				if ((sara_wxp_flags & SARA_WXP_VERBOSE))
+					pr_wxp("mprotect on heap");
+				if (!(sara_wxp_flags &
+					SARA_WXP_COMPLAIN))
+					return -EACCES;
+			}
+		} else if ((vma->vm_start <= vma->vm_mm->start_stack &&
+			    vma->vm_end >= vma->vm_mm->start_stack) ||
+			   vma_is_stack_for_current(vma)) {
+			if (sara_wxp_flags & SARA_WXP_STACK) {
+				if ((sara_wxp_flags &
+					SARA_WXP_VERBOSE))
+					pr_wxp("mprotect on stack");
+				if (!(sara_wxp_flags &
+					SARA_WXP_COMPLAIN))
+					return -EACCES;
+			}
+		} else if (sara_wxp_flags & SARA_WXP_OTHER) {
+			if ((sara_wxp_flags & SARA_WXP_VERBOSE))
+				pr_wxp("mprotect on anon mmap");
+			if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
+				return -EACCES;
+		}
+	}
+
+	if (sara_wxp_flags & SARA_WXP_WXORX &&
+	    prot & PROT_EXEC &&
+	    prot & PROT_WRITE &&
+	    (!(vma->vm_flags & VM_EXEC) ||
+	     !(vma->vm_flags & VM_WRITE))) {
+		if ((sara_wxp_flags & SARA_WXP_VERBOSE))
+			pr_wxp("W^X");
+		if (!(sara_wxp_flags & SARA_WXP_COMPLAIN))
+			return -EACCES;
+	}
+
+	if (vma->vm_flags & VM_WRITE &&
+	    !(prot & PROT_WRITE) &&
+	    is_relro_page(vma))
+		get_current_sara_mmap_blocked() = true;
+
+	return 0;
+}
+
+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),
+	LSM_HOOK_INIT(file_mprotect, sara_file_mprotect),
+};
+
+struct binary_config_header {
+	char magic[8];
+	__le32 version;
+	__le32 rules_size;
+	char hash[SARA_CONFIG_HASH_LEN];
+} __packed;
+
+struct binary_config_rule {
+	__le16 path_len;
+	__le16 flags;
+	u8 exact;
+} __packed;
+
+static void config_free(struct wxprot_config_container *data)
+{
+	int i;
+
+	for (i = 0; i < data->rules_size; ++i)
+		kfree(data->rules[i].path);
+	kvfree(data->rules);
+	kfree(data);
+}
+
+static int config_load(const char *buf, size_t buf_len)
+{
+	int ret;
+	int i;
+	int path_len;
+	size_t inc;
+	size_t last_path_len = SARA_PATH_MAX;
+	bool last_exact = true;
+	const char *pos;
+	struct wxprot_config_container *new;
+	struct binary_config_header *h;
+	struct binary_config_rule *r;
+
+	ret = -EINVAL;
+	if (unlikely(buf_len < sizeof(*h)))
+		goto out;
+
+	h = (struct binary_config_header *) buf;
+	pos = buf + sizeof(*h);
+
+	ret = -EINVAL;
+	if (unlikely(memcmp(h->magic, "SARAWXPR", 8) != 0))
+		goto out;
+	if (unlikely(le32_to_cpu(h->version) != wxprot_config_version))
+		goto out;
+
+	ret = -ENOMEM;
+	new = kmalloc(sizeof(*new), GFP_KERNEL);
+	if (unlikely(new == NULL))
+		goto out;
+	kref_init(&new->refcount);
+	new->rules_size = le32_to_cpu(h->rules_size);
+	BUILD_BUG_ON(sizeof(new->hash) != sizeof(h->hash));
+	memcpy(new->hash, h->hash, sizeof(new->hash));
+	if (unlikely(new->rules_size == 0)) {
+		new->rules = NULL;
+		goto replace;
+	}
+
+	ret = -ENOMEM;
+	new->rules = sara_kvcalloc(new->rules_size,
+				   sizeof(*new->rules));
+	if (unlikely(new->rules == NULL))
+		goto out_new;
+	for (i = 0; i < new->rules_size; ++i) {
+		r = (struct binary_config_rule *) pos;
+		pos += sizeof(*r);
+		inc = pos-buf;
+		path_len = le16_to_cpu(r->path_len);
+		new->rules[i].flags = le16_to_cpu(r->flags);
+		new->rules[i].exact = r->exact;
+
+		ret = -EINVAL;
+		if (unlikely(inc + path_len > buf_len))
+			goto out_rules;
+		if (unlikely(path_len > last_path_len))
+			goto out_rules;
+		if (unlikely((int) new->rules[i].exact != 0 &&
+			     (int) new->rules[i].exact != 1))
+			goto out_rules;
+		if (unlikely(path_len == last_path_len &&
+			     new->rules[i].exact &&
+			     !last_exact))
+			goto out_rules;
+		if (!are_flags_valid(new->rules[i].flags))
+			goto out_rules;
+
+		ret = -ENOMEM;
+		new->rules[i].path = kmalloc(path_len+1, GFP_KERNEL);
+		if (unlikely(new->rules[i].path == NULL))
+			goto out_rules;
+		memcpy(new->rules[i].path, pos, path_len);
+		new->rules[i].path[path_len] = '\0';
+		if (i > 0 &&
+		    unlikely(new->rules[i].exact == new->rules[i-1].exact &&
+			     strcmp(new->rules[i].path,
+				    new->rules[i-1].path) == 0))
+			goto out_rules;
+		pos += path_len;
+		last_path_len = path_len;
+		last_exact = new->rules[i].exact;
+	}
+	new->buf_len = (size_t) (pos-buf);
+
+replace:
+	SARA_CONFIG_REPLACE(wxprot_config,
+			    new,
+			    config_free,
+			    &wxprot_config_lock);
+	pr_notice("WXP: new rules loaded.\n");
+	return 0;
+
+out_rules:
+	for (i = 0; i < new->rules_size; ++i)
+		kfree(new->rules[i].path);
+	kvfree(new->rules);
+out_new:
+	kfree(new);
+out:
+	pr_notice("WXP: failed to load rules.\n");
+	return ret;
+}
+
+static ssize_t config_dump(char **buf)
+{
+	int i;
+	ssize_t ret;
+	size_t buf_len;
+	char *pos;
+	char *mybuf;
+	u16 path_len;
+	int rulen;
+	struct wxprot_config_container *c;
+	struct wxprot_rule *rc;
+	struct binary_config_header *h;
+	struct binary_config_rule *r;
+
+	ret = -ENOMEM;
+	SARA_CONFIG_GET(c, wxprot_config);
+	buf_len = c->buf_len;
+	mybuf = sara_kvmalloc(buf_len);
+	if (unlikely(mybuf == NULL))
+		goto out;
+	rulen = c->rules_size;
+	h = (struct binary_config_header *) mybuf;
+	memcpy(h->magic, "SARAWXPR", 8);
+	h->version = cpu_to_le32(SARA_WXPROT_CONFIG_VERSION);
+	h->rules_size = cpu_to_le32(rulen);
+	BUILD_BUG_ON(sizeof(c->hash) != sizeof(h->hash));
+	memcpy(h->hash, c->hash, sizeof(h->hash));
+	pos = mybuf + sizeof(*h);
+	for (i = 0; i < rulen; ++i) {
+		r = (struct binary_config_rule *) pos;
+		pos += sizeof(*r);
+		if (buf_len < (pos - mybuf))
+			goto out;
+		rc = &c->rules[i];
+		r->flags = cpu_to_le16(rc->flags);
+		r->exact = (u8) rc->exact;
+		path_len = strlen(rc->path);
+		r->path_len = cpu_to_le16(path_len);
+		if (buf_len < ((pos - mybuf) + path_len))
+			goto out;
+		memcpy(pos, rc->path, path_len);
+		pos += path_len;
+	}
+	ret = (ssize_t) (pos - mybuf);
+	*buf = mybuf;
+out:
+	SARA_CONFIG_PUT(c, config_free);
+	return ret;
+}
+
+static int config_hash(char **buf)
+{
+	int ret;
+	struct wxprot_config_container *config;
+
+	ret = -ENOMEM;
+	*buf = kzalloc(sizeof(config->hash), GFP_KERNEL);
+	if (unlikely(*buf == NULL))
+		goto out;
+
+	SARA_CONFIG_GET_RCU(config, wxprot_config);
+	memcpy(*buf, config->hash, sizeof(config->hash));
+	SARA_CONFIG_PUT_RCU(config);
+
+	ret = 0;
+out:
+	return ret;
+}
+
+static DEFINE_SARA_SECFS_BOOL_FLAG(wxprot_enabled_data,
+				   wxprot_enabled);
+
+static struct sara_secfs_fptrs fptrs __ro_after_init = {
+	.load = config_load,
+	.dump = config_dump,
+	.hash = config_hash,
+};
+
+static const struct sara_secfs_node wxprot_fs[] __initconst = {
+	{
+		.name = "enabled",
+		.type = SARA_SECFS_BOOL,
+		.data = (void *) &wxprot_enabled_data,
+	},
+	{
+		.name = "version",
+		.type = SARA_SECFS_READONLY_INT,
+		.data = (int *) &wxprot_config_version,
+	},
+	{
+		.name = "default_flags",
+		.type = SARA_SECFS_READONLY_INT,
+		.data = &default_flags,
+	},
+	{
+		.name = "emutramp_available",
+		.type = SARA_SECFS_READONLY_INT,
+		.data = (int *) &wxprot_emutramp,
+	},
+	{
+		.name = ".load",
+		.type = SARA_SECFS_CONFIG_LOAD,
+		.data = &fptrs,
+	},
+	{
+		.name = ".dump",
+		.type = SARA_SECFS_CONFIG_DUMP,
+		.data = &fptrs,
+	},
+	{
+		.name = "hash",
+		.type = SARA_SECFS_CONFIG_HASH,
+		.data = &fptrs,
+	},
+};
+
+
+int __init sara_wxprot_init(void)
+{
+	int ret;
+	struct wxprot_config_container *tmpc;
+
+	ret = -EINVAL;
+	if (!are_flags_valid(default_flags))
+		goto out_fail;
+	ret = -ENOMEM;
+	tmpc = kzalloc(sizeof(*tmpc), GFP_KERNEL);
+	if (unlikely(tmpc == NULL))
+		goto out_fail;
+	tmpc->buf_len = sizeof(struct binary_config_header);
+	kref_init(&tmpc->refcount);
+	wxprot_config = (struct wxprot_config_container __rcu *) tmpc;
+	ret = sara_secfs_subtree_register("wxprot",
+					  wxprot_fs,
+					  ARRAY_SIZE(wxprot_fs));
+	if (unlikely(ret))
+		goto out_fail;
+	security_add_hooks(wxprot_hooks, ARRAY_SIZE(wxprot_hooks), "sara");
+	return 0;
+
+out_fail:
+	kfree(tmpc);
+	return ret;
+}
+
+#endif /* CONFIG_SECURITY_SARA_WXPROT */
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1664032 — [PATCH 06/11] S.A.R.A. cred blob management

FromSalvatore Mesoraca <s.mesoraca16@gmail.com>
Date2017-06-12 19:10 +0200
Subject[PATCH 06/11] S.A.R.A. cred blob management
Message-ID<tRB0L-4VC-47@gated-at.bofh.it>
In reply to#1663977
Creation of the S.A.R.A. cred blob management "API".
In order to allow S.A.R.A. to be stackable with other LSMs, it doesn't use
the "security" field of struct cred, instead it uses an ad hoc field named
security_sara.
This solution is probably not acceptable for upstream, so this part will
be modified as soon as the LSM stackable cred blob management will be
available.

Signed-off-by: Salvatore Mesoraca <s.mesoraca16@gmail.com>
---
 include/linux/cred.h              |  3 ++
 security/sara/Makefile            |  2 +-
 security/sara/include/sara_data.h | 47 +++++++++++++++++++++++
 security/sara/main.c              |  6 +++
 security/sara/sara_data.c         | 79 +++++++++++++++++++++++++++++++++++++++
 5 files changed, 136 insertions(+), 1 deletion(-)
 create mode 100644 security/sara/include/sara_data.h
 create mode 100644 security/sara/sara_data.c

diff --git a/include/linux/cred.h b/include/linux/cred.h
index b03e7d0..007feb5 100644
--- a/include/linux/cred.h
+++ b/include/linux/cred.h
@@ -141,6 +141,9 @@ struct cred {
 #ifdef CONFIG_SECURITY
 	void		*security;	/* subjective LSM security */
 #endif
+#ifdef CONFIG_SECURITY_SARA
+	void		*security_sara;
+#endif
 	struct user_struct *user;	/* real user ID subscription */
 	struct user_namespace *user_ns; /* user_ns the caps and keyrings are relative to. */
 	struct group_info *group_info;	/* supplementary groups for euid/fsgid */
diff --git a/security/sara/Makefile b/security/sara/Makefile
index 8acf8a9..0543390 100644
--- a/security/sara/Makefile
+++ b/security/sara/Makefile
@@ -1,4 +1,4 @@
 obj-$(CONFIG_SECURITY_SARA) := sara.o
 
-sara-y := main.o securityfs.o utils.o
+sara-y := main.o securityfs.o utils.o sara_data.o
 sara-$(CONFIG_SECURITY_SARA_USB_FILTERING) += usb_filtering.o
diff --git a/security/sara/include/sara_data.h b/security/sara/include/sara_data.h
new file mode 100644
index 0000000..7ed04fd
--- /dev/null
+++ b/security/sara/include/sara_data.h
@@ -0,0 +1,47 @@
+/*
+ * S.A.R.A. Linux Security Module
+ *
+ * Copyright (C) 2017 Salvatore Mesoraca <s.mesoraca16@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __SARA_DATA_H
+#define __SARA_DATA_H
+
+#include <linux/init.h>
+
+int sara_data_init(void) __init;
+
+#ifdef CONFIG_SECURITY_SARA_WXPROT
+
+struct sara_data {
+	unsigned long	relro_page;
+	u16		wxp_flags;
+	bool		relro_page_found;
+	bool		mmap_blocked;
+};
+
+#define get_sara_data_leftvalue(X) ((X)->security_sara)
+#define get_sara_data(X) ((struct sara_data *) (X)->security_sara)
+#define get_current_sara_data() get_sara_data(current_cred())
+
+#define get_sara_wxp_flags(X) (get_sara_data((X))->wxp_flags)
+#define get_current_sara_wxp_flags() get_sara_wxp_flags(current_cred())
+
+#define get_sara_relro_page(X) (get_sara_data((X))->relro_page)
+#define get_current_sara_relro_page() get_sara_relro_page(current_cred())
+
+#define get_sara_relro_page_found(X) (get_sara_data((X))->relro_page_found)
+#define get_current_sara_relro_page_found() \
+	get_sara_relro_page_found(current_cred())
+
+#define get_sara_mmap_blocked(X) (get_sara_data((X))->mmap_blocked)
+#define get_current_sara_mmap_blocked() get_sara_mmap_blocked(current_cred())
+
+#endif
+
+#endif /* __SARA_H */
diff --git a/security/sara/main.c b/security/sara/main.c
index 8783c3c..e870c68 100644
--- a/security/sara/main.c
+++ b/security/sara/main.c
@@ -14,6 +14,7 @@
 #include <linux/printk.h>
 
 #include "include/sara.h"
+#include "include/sara_data.h"
 #include "include/securityfs.h"
 #include "include/usb_filtering.h"
 
@@ -81,6 +82,11 @@ void __init sara_init(void)
 		goto error;
 	}
 
+	if (sara_data_init()) {
+		pr_crit("impossible to initialize creds.\n");
+		goto error;
+	}
+
 	if (sara_usb_filtering_init()) {
 		pr_crit("impossible to initialize usb filtering.\n");
 		goto error;
diff --git a/security/sara/sara_data.c b/security/sara/sara_data.c
new file mode 100644
index 0000000..8f11cd1
--- /dev/null
+++ b/security/sara/sara_data.c
@@ -0,0 +1,79 @@
+/*
+ * S.A.R.A. Linux Security Module
+ *
+ * Copyright (C) 2017 Salvatore Mesoraca <s.mesoraca16@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include "include/sara_data.h"
+
+#ifdef CONFIG_SECURITY_SARA_WXPROT
+#include <linux/cred.h>
+#include <linux/lsm_hooks.h>
+#include <linux/mm.h>
+
+static int sara_cred_alloc_blank(struct cred *cred, gfp_t gfp)
+{
+	struct sara_data *d;
+
+	d = kzalloc(sizeof(*d), gfp);
+	if (d == NULL)
+		return -ENOMEM;
+	get_sara_data_leftvalue(cred) = d;
+	return 0;
+}
+
+static void sara_cred_free(struct cred *cred)
+{
+	struct sara_data *d;
+
+	d = get_sara_data(cred);
+	if (d != NULL) {
+		kfree(d);
+		get_sara_data_leftvalue(cred) = NULL;
+	}
+}
+
+static int sara_cred_prepare(struct cred *new, const struct cred *old,
+			     gfp_t gfp)
+{
+	struct sara_data *d;
+
+	d = kmemdup(get_sara_data(old), sizeof(*d), gfp);
+	if (d == NULL)
+		return -ENOMEM;
+	get_sara_data_leftvalue(new) = d;
+	return 0;
+}
+
+static void sara_cred_transfer(struct cred *new, const struct cred *old)
+{
+	*get_sara_data(new) = *get_sara_data(old);
+}
+
+static struct security_hook_list data_hooks[] __ro_after_init = {
+	LSM_HOOK_INIT(cred_alloc_blank, sara_cred_alloc_blank),
+	LSM_HOOK_INIT(cred_free, sara_cred_free),
+	LSM_HOOK_INIT(cred_prepare, sara_cred_prepare),
+	LSM_HOOK_INIT(cred_transfer, sara_cred_transfer),
+};
+
+int __init sara_data_init(void)
+{
+	security_add_hooks(data_hooks, ARRAY_SIZE(data_hooks), "sara");
+	return sara_cred_alloc_blank((struct cred *) current->real_cred,
+				     GFP_KERNEL);
+}
+
+#else /* CONFIG_SECURITY_SARA_WXPROT */
+
+int __init sara_data_init(void)
+{
+	return 0;
+}
+
+#endif
-- 
1.9.1

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

Back to top | Article view | linux.kernel


csiph-web