All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kentaro Takeda <takedakn@nttdata.co.jp>
To: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Stephen Smalley <sds@tycho.nsa.gov>,
	James Morris <jmorris@namei.org>,
	Chris Wright <chrisw@sous-sol.org>,
	"Serge E. Hallyn" <serue@us.ibm.com>,
	David Howells <dhowells@redhat.com>,
	linux-security-module@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	Toshiharu Harada <haradats@nttdata.co.jp>,
	Andrew Morton <akpm@linux-foundation.org>,
	Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Subject: Re: [TOMOYO #10 (linux-next) 3/8] LSM adapter functions.
Date: Thu, 09 Oct 2008 15:57:10 +0900	[thread overview]
Message-ID: <48EDAB46.4000200@nttdata.co.jp> (raw)
In-Reply-To: <20081009151006.377fbf9e.kamezawa.hiroyu@jp.fujitsu.com>

KAMEZAWA Hiroyuki wrote:
>> + * Version: 2.2.0-pre   2008/10/01
<snip>
> What is this Version for ?
> Is this exported to userland via some interface ?
Yes. This version is exported via /sys/kernel/security/tomoyo/version .

>> +static int tmy_sysctl(struct ctl_table *table, int op)
>> +{
>> +	int error;
>> +	char *name;
>> +	if ((op & 6) == 0)
>> +		return 0;
> 
> It seems that you need a blanc line between variable declaration and
> start of code, like this.
> 
> ==
>   char *name;
>                                  << 
>   if ((op & 6) == 0)
> 		return 0;
> ==
Fixed.

> BTW, is this "6" need to be "6" rather than some readable macro ?
Replaced "6" with "(MAY_READ | MAY_WRITE)" .

> This tmy_check_open_permission() is defiend in 7/8.
> Because people uses "bisect" in these days, I think it's better to avoid
> this kind of reversed dependency of patch stack.
I see. I'll change patch order next time.
Thanks for your advice. :)

Regards,

---
Subject: LSM adapter functions.

Signed-off-by: Kentaro Takeda <takedakn@nttdata.co.jp>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: Toshiharu Harada <haradats@nttdata.co.jp>
Cc: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
---
 security/tomoyo/tomoyo.c |  328 +++++++++++++++++++++++++++++++++++++++++++++++
 security/tomoyo/tomoyo.h |  106 +++++++++++++++
 2 files changed, 434 insertions(+)

--- /dev/null
+++ linux-next/security/tomoyo/tomoyo.c
@@ -0,0 +1,328 @@
+/*
+ * security/tomoyo/tomoyo.c
+ *
+ * LSM hooks for TOMOYO Linux.
+ *
+ * Copyright (C) 2005-2008  NTT DATA CORPORATION
+ *
+ * Version: 2.2.0-pre   2008/10/01
+ *
+ */
+
+#include <linux/security.h>
+#include "common.h"
+#include "tomoyo.h"
+#include "realpath.h"
+#include <linux/audit.h>
+#include <linux/device_cgroup.h>
+
+static int tmy_cred_prepare(struct cred *new, const struct cred *old, gfp_t gfp)
+{
+	new->security = old->security;
+	return 0;
+}
+
+static int tmy_bprm_set_creds(struct linux_binprm *bprm)
+{
+	if (bprm->cred_prepared)
+		return 0;
+	if (!sbin_init_started)
+		tmy_load_policy(bprm->filename);
+	bprm->cred->security = NULL;
+	return 0;
+}
+
+static int tmy_bprm_check_security(struct linux_binprm *bprm)
+{
+	struct domain_info *domain = bprm->cred->security;
+
+	/*
+	 * Execute permission is checked against pathname passed to do_execve()
+	 * using current domain.
+	 */
+	if (!domain) {
+		struct domain_info *next_domain = NULL;
+		int retval = tmy_find_next_domain(bprm, &next_domain);
+		if (!retval)
+			bprm->cred->security = next_domain;
+		return retval;
+	}
+	/*
+	 * Read permission is checked against interpreters using next domain.
+	 */
+	return tmy_check_open_permission(domain, bprm->file->f_path.dentry,
+					 bprm->file->f_path.mnt, 1);
+}
+
+static int tmy_sysctl(struct ctl_table *table, int op)
+{
+	int error;
+	char *name;
+
+	if ((op & (MAY_READ | MAY_WRITE)) == 0)
+		return 0;
+	name = sysctlpath_from_table(table);
+	if (!name)
+		return -ENOMEM;
+	error = tmy_check_file_perm(tmy_domain(), name,
+				    op & (MAY_READ | MAY_WRITE),
+				    "sysctl");
+	tmy_free(name);
+	return error;
+}
+
+struct check_result_entry {
+	struct list_head list;
+	struct task_struct *task;
+	int error;
+};
+
+static LIST_HEAD(check_result_list);
+static DEFINE_SPINLOCK(check_result_list_lock);
+
+/* Remember error code for security_inode_*(). */
+static int tmy_save_result(const int error)
+{
+	struct check_result_entry *entry;
+
+	if (!error)
+		return 0;
+	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
+		return -ENOMEM;
+	entry->task = current;
+	entry->error = error;
+	spin_lock(&check_result_list_lock);
+	list_add(&entry->list, &check_result_list);
+	spin_unlock(&check_result_list_lock);
+	return 0;
+}
+
+/* Fetch error code from security_inode_*(). */
+static int tmy_load_result(void)
+{
+	struct task_struct *task = current;
+	struct check_result_entry *p;
+	struct check_result_entry *entry = NULL;
+
+	if (list_empty(&check_result_list))
+		return 0;
+	spin_lock(&check_result_list_lock);
+	list_for_each_entry(p, &check_result_list, list) {
+		if (p->task != task)
+			continue;
+		list_del(&p->list);
+		entry = p;
+		break;
+	}
+	spin_unlock(&check_result_list_lock);
+	if (entry) {
+		int error = entry->error;
+		kfree(entry);
+		return error;
+	}
+	return 0;
+}
+
+/* Clear error code if security_inode_*() was not called. */
+static void tmy_path_clear(void)
+{
+	tmy_load_result();
+}
+
+static int tmy_path_truncate(struct path *path, loff_t length,
+			     unsigned int time_attrs, struct file *filp)
+{
+	return tmy_save_result(tmy_check_1path_perm(tmy_domain(),
+						    TMY_TYPE_TRUNCATE_ACL,
+						    path->dentry, path->mnt));
+}
+
+static int tmy_path_unlink(struct path *parent, struct dentry *dentry)
+{
+	return tmy_save_result(tmy_check_1path_perm(tmy_domain(),
+						    TMY_TYPE_UNLINK_ACL,
+						    dentry, parent->mnt));
+}
+
+static int tmy_path_mkdir(struct path *parent, struct dentry *dentry, int mode)
+{
+	return tmy_save_result(tmy_check_1path_perm(tmy_domain(),
+						    TMY_TYPE_MKDIR_ACL,
+						    dentry, parent->mnt));
+}
+
+static int tmy_path_rmdir(struct path *parent, struct dentry *dentry)
+{
+	return tmy_save_result(tmy_check_1path_perm(tmy_domain(),
+						    TMY_TYPE_RMDIR_ACL,
+						    dentry, parent->mnt));
+}
+
+static int tmy_path_symlink(struct path *parent, struct dentry *dentry,
+			    const char *old_name)
+{
+	return tmy_save_result(tmy_check_1path_perm(tmy_domain(),
+						    TMY_TYPE_SYMLINK_ACL,
+						    dentry, parent->mnt));
+}
+
+static int tmy_path_mknod(struct path *parent, struct dentry *dentry, int mode,
+			  unsigned int dev)
+{
+	struct vfsmount *mnt = parent->mnt;
+	int type = TMY_TYPE_CREATE_ACL;
+
+	switch (mode & S_IFMT) {
+	case S_IFCHR:
+		type = TMY_TYPE_MKCHAR_ACL;
+		break;
+	case S_IFBLK:
+		type = TMY_TYPE_MKBLOCK_ACL;
+		break;
+	case S_IFIFO:
+		type = TMY_TYPE_MKFIFO_ACL;
+		break;
+	case S_IFSOCK:
+		type = TMY_TYPE_MKSOCK_ACL;
+		break;
+	}
+	return tmy_save_result(tmy_check_1path_perm(tmy_domain(),
+						    type, dentry, mnt));
+}
+
+static int tmy_path_link(struct dentry *old_dentry, struct path *new_dir,
+			 struct dentry *new_dentry)
+{
+	return tmy_save_result(tmy_check_2path_perm(tmy_domain(),
+						    TMY_TYPE_LINK_ACL,
+						    old_dentry, new_dir->mnt,
+						    new_dentry, new_dir->mnt));
+}
+
+static int tmy_path_rename(struct path *old_parent, struct dentry *old_dentry,
+			   struct path *new_parent, struct dentry *new_dentry)
+{
+	return tmy_save_result(tmy_check_2path_perm(tmy_domain(),
+						    TMY_TYPE_RENAME_ACL,
+						    old_dentry,
+						    old_parent->mnt,
+						    new_dentry,
+						    new_parent->mnt));
+}
+
+static int tmy_inode_link(struct dentry *old_dentry, struct inode *inode,
+			  struct dentry *new_dentry)
+{
+	return tmy_load_result();
+}
+
+static int tmy_inode_unlink(struct inode *inode, struct dentry *dentry)
+{
+	return tmy_load_result();
+}
+
+static int tmy_inode_symlink(struct inode *inode, struct dentry *dentry,
+			     const char *name)
+{
+	return tmy_load_result();
+}
+
+static int tmy_inode_mkdir(struct inode *inode, struct dentry *dentry,
+			   int mask)
+{
+	return tmy_load_result();
+}
+
+static int tmy_inode_rmdir(struct inode *inode, struct dentry *dentry)
+{
+	return tmy_load_result();
+}
+
+static int tmy_inode_create(struct inode *dir, struct dentry *dentry, int mode)
+{
+	return tmy_load_result();
+}
+
+static int tmy_inode_mknod(struct inode *inode, struct dentry *dentry,
+			   int mode, dev_t dev)
+{
+	return tmy_load_result();
+}
+
+static int tmy_inode_rename(struct inode *old_inode, struct dentry *old_dentry,
+			    struct inode *new_inode, struct dentry *new_dentry)
+{
+	return tmy_load_result();
+}
+
+static int tmy_inode_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+	return tmy_load_result();
+}
+
+static int tmy_file_fcntl(struct file *file, unsigned int cmd,
+			  unsigned long arg)
+{
+	if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND))
+		return tmy_check_rewrite_permission(tmy_domain(), file);
+	return 0;
+}
+
+static int tmy_dentry_open(struct file *f, const struct cred *cred)
+{
+	int flags = f->f_flags;
+
+	if ((flags + 1) & O_ACCMODE)
+		flags++;
+	flags |= f->f_flags & (O_APPEND | O_TRUNC);
+	/* Don't check read permission here if called from do_execve(). */
+	if (current->in_execve)
+		return 0;
+	return tmy_check_open_permission(tmy_domain(), f->f_path.dentry,
+					 f->f_path.mnt, flags);
+}
+
+static struct security_operations tomoyo_security_ops = {
+	.name                      = "tomoyo",
+	.cred_prepare              = tmy_cred_prepare,
+	.bprm_set_creds            = tmy_bprm_set_creds,
+	.bprm_check_security       = tmy_bprm_check_security,
+	.sysctl                    = tmy_sysctl,
+	.file_fcntl                = tmy_file_fcntl,
+	.dentry_open               = tmy_dentry_open,
+	.path_truncate             = tmy_path_truncate,
+	.path_unlink               = tmy_path_unlink,
+	.path_mkdir                = tmy_path_mkdir,
+	.path_rmdir                = tmy_path_rmdir,
+	.path_symlink              = tmy_path_symlink,
+	.path_mknod                = tmy_path_mknod,
+	.path_link                 = tmy_path_link,
+	.path_rename               = tmy_path_rename,
+	.inode_create              = tmy_inode_create,
+	.inode_setattr             = tmy_inode_setattr,
+	.inode_unlink              = tmy_inode_unlink,
+	.inode_mkdir               = tmy_inode_mkdir,
+	.inode_rmdir               = tmy_inode_rmdir,
+	.inode_symlink             = tmy_inode_symlink,
+	.inode_mknod               = tmy_inode_mknod,
+	.inode_link                = tmy_inode_link,
+	.inode_rename              = tmy_inode_rename,
+	.path_clear                = tmy_path_clear,
+};
+
+static int __init tmy_init(void)
+{
+	struct cred *cred = (struct cred *) current_cred();
+
+	if (!security_module_enable(&tomoyo_security_ops))
+		return 0;
+	/* register ourselves with the security framework */
+	if (register_security(&tomoyo_security_ops))
+		panic("Failure registering TOMOYO Linux");
+	printk(KERN_INFO "TOMOYO Linux initialized\n");
+	cred->security = &KERNEL_DOMAIN;
+	return 0;
+}
+
+security_initcall(tmy_init);
--- /dev/null
+++ linux-next/security/tomoyo/tomoyo.h
@@ -0,0 +1,106 @@
+/*
+ * security/tomoyo/tomoyo.h
+ *
+ * Implementation of the Domain-Based Mandatory Access Control.
+ *
+ * Copyright (C) 2005-2008  NTT DATA CORPORATION
+ *
+ * Version: 2.2.0-pre   2008/10/01
+ *
+ */
+
+#ifndef _LINUX_TOMOYO_H
+#define _LINUX_TOMOYO_H
+
+struct path_info;
+struct dentry;
+struct vfsmount;
+struct inode;
+struct linux_binprm;
+struct pt_regs;
+struct tmy_page_buffer;
+
+char *sysctlpath_from_table(struct ctl_table *table);
+int tmy_check_file_perm(struct domain_info *domain, const char *filename,
+			const u8 perm, const char *operation);
+int tmy_check_exec_perm(struct domain_info *domain,
+			const struct path_info *filename,
+			struct tmy_page_buffer *buf);
+int tmy_check_open_permission(struct domain_info *domain,
+			      struct dentry *dentry, struct vfsmount *mnt,
+			      const int flag);
+int tmy_check_1path_perm(struct domain_info *domain, const u8 operation,
+			 struct dentry *dentry, struct vfsmount *mnt);
+int tmy_check_2path_perm(struct domain_info *domain, const u8 operation,
+			 struct dentry *dentry1, struct vfsmount *mnt1,
+			 struct dentry *dentry2, struct vfsmount *mnt2);
+int tmy_check_rewrite_permission(struct domain_info *domain,
+				 struct file *filp);
+int tmy_find_next_domain(struct linux_binprm *bprm,
+			 struct domain_info **next_domain);
+
+/* Index numbers for Access Controls. */
+
+#define TYPE_SINGLE_PATH_ACL                 0
+#define TYPE_DOUBLE_PATH_ACL                 1
+
+/* Index numbers for File Controls. */
+
+/*
+ * TYPE_READ_WRITE_ACL is special. TYPE_READ_WRITE_ACL is automatically set
+ * if both TYPE_READ_ACL and TYPE_WRITE_ACL are set. Both TYPE_READ_ACL and
+ * TYPE_WRITE_ACL are automatically set if TYPE_READ_WRITE_ACL is set.
+ * TYPE_READ_WRITE_ACL is automatically cleared if either TYPE_READ_ACL or
+ * TYPE_WRITE_ACL is cleared. Both TYPE_READ_ACL and TYPE_WRITE_ACL are
+ * automatically cleared if TYPE_READ_WRITE_ACL is cleared.
+ */
+
+#define TMY_TYPE_READ_WRITE_ACL    0
+#define TMY_TYPE_EXECUTE_ACL       1
+#define TMY_TYPE_READ_ACL          2
+#define TMY_TYPE_WRITE_ACL         3
+#define TMY_TYPE_CREATE_ACL        4
+#define TMY_TYPE_UNLINK_ACL        5
+#define TMY_TYPE_MKDIR_ACL         6
+#define TMY_TYPE_RMDIR_ACL         7
+#define TMY_TYPE_MKFIFO_ACL        8
+#define TMY_TYPE_MKSOCK_ACL        9
+#define TMY_TYPE_MKBLOCK_ACL      10
+#define TMY_TYPE_MKCHAR_ACL       11
+#define TMY_TYPE_TRUNCATE_ACL     12
+#define TMY_TYPE_SYMLINK_ACL      13
+#define TMY_TYPE_REWRITE_ACL      14
+#define MAX_SINGLE_PATH_OPERATION 15
+
+#define TMY_TYPE_LINK_ACL         0
+#define TMY_TYPE_RENAME_ACL       1
+#define MAX_DOUBLE_PATH_OPERATION 2
+
+#define TMY_DOMAINPOLICY          0
+#define TMY_EXCEPTIONPOLICY       1
+#define TMY_DOMAIN_STATUS         2
+#define TMY_PROCESS_STATUS        3
+#define TMY_MEMINFO               4
+#define TMY_SELFDOMAIN            5
+#define TMY_VERSION               6
+#define TMY_PROFILE               7
+#define TMY_MANAGER               8
+#define TMY_UPDATESCOUNTER        9
+
+extern struct domain_info KERNEL_DOMAIN;
+
+static inline struct domain_info *tmy_domain(void)
+{
+	return current_cred()->security;
+}
+
+static inline struct domain_info *tmy_real_domain(struct task_struct *task)
+{
+	/* Caller must hold tasklist_lock. */
+	const struct cred *cred = get_task_cred(task);
+	struct domain_info *domain = cred->security;
+	put_cred(cred);
+	return domain;
+}
+
+#endif



  reply	other threads:[~2008-10-09  6:57 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-10-09  4:28 [TOMOYO #10 (linux-next) 0/8] TOMOYO Linux Kentaro Takeda
2008-10-09  4:28 ` [TOMOYO #10 (linux-next) 1/8] Introduce new LSM hooks where vfsmount is available Kentaro Takeda
2008-10-09  4:28 ` [TOMOYO #10 (linux-next) 2/8] Add in_execve flag into task_struct Kentaro Takeda
2008-10-09  4:28 ` [TOMOYO #10 (linux-next) 3/8] LSM adapter functions Kentaro Takeda
2008-10-09  6:10   ` KAMEZAWA Hiroyuki
2008-10-09  6:57     ` Kentaro Takeda [this message]
2008-10-09  4:28 ` [TOMOYO #10 (linux-next) 4/8] Memory and pathname management functions Kentaro Takeda
2008-10-09  6:18   ` KAMEZAWA Hiroyuki
2008-10-09  7:17     ` Kentaro Takeda
2008-10-09  4:28 ` [TOMOYO #10 (linux-next) 5/8] Common functions for TOMOYO Linux Kentaro Takeda
2008-10-09  4:28 ` [TOMOYO #10 (linux-next) 6/8] Domain transition handler Kentaro Takeda
2008-10-09  4:28 ` [TOMOYO #10 (linux-next) 7/8] File operation restriction part Kentaro Takeda
2008-10-09 16:48   ` Serge E. Hallyn
2008-10-12  0:09     ` Tetsuo Handa
2008-10-15  1:29       ` Paul E. McKenney
2008-10-16  4:05         ` Kentaro Takeda
2008-10-16 15:10           ` Paul E. McKenney
2008-10-17  8:32             ` Kentaro Takeda
2008-10-17 14:56               ` Paul E. McKenney
2008-10-18 14:04                 ` Tetsuo Handa
2008-10-18 15:18                   ` Paul E. McKenney
2008-10-19 13:10                     ` Tetsuo Handa
2008-10-20  4:17                       ` Paul E. McKenney
2008-10-15 15:24       ` Serge E. Hallyn
2008-10-09  4:28 ` [TOMOYO #10 (linux-next) 8/8] Kconfig and Makefile 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=48EDAB46.4000200@nttdata.co.jp \
    --to=takedakn@nttdata.co.jp \
    --cc=akpm@linux-foundation.org \
    --cc=chrisw@sous-sol.org \
    --cc=dhowells@redhat.com \
    --cc=haradats@nttdata.co.jp \
    --cc=jmorris@namei.org \
    --cc=kamezawa.hiroyu@jp.fujitsu.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=penguin-kernel@I-love.SAKURA.ne.jp \
    --cc=sds@tycho.nsa.gov \
    --cc=serue@us.ibm.com \
    /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.