From: Kentaro Takeda <takedakn@nttdata.co.jp>
To: Stephen Smalley <sds@tycho.nsa.gov>,
James Morris <jmorris@namei.org>,
Chris Wright <chrisw@sous-sol.org>
Cc: "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>,
Kentaro Takeda <takedakn@nttdata.co.jp>,
Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Subject: [TOMOYO #10 (linux-next) 3/8] LSM adapter functions.
Date: Thu, 09 Oct 2008 13:28:17 +0900 [thread overview]
Message-ID: <20081009042916.295927224@nttdata.co.jp> (raw)
In-Reply-To: 20081009042814.398846861@nttdata.co.jp
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>
---
security/tomoyo/tomoyo.c | 319 +++++++++++++++++++++++++++++++++++++++++++++++
security/tomoyo/tomoyo.h | 106 +++++++++++++++
2 files changed, 425 insertions(+)
--- /dev/null
+++ linux-next/security/tomoyo/tomoyo.c
@@ -0,0 +1,319 @@
+/*
+ * 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 & 6) == 0)
+ return 0;
+ name = sysctlpath_from_table(table);
+ if (!name)
+ return -ENOMEM;
+ error = tmy_check_file_perm(tmy_domain(), name, op & 6, "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
--
next prev parent reply other threads:[~2008-10-09 4:30 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 ` Kentaro Takeda [this message]
2008-10-09 6:10 ` [TOMOYO #10 (linux-next) 3/8] LSM adapter functions KAMEZAWA Hiroyuki
2008-10-09 6:57 ` Kentaro Takeda
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=20081009042916.295927224@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=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.