linux-security-module.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: zohar@linux.vnet.ibm.com (Mimi Zohar)
To: linux-security-module@vger.kernel.org
Subject: [PATCH v1] shebang: restrict python interactive prompt/interpreter
Date: Fri, 09 Jun 2017 09:22:08 -0400	[thread overview]
Message-ID: <1497014528.21594.190.camel@linux.vnet.ibm.com> (raw)

This patch defines a new, minor LSM named "shebang", that restricts
python such that scripts are allowed to execute, while the interactive
prompt/interpreter is not available.  When used in conjunction with an
IMA appraise execute policy requiring files signatures, only signed
python scripts would be allowed to execute.  (A separate method for
identifying "imported" code would need to be defined in order to verify
their file signatures.)

A blank/comma delimited list of interpreter pathnames is converted to
a list of inodes, which is used to detect and prevent the interactive
prompt/interpreter's usage.

Mimi Zohar <zohar@linux.vnet.ibm.com>
---
 security/Kconfig                  |   1 +
 security/Makefile                 |   2 +
 security/shebang/Kconfig          |  16 ++++++
 security/shebang/Makefile         |   3 +
 security/shebang/shebang_python.c | 117 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 139 insertions(+)
 create mode 100644 security/shebang/Kconfig
 create mode 100644 security/shebang/Makefile
 create mode 100644 security/shebang/shebang_python.c

diff --git a/security/Kconfig b/security/Kconfig
index bdcbb92927ab..4453299c430e 100644
--- a/security/Kconfig
+++ b/security/Kconfig
@@ -195,6 +195,7 @@ source security/tomoyo/Kconfig
 source security/apparmor/Kconfig
 source security/loadpin/Kconfig
 source security/yama/Kconfig
+source security/shebang/Kconfig
 
 source security/integrity/Kconfig
 
diff --git a/security/Makefile b/security/Makefile
index f2d71cdb8e19..00a8dbebb07f 100644
--- a/security/Makefile
+++ b/security/Makefile
@@ -9,6 +9,7 @@ subdir-$(CONFIG_SECURITY_TOMOYO)        += tomoyo
 subdir-$(CONFIG_SECURITY_APPARMOR)	+= apparmor
 subdir-$(CONFIG_SECURITY_YAMA)		+= yama
 subdir-$(CONFIG_SECURITY_LOADPIN)	+= loadpin
+subdir-$(CONFIG_SECURITY_SHEBANG)	+= shebang
 
 # always enable default capabilities
 obj-y					+= commoncap.o
@@ -24,6 +25,7 @@ obj-$(CONFIG_SECURITY_TOMOYO)		+= tomoyo/
 obj-$(CONFIG_SECURITY_APPARMOR)		+= apparmor/
 obj-$(CONFIG_SECURITY_YAMA)		+= yama/
 obj-$(CONFIG_SECURITY_LOADPIN)		+= loadpin/
+obj-$(CONFIG_SECURITY_SHEBANG)		+= shebang/
 obj-$(CONFIG_CGROUP_DEVICE)		+= device_cgroup.o
 
 # Object integrity file lists
