lkml.org 
[lkml]   [2008]   [May]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[TOMOYO #8 (2.6.25-mm1) 2/7] 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>
    ---
    security/tomoyo/tomoyo.c | 279 +++++++++++++++++++++++++++++++++++++++++++++++
    security/tomoyo/tomoyo.h | 102 +++++++++++++++++
    2 files changed, 381 insertions(+)

    --- /dev/null
    +++ mm/security/tomoyo/tomoyo.h
    @@ -0,0 +1,102 @@
    +/*
    + * 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/04/30
    + *
    + */
    +
    +#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(const char *filename, const u8 perm,
    + const char *operation);
    +int tmy_check_exec_perm(const struct path_info *filename,
    + struct tmy_page_buffer *buf);
    +int tmy_check_open_permission(struct dentry *dentry, struct vfsmount *mnt,
    + const int flag);
    +int tmy_check_1path_perm(const u8 operation,
    + struct dentry *dentry,
    + struct vfsmount *mnt);
    +int tmy_check_2path_perm(const u8 operation,
    + struct dentry *dentry1,
    + struct vfsmount *mnt1,
    + struct dentry *dentry2,
    + struct vfsmount *mnt2);
    +int tmy_check_rewrite_permission(struct file *filp);
    +int tmy_find_next_domain(struct linux_binprm *bprm,
    + struct domain_info **next_domain);
    +
    +#define TMY_CHECK_READ_FOR_OPEN_EXEC 1
    +
    +/* 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
    +
    +struct tmy_security {
    + struct domain_info *domain;
    + struct domain_info *prev_domain;
    + u32 flags;
    +};
    +
    +#define TMY_SECURITY ((struct tmy_security *) current->security)
    +
    +#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;
    +
    +#endif
    --- /dev/null
    +++ mm/security/tomoyo/tomoyo.c
    @@ -0,0 +1,279 @@
    +/*
    + * security/tomoyo/tomoyo.c
    + *
    + * LSM hooks for TOMOYO Linux.
    + */
    +
    +#include <linux/security.h>
    +#include "common.h"
    +#include "tomoyo.h"
    +#include "realpath.h"
    +
    +static struct kmem_cache *tmy_cachep;
    +
    +static int tmy_task_alloc_security(struct task_struct *p)
    +{
    + struct tmy_security *ptr = kmem_cache_alloc(tmy_cachep, GFP_KERNEL);
    +
    + if (!ptr)
    + return -ENOMEM;
    + memcpy(ptr, TMY_SECURITY, sizeof(*ptr));
    + p->security = ptr;
    + return 0;
    +}
    +
    +static void tmy_task_free_security(struct task_struct *p)
    +{
    + kmem_cache_free(tmy_cachep, p->security);
    +}
    +
    +static int tmy_bprm_alloc_security(struct linux_binprm *bprm)
    +{
    + TMY_SECURITY->prev_domain = TMY_SECURITY->domain;
    + return 0;
    +}
    +
    +static int tmy_bprm_check_security(struct linux_binprm *bprm)
    +{
    + struct domain_info *next_domain = NULL;
    + int retval = 0;
    +
    + tmy_load_policy(bprm->filename);
    +
    + /*
    + * TMY_CHECK_READ_FOR_OPEN_EXEC bit indicates whether this function is
    + * called by do_execve() or not.
    + * If called by do_execve(), I do domain transition.
    + */
    + if ((TMY_SECURITY->flags & TMY_CHECK_READ_FOR_OPEN_EXEC))
    + goto out;
    + retval = tmy_find_next_domain(bprm, &next_domain);
    + if (retval)
    + goto out;
    + TMY_SECURITY->domain = next_domain;
    + TMY_SECURITY->flags |= TMY_CHECK_READ_FOR_OPEN_EXEC;
    +out:
    + return retval;
    +}
    +
    +static void tmy_bprm_post_apply_creds(struct linux_binprm *bprm)
    +{
    + TMY_SECURITY->prev_domain = TMY_SECURITY->domain;
    +}
    +
    +static void tmy_bprm_free_security(struct linux_binprm *bprm)
    +{
    + TMY_SECURITY->domain = TMY_SECURITY->prev_domain;
    + TMY_SECURITY->flags &= ~TMY_CHECK_READ_FOR_OPEN_EXEC;
    +}
    +
    +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(name, op & 6, "sysctl");
    + tmy_free(name);
    +
    + return error;
    +}
    +
    +static int tmy_inode_permission(struct inode *inode, int mask,
    + struct nameidata *nd)
    +{
    + if (S_ISDIR(inode->i_mode)) /* ignore because inode is directory */
    + return 0;
    + if (!nd || !nd->path.dentry || !nd->path.mnt)
    + return 0;
    +
    + /*
    + * If called by other than do_execve(), I check for read permission of
    + * interpreter.
    + * Unlike DAC, I don't check for read permission of pathname passed to
    + * do_execve().
    + * TOMOYO Linux checks for program's execute permission and
    + * interpreter's read permission.
    + */
    + if ((mask != MAY_EXEC) ||
    + !(TMY_SECURITY->flags & TMY_CHECK_READ_FOR_OPEN_EXEC))
    + return 0;
    +
    + /* called from open_exec() other than do_execve() */;
    + return tmy_check_open_permission(nd->path.dentry, nd->path.mnt,
    + O_RDONLY + 1);
    +}
    +
    +static int tmy_path_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
    +{
    + return tmy_check_open_permission(dentry, mnt, flags);
    +}
    +
    +static int tmy_path_truncate(struct path *path, loff_t length,
    + unsigned int time_attrs, struct file *filp)
    +{
    + return tmy_check_1path_perm(TMY_TYPE_TRUNCATE_ACL, path->dentry,
    + path->mnt);
    +}
    +
    +static int tmy_path_create(struct inode *dir, struct dentry *dentry, int mode,
    + struct nameidata *nd)
    +{
    + if (!nd || !nd->path.mnt)
    + return 0;
    + return tmy_check_1path_perm(TMY_TYPE_CREATE_ACL, dentry, nd->path.mnt);
    +}
    +
    +static int tmy_path_unlink(struct path *dir, struct dentry *dentry)
    +{
    + const int err = pre_vfs_unlink(dir->dentry->d_inode, dentry);
    + if (err)
    + return err;
    + return tmy_check_1path_perm(TMY_TYPE_UNLINK_ACL, dentry, dir->mnt);
    +}
    +
    +static int tmy_path_mkdir(struct path *dir, struct dentry *dentry, int mode)
    +{
    + const int err = pre_vfs_mkdir(dir->dentry->d_inode, dentry);
    + if (err)
    + return err;
    + return tmy_check_1path_perm(TMY_TYPE_MKDIR_ACL, dentry, dir->mnt);
    +}
    +
    +static int tmy_path_rmdir(struct path *dir, struct dentry *dentry)
    +{
    + const int err = pre_vfs_rmdir(dir->dentry->d_inode, dentry);
    + if (err)
    + return err;
    + return tmy_check_1path_perm(TMY_TYPE_RMDIR_ACL, dentry, dir->mnt);
    +}
    +
    +static int tmy_path_symlink(struct path *dir, struct dentry *dentry,
    + const char *old_name)
    +{
    + const int err = pre_vfs_symlink(dir->dentry->d_inode, dentry);
    + if (err)
    + return err;
    + return tmy_check_1path_perm(TMY_TYPE_SYMLINK_ACL, dentry, dir->mnt);
    +}
    +
    +static int tmy_path_mknod(struct path *dir, struct dentry *dentry, int mode,
    + unsigned int dev)
    +{
    + struct vfsmount *mnt = dir->mnt;
    + int err = 0;
    + switch (mode & S_IFMT) {
    + case S_IFCHR:
    + case S_IFBLK:
    + case S_IFIFO:
    + case S_IFSOCK:
    + break;
    + default:
    + return 0;
    + }
    + err = pre_vfs_mknod(dir->dentry->d_inode, dentry, mode);
    + if (err)
    + return err;
    + if (S_ISCHR(mode))
    + return tmy_check_1path_perm(TMY_TYPE_MKCHAR_ACL, dentry, mnt);
    + if (S_ISBLK(mode))
    + return tmy_check_1path_perm(TMY_TYPE_MKBLOCK_ACL, dentry, mnt);
    + if (S_ISFIFO(mode))
    + return tmy_check_1path_perm(TMY_TYPE_MKFIFO_ACL, dentry, mnt);
    + if (S_ISSOCK(mode))
    + return tmy_check_1path_perm(TMY_TYPE_MKSOCK_ACL, dentry, mnt);
    + return 0;
    +}
    +
    +static int tmy_path_link(struct path *old_path, struct path *new_dir,
    + struct dentry *new_dentry)
    +{
    + const int err = pre_vfs_link(old_path->dentry, new_dir->dentry->d_inode,
    + new_dentry);
    + if (err)
    + return err;
    + return tmy_check_2path_perm(TMY_TYPE_LINK_ACL,
    + old_path->dentry, old_path->mnt,
    + new_dentry, new_dir->mnt);
    +}
    +
    +static int tmy_path_rename(struct path *old_dir, struct dentry *old_dentry,
    + struct path *new_dir, struct dentry *new_dentry)
    +{
    + const int err = pre_vfs_rename(old_dir->dentry->d_inode, old_dentry,
    + new_dir->dentry->d_inode, new_dentry);
    + if (err)
    + return err;
    + return tmy_check_2path_perm(TMY_TYPE_RENAME_ACL,
    + old_dentry, old_dir->mnt,
    + new_dentry, new_dir->mnt);
    +}
    +
    +static int tmy_path_uselib(struct nameidata *nd)
    +{
    + return tmy_check_open_permission(nd->path.dentry, nd->path.mnt,
    + O_RDONLY + 1);
    +}
    +
    +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(file);
    + return 0;
    +}
    +
    +static struct security_operations tomoyo_security_ops = {
    + .name = "tomoyo",
    +
    + .task_alloc_security = tmy_task_alloc_security,
    + .task_free_security = tmy_task_free_security,
    + .bprm_alloc_security = tmy_bprm_alloc_security,
    + .bprm_check_security = tmy_bprm_check_security,
    + .bprm_post_apply_creds = tmy_bprm_post_apply_creds,
    + .bprm_free_security = tmy_bprm_free_security,
    + .sysctl = tmy_sysctl,
    + .inode_permission = tmy_inode_permission,
    + .path_truncate = tmy_path_truncate,
    + .path_create = tmy_path_create,
    + .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,
    + .path_open = tmy_path_open,
    + .path_uselib = tmy_path_uselib,
    + .file_fcntl = tmy_file_fcntl,
    +};
    +
    +static int __init tmy_init(void)
    +{
    + struct tmy_security *tmy_security;
    + 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");
    + tmy_cachep = kmem_cache_create("tomoyo_security",
    + sizeof(struct tmy_security),
    + 0, SLAB_PANIC, NULL);
    + tmy_security = kmem_cache_alloc(tmy_cachep, GFP_KERNEL);
    + BUG_ON(!tmy_security);
    + memset(tmy_security, 0, sizeof(*tmy_security));
    + tmy_security->domain = &KERNEL_DOMAIN;
    + init_task.security = tmy_security;
    + return 0;
    +}
    +
    +security_initcall(tmy_init);
    --



    \
     
     \ /
      Last update: 2008-05-01 07:59    [W:0.044 / U:0.256 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site