All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kentaro Takeda <takedakn@nttdata.co.jp>
To: linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org
Cc: chrisw@sous-sol.org
Subject: [TOMOYO 11/15](repost) Signal transmission control functions.
Date: Tue, 02 Oct 2007 16:37:45 +0900	[thread overview]
Message-ID: <4701F549.6060602@nttdata.co.jp> (raw)
In-Reply-To: <4701F285.5000206@nttdata.co.jp>

Signal control functions for TOMOYO Linux.
TOMOYO Linux checks sending signal by signal number and
the domain of target process. In order to check signal
permission, LSM expansion patch [TOMOYO 14/15] is needed.

Each permission can be automatically accumulated into
the policy of each domain using 'learning mode'.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
 security/tomoyo/signal.c |  229 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 229 insertions(+)

--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6/security/tomoyo/signal.c	2007-10-02 11:26:22.000000000 +0900
@@ -0,0 +1,229 @@
+/*
+ * security/tomoyo/signal.c
+ *
+ * Signal access contol functions for TOMOYO Linux.
+ */
+
+#include "tomoyo.h"
+#include "realpath.h"
+
+/*************************  AUDIT FUNCTIONS  *************************/
+
+static int tmy_audit_signal_log(const int signal,
+				const struct path_info *dest_domain,
+				const u8 is_granted,
+				const u8 is_enforce)
+{
+	char *buf;
+	int len;
+
+	if (is_granted) {
+		if (!tmy_audit_grant())
+			return 0;
+	} else {
+		if (!tmy_audit_reject())
+			return 0;
+	}
+
+	len = dest_domain->total_len;
+	buf = tmy_init_audit_log(&len);
+
+	if (!buf)
+		return -ENOMEM;
+
+	snprintf(buf + strlen(buf),
+		 len - strlen(buf) - 1,
+		 "%s%d %s",
+		 TMY_ALLOW_SIGNAL, signal, dest_domain->name);
+
+	return tmy_write_audit_log(buf, is_granted, is_enforce);
+}
+
+/*************************  SIGNAL ACL HANDLER  *************************/
+
+static int tmy_add_signal_entry(const u16 sig, const char *dest_pattern,
+				struct domain_info *domain,
+				const struct condition_list *cond,
+				const u8 is_delete)
+{
+	struct acl_info *ptr;
+	const struct path_info *saved_dest_pattern;
+	int error = -ENOMEM;
+
+	if (!domain)
+		return -EINVAL;
+	if (!dest_pattern ||
+	    !tmy_is_correct_domain(dest_pattern, __FUNCTION__))
+		return -EINVAL;
+
+	saved_dest_pattern = tmy_save_name(dest_pattern);
+	if (!saved_dest_pattern)
+		return -ENOMEM;
+
+	down(&domain_acl_lock);
+
+	if (is_delete)
+		goto remove;
+
+	ptr = domain->first_acl_ptr;
+	if (!ptr)
+		goto first_entry;
+
+	while (1) {
+		struct signal_acl *acl = (struct signal_acl *) ptr;
+
+		if (ptr->type == TMY_TYPE_SIGNAL_ACL && acl->sig == sig
+		    && ptr->cond == cond
+		    && !tmy_pathcmp(acl->domainname, saved_dest_pattern)) {
+			ptr->is_deleted = 0;
+			/* Found. Nothing to do. */
+			error = 0;
+			break;
+		}
+
+		if (ptr->next) {
+			ptr = ptr->next;
+			continue;
+		}
+
+first_entry: ;
+		/* Not found. Append it to the tail. */
+		acl = tmy_alloc_element(sizeof(*acl));
+		if (!acl)
+			break;
+
+		acl->head.type = TMY_TYPE_SIGNAL_ACL;
+		acl->head.cond = cond;
+		acl->sig = sig;
+		acl->domainname = saved_dest_pattern;
+		error = tmy_add_acl(ptr, domain, (struct acl_info *) acl);
+		break;
+	}
+	goto ok;
+remove: ;
+	error = -ENOENT;
+	for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {
+		struct signal_acl *acl = (struct signal_acl *) ptr;
+		if (ptr->type != TMY_TYPE_SIGNAL_ACL || ptr->cond != cond ||
+		    ptr->is_deleted || acl->sig != sig ||
+		    tmy_pathcmp(acl->domainname, saved_dest_pattern))
+			continue;
+		error = tmy_del_acl(ptr);
+		break;
+	}
+
+ok: ;
+	up(&domain_acl_lock);
+
+	return error;
+}
+
+/**
+ * tmy_signal_acl - check permission for kill(2)/tkill(2)/tgkill(2).
+ * @sig:  signal number.
+ * @pid:  pid of destination process.
+ *
+ * Returns zero if permission granted.
+ * Returns nonzero if permission denied.
+ */
+int tmy_signal_acl(const int sig, const int pid)
+{
+	struct domain_info *domain = TMY_SECURITY->domain;
+	struct domain_info *dest = NULL;
+	const char *dest_pattern;
+	struct acl_info *ptr;
+	const u16 hash = sig;
+	const u8 is_enforce = tmy_enforce(TMY_MAC_FOR_SIGNAL);
+
+	if (!tmy_flags(TMY_MAC_FOR_SIGNAL))
+		return 0;
+	if (!sig)
+		return 0; /* No check for NULL signal. */
+	if (current->pid == pid) {
+		tmy_audit_signal_log(sig, domain->domainname, 1, is_enforce);
+		return 0; /* No check for self. */
+	}
+
+	{ /* Simplified checking. */
+		struct task_struct *p = NULL;
+		read_lock(&tasklist_lock);
+		if (pid > 0)
+			p = find_task_by_pid((pid_t) pid);
+		else if (pid == 0)
+			p = current;
+		else if (pid == -1)
+			dest = &KERNEL_DOMAIN;
+		else
+			p = find_task_by_pid((pid_t) -pid);
+		if (p)
+			/* "struct task_struct"->security is not NULL. */
+			dest = ((struct tmy_security *) p->security)->domain;
+		read_unlock(&tasklist_lock);
+		if (!dest)
+			return 0; /* I can't find destinatioin. */
+	}
+
+	if (domain == dest) {
+		tmy_audit_signal_log(sig, dest->domainname, 1, is_enforce);
+		return 0;
+	}
+
+	dest_pattern = dest->domainname->name;
+	for (ptr = domain->first_acl_ptr; ptr; ptr = ptr->next) {
+		struct signal_acl *acl = (struct signal_acl *) ptr;
+
+		if (ptr->type == TMY_TYPE_SIGNAL_ACL && ptr->is_deleted == 0
+		    && acl->sig == hash &&
+		    tmy_check_condition(ptr->cond, NULL) == 0) {
+			const int len = acl->domainname->total_len;
+
+			if (strncmp(acl->domainname->name,
+				    dest_pattern, len) == 0
+			    && (dest_pattern[len] == ' ' ||
+				dest_pattern[len] == '\0'))
+				break;
+
+		}
+	}
+
+	if (ptr) {
+		tmy_audit_signal_log(sig, dest->domainname, 1, is_enforce);
+		return 0;
+	}
+
+	tmy_audit_signal_log(sig, dest->domainname, 0, is_enforce);
+	if (is_enforce)
+		return tmy_supervisor("%s\n" TMY_ALLOW_SIGNAL "%d %s\n",
+				      domain->domainname->name,
+				      sig, dest_pattern);
+	if (tmy_accept(TMY_MAC_FOR_SIGNAL, domain))
+		tmy_add_signal_entry(sig, dest_pattern, domain, NULL, 0);
+
+	return 0;
+}
+
+/**
+ * tmy_add_signal_policy - add or delete signal policy.
+ * @data:      a line to parse.
+ * @domain:    pointer to "struct domain_info".
+ * @cond:      pointer to "struct condition_list". May be NULL.
+ * @is_delete: is this delete request?
+ *
+ * Returns zero on success.
+ * Returns nonzero on failure.
+ */
+int tmy_add_signal_policy(char *data,
+			  struct domain_info *domain,
+			  const struct condition_list *cond,
+			  const u8 is_delete)
+{
+	int sig;
+	char *domainname = strchr(data, ' ');
+
+	if (sscanf(data, "%d", &sig) == 1 && domainname &&
+	    tmy_is_domain_def(domainname + 1))
+		return tmy_add_signal_entry(sig, domainname + 1, domain,
+					    cond, is_delete);
+
+	return -EINVAL;
+}



  parent reply	other threads:[~2007-10-02  7:38 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-02  7:25 [TOMOYO 00/15](repost) TOMOYO Linux - MAC based on process invocation history Kentaro Takeda
2007-10-02  7:28 ` [TOMOYO 01/15](repost) Allow use of namespace_sem from LSM module Kentaro Takeda
2007-10-02  7:29 ` [TOMOYO 02/15](repost) Data structures and prototypes definition Kentaro Takeda
2007-10-02  7:30 ` [TOMOYO 03/15](repost) Memory and pathname management functions Kentaro Takeda
2007-10-03  7:39   ` James Morris
2007-10-03 11:12     ` Tetsuo Handa
2007-10-02  7:31 ` [TOMOYO 04/15](repost) Utility functions and securityfs interface for policy manipulation Kentaro Takeda
2007-10-02  8:05   ` Paul Mundt
2007-10-02 14:15     ` Greg KH
2007-10-02  7:32 ` [TOMOYO 05/15](repost) Domain transition handler functions Kentaro Takeda
2007-10-02 11:15   ` James Morris
2007-10-02 12:44     ` Tetsuo Handa
2007-10-02 13:00       ` YOSHIFUJI Hideaki / 吉藤英明
2007-10-02 13:07       ` James Morris
2007-10-02 14:50         ` Andi Kleen
2007-10-03 11:24         ` Tetsuo Handa
2007-10-03 11:43           ` YOSHIFUJI Hideaki / 吉藤英明
2007-10-03 12:37             ` James Morris
2007-10-03 13:04               ` Tetsuo Handa
2007-10-03 13:11                 ` YOSHIFUJI Hideaki / 吉藤英明
2007-10-03 13:14                 ` KaiGai Kohei
2007-10-03 13:59                   ` Tetsuo Handa
2007-10-03 14:07                     ` Peter Zijlstra
2007-10-03 14:26                       ` Tetsuo Handa
2007-10-03 14:26                         ` Peter Zijlstra
2007-10-03 14:32                         ` YOSHIFUJI Hideaki / 吉藤英明
2007-10-03 14:39                           ` James Morris
2007-10-03 14:56                           ` Tetsuo Handa
2007-10-04 12:57                             ` Tetsuo Handa
2007-10-03 14:37                         ` Jiri Kosina
2007-10-07 10:38                       ` Sleeping in RCU list traversal Tetsuo Handa
2007-10-03 13:24                 ` [TOMOYO 05/15](repost) Domain transition handler functions Peter Zijlstra
2007-10-03 14:19                   ` Tetsuo Handa
2007-10-03 14:28                     ` Peter Zijlstra
2007-10-15 11:46                       ` Tetsuo Handa
2007-10-03 14:35                     ` David P. Quigley
2007-10-15 12:09               ` Tetsuo Handa
2007-10-02  7:33 ` [TOMOYO 06/15](repost) Auditing interface Kentaro Takeda
2007-10-02  7:34 ` [TOMOYO 07/15](repost) File access control functions Kentaro Takeda
2007-10-02  7:35 ` [TOMOYO 08/15](repost) Argv[0] " Kentaro Takeda
2007-10-02  7:36 ` [TOMOYO 09/15](repost) Networking " Kentaro Takeda
2007-10-02  7:37 ` [TOMOYO 10/15](repost) Namespace manipulation " Kentaro Takeda
2007-10-02  7:37 ` Kentaro Takeda [this message]
2007-10-02  7:38 ` [TOMOYO 12/15](repost) LSM adapter for TOMOYO Kentaro Takeda
2007-10-02  7:39 ` [TOMOYO 13/15](repost) Conditional permission support Kentaro Takeda
2007-10-02  7:39 ` [TOMOYO 14/15](repost) LSM expansion for TOMOYO Linux Kentaro Takeda
2007-10-02 12:48   ` James Morris
2007-10-02 13:33     ` Tetsuo Handa
2007-10-02 14:36   ` James Morris
2007-10-02 21:49     ` Tetsuo Handa
2007-10-02  7:40 ` [TOMOYO 15/15](repost) Kconfig and Makefile " Kentaro Takeda
2007-10-02  7:42 ` [TOMOYO 00/15](repost) TOMOYO Linux - MAC based on process invocation history Kentaro Takeda
2007-10-02 10:37   ` James Morris
2007-10-02 10:58     ` Kentaro Takeda

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=4701F549.6060602@nttdata.co.jp \
    --to=takedakn@nttdata.co.jp \
    --cc=chrisw@sous-sol.org \
    --cc=linux-kernel@vger.kernel.org \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.