diff --git a/security/shebang/Kconfig b/security/shebang/Kconfig
new file mode 100644
index 000000000000..1b977b266413
--- /dev/null
+++ b/security/shebang/Kconfig
@@ -0,0 +1,16 @@
+config SECURITY_SHEBANG
+	bool "Restrict python interactive prompt/interpreter"
+	depends on SECURITY
+	help
+	  Restrict python so that python scripts are allowed to execute,
+	  while the interactive prompt/interpreter is not available.  When
+	  used in conjunction with an IMA appraise policy requiring files
+	  signatures, only signed scripts will be executed.
+
+config SECURITY_SHEBANG_PATHNAME
+	string "interactive prompt/interpreter pathname"
+	depends on SECURITY_SHEBANG
+	default "/usr/bin/python2, /usr/bin/python3"
+	help
+	  This option defines a blank/comma delimited list of
+	  interpreter pathnames.
diff --git a/security/shebang/Makefile b/security/shebang/Makefile
new file mode 100644
index 000000000000..f1b83dcb96d1
--- /dev/null
+++ b/security/shebang/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_SECURITY_SHEBANG) += shebang.o
+
+shebang-y := shebang_python.o
diff --git a/security/shebang/shebang_python.c b/security/shebang/shebang_python.c
new file mode 100644
index 000000000000..6f98cce38ea4
--- /dev/null
+++ b/security/shebang/shebang_python.c
@@ -0,0 +1,117 @@
+/*
+ * shebang security module
+ *
+ * Copyright (C) 2017 IBM Corporation
+ *
+ * Authors:
+ * Mimi Zohar <zohar@linux.vnet.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#define pr_fmt(fmt) "shebang: " fmt
+
+#include <linux/module.h>
+#include <linux/binfmts.h>
+#include <linux/namei.h>
+#include <linux/lsm_hooks.h>
+
+static int initialized;
+
+#define MAX_INODES 6 
+static char *pathnames;
+static int pathnames_len;
+static unsigned long inode_list[MAX_INODES];
+static int total;
+
+/*
+ * Get the inodes associated with the list of pathnames, as specified
+ * on CONFIG_SECURITY_SHEBANG_PATHNAME.
+ */
+static void init_inode_list(void)
+{
+	char *tmp_pathnames = pathnames;
+	char *p;
+	struct path path;
+	int i;
+	int ret;
+
+	total = 0;
+	while ((p = strsep(&tmp_pathnames, " ,")) != NULL) {
+		if ((*p == '\0') || (*p == ' ') || (*p == ','))
+			continue;
+
+		if (total > MAX_INODES - 1) {
+			pr_info("too many interpreters\n");
+			break;
+		}
+
+		ret = kern_path(p, LOOKUP_FOLLOW, &path);
+		if (!ret) {
+			struct inode *inode = d_backing_inode(path.dentry);
+
+			inode_list[total] = inode->i_ino;
+			pr_info("pathname:%s i_ino: %lu\n",
+				p, inode_list[total]);
+			initialized = 1;
+			total++;
+		}
+	}
+
+	/* cleanup in case we need to lookup the inodes again. */
+	tmp_pathnames = pathnames;
+	for (i = 0; i < pathnames_len; i++)
+		if (tmp_pathnames[i] == '\0')
+			tmp_pathnames[i] = ' ';
+}
+
+/**
+ * shebang_bprm_check - prevent python interactive prompt/interpreter
+ * @bprm: contains the linux_binprm structure
+ *
+ * Restrict python such that scripts are allowed to execute, while the
+ * interactive prompt/interpreter is not available.
+ */
+static int shebang_bprm_check(struct linux_binprm *bprm)
+{
+	struct inode *inode = file_inode(bprm->file);
+	int i = 0;
+
+	if (bprm->interp != bprm->filename)	/* allow scripts */
+		return 0;
+
+	if (!initialized)
+		init_inode_list();
+
+	while (i < total) {
+		if (inode_list[i++] != inode->i_ino)
+			continue;
+
+		pr_info("prevent executing %s (ino=%lu)\n",
+			bprm->interp, inode->i_ino);
+		return -EPERM;
+	}
+	return 0;
+}
+
+static struct security_hook_list shebang_hooks[] = {
+	LSM_HOOK_INIT(bprm_check_security, shebang_bprm_check)
+};
+
+static int __init init_shebang(void)
+{
+	pathnames = kstrdup(CONFIG_SECURITY_SHEBANG_PATHNAME, GFP_KERNEL);
+	if (!pathnames)
+		return -ENOMEM;
+	pathnames_len = strlen(pathnames);
+
+	security_add_hooks(shebang_hooks, ARRAY_SIZE(shebang_hooks), "shebang");
+	pr_info("initialized\n");
+	return 0;
+}
+
+late_initcall(init_shebang);
+MODULE_LICENSE("GPL");
-- 
2.7.4

--
To unsubscribe from this list: send the line "unsubscribe linux-security-module" in
the body of a message to majordomo at vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

             reply	other threads:[~2017-06-09 13:22 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-09 13:22 Mimi Zohar [this message]
2017-06-09 14:02 ` [PATCH v1] shebang: restrict python interactive prompt/interpreter Tetsuo Handa
2017-06-09 14:50   ` Matt Brown
2017-06-09 15:41     ` Tetsuo Handa
2017-06-09 16:37       ` Matt Brown
2017-06-09 16:43         ` Jason Zaman
2017-06-09 17:23           ` Matt Brown
2017-06-09 23:04             ` Tetsuo Handa
2017-06-10  1:56             ` Kees Cook
2017-06-10  5:27               ` Tetsuo Handa
2017-06-12  0:34                 ` Matt Brown
     [not found]                 ` <d9aca46b-97c6-4faf-b559-484feb4aa640@digikod.net>
2017-06-12  2:32                   ` Mimi Zohar
2017-06-12 14:27                     ` Mimi Zohar
2017-06-14 14:10                       ` Alan Cox
2017-06-14 20:37                         ` [kernel-hardening] " Boris Lukashev
     [not found]                     ` <8a2300ef-1462-0e1f-2d6a-81e6020bc71f@digikod.net>
2017-06-13 21:44                       ` Casey Schaufler
2017-06-10  1:49     ` Tetsuo Handa
2017-06-09 15:06   ` Mimi Zohar
2017-06-09 15:23     ` Tetsuo Handa

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=1497014528.21594.190.camel@linux.vnet.ibm.com \
    --to=zohar@linux.vnet.ibm.com \
    --cc=linux-security-module@vger.kernel.org \
    /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).