LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1032|回复: 0

Linux Security Module的注册过程分析(1)

[复制链接]
发表于 2007-8-9 14:57:37 | 显示全部楼层 |阅读模式
Linux Security Module的注册层次

===================================================
作者:ietf AT doit.com.cn
所有源文件来自于linux kernel 2.6.20
请在GNU Library General Public License下参考。
引用请注明出处。
===================================================

selinux的出现着实扰乱了文件系统的进度,不过送算慢慢搞清楚了其中的来龙去脉。下面将通过2.6.20内核中的security代码进行一番简单的分析。该版本的security系统在capability和rootplug之间还存在一些问题,有很多新的补丁程序,具体可以参考下列邮件列表。

http://lists.jammed.com/linux-security-module/2005/08/

初次接触LSM时,其间复杂的模块加载方式和顺序很是让人头疼。光其中的ops操作就有security_ops, capability_ops, secondary_ops, selinux_ops, rootplug_ops, selinux_ops, original_ops,再有init函数security_init, capability_init, rootplug_init, selinux_init中的注册关系register_secrity反反复复的来回赋值,最后究竟ops操作都是什么,已经成了一团乱麻。为此,不得不从系统的启动过程开始,寻找其间的因果顺序,事情的经过是这样的:

一、LSM的初始化

LSM系统的初始化发生在系统内核初始化阶段,在src/init/main.c的start_kernel()里,其位置如下所示:
       fork_init(num_physpages);
       proc_caches_init();
       buffer_init();
       unnamed_dev_init();
       key_init();
       security_init();
       vfs_caches_init(num_physpages);
       radix_tree_init();
       signals_init();
在unnamed_dev_init(), key_init()之后,vfs_caches_init之前,其在内核中的位置层次也基本上如此。

security_init()的具体实现在/src/security/security.c中,
/**
* security_init - initializes the security framework
*
* This should be called early in the kernel initialization sequence.
*/
int __init security_init(void)
{
       printk(KERN_INFO "Security Framework v" SECURITY_FRAMEWORK_VERSION
              " initialized\n");

       if (verify(&dummy_security_ops)) {
              printk(KERN_ERR "%s could not verify "
                     "dummy_security_ops structure.\n", __FUNCTION__);
              return -EIO;
       }

       security_ops = &dummy_security_ops;
       do_security_initcalls();

       return 0;
}
在此,很有必要了解一下dummy_security_ops的定义,在src/security/dummy.c中,给出了其定义

struct security_operations dummy_security_ops;

定义后的dummy_security_ops并没有初始化,也就是说,它是security_operations的一个结构,该结构里是一系列的指针,每个指针都指向一个函数,而这些函数,就是security框架所能覆盖的领域,通过修改函数指针,可以达到为原先的系统通过钩子增加一个安全过滤层的目的。即,系统的这些调用,先通过你设计的函数过滤相关操作,再有你的函数调用原先的实现,实现增加一层的目的,这和NT中注册操作的回调函数相似。

struct security_operations {
       int (*ptrace) (struct task_struct * parent, struct task_struct * child);
       int (*capget) (struct task_struct * target,
                     kernel_cap_t * effective,
                     kernel_cap_t * inheritable, kernel_cap_t * permitted);
       int (*capset_check) (struct task_struct * target,
                          kernel_cap_t * effective,
                          kernel_cap_t * inheritable,
                          kernel_cap_t * permitted);
       void (*capset_set) (struct task_struct * target,
                         kernel_cap_t * effective,
                         kernel_cap_t * inheritable,
                         kernel_cap_t * permitted);
       int (*capable) (struct task_struct * tsk, int cap);
       int (*acct) (struct file * file);
       int (*sysctl) (struct ctl_table * table, int op);
       int (*quotactl) (int cmds, int type, int id, struct super_block * sb);
       int (*quota_on) (struct dentry * dentry);
       int (*syslog) (int type);
       int (*settime) (struct timespec *ts, struct timezone *tz);
       int (*vm_enough_memory) (long pages);

       int (*bprm_alloc_security) (struct linux_binprm * bprm);
       void (*bprm_free_security) (struct linux_binprm * bprm);
       void (*bprm_apply_creds) (struct linux_binprm * bprm, int unsafe);
       void (*bprm_post_apply_creds) (struct linux_binprm * bprm);
       int (*bprm_set_security) (struct linux_binprm * bprm);
       int (*bprm_check_security) (struct linux_binprm * bprm);
       int (*bprm_secureexec) (struct linux_binprm * bprm);

       int (*sb_alloc_security) (struct super_block * sb);
       void (*sb_free_security) (struct super_block * sb);
       int (*sb_copy_data)(struct file_system_type *type,
                         void *orig, void *copy);
       int (*sb_kern_mount) (struct super_block *sb, void *data);
       int (*sb_statfs) (struct dentry *dentry);
       int (*sb_mount) (char *dev_name, struct nameidata * nd,
                      char *type, unsigned long flags, void *data);
       int (*sb_check_sb) (struct vfsmount * mnt, struct nameidata * nd);
       int (*sb_umount) (struct vfsmount * mnt, int flags);
       void (*sb_umount_close) (struct vfsmount * mnt);
       void (*sb_umount_busy) (struct vfsmount * mnt);
       void (*sb_post_remount) (struct vfsmount * mnt,
                             unsigned long flags, void *data);
       void (*sb_post_mountroot) (void);
       void (*sb_post_addmount) (struct vfsmount * mnt,
                              struct nameidata * mountpoint_nd);
       int (*sb_pivotroot) (struct nameidata * old_nd,
                          struct nameidata * new_nd);
       void (*sb_post_pivotroot) (struct nameidata * old_nd,
                               struct nameidata * new_nd);

       int (*inode_alloc_security) (struct inode *inode);
       void (*inode_free_security) (struct inode *inode);
       int (*inode_init_security) (struct inode *inode, struct inode *dir,
                                char **name, void **value, size_t *len);
       int (*inode_create) (struct inode *dir,
                            struct dentry *dentry, int mode);
       int (*inode_link) (struct dentry *old_dentry,
                          struct inode *dir, struct dentry *new_dentry);
       int (*inode_unlink) (struct inode *dir, struct dentry *dentry);
       int (*inode_symlink) (struct inode *dir,
                             struct dentry *dentry, const char *old_name);
       int (*inode_mkdir) (struct inode *dir, struct dentry *dentry, int mode);
       int (*inode_rmdir) (struct inode *dir, struct dentry *dentry);
       int (*inode_mknod) (struct inode *dir, struct dentry *dentry,
                           int mode, dev_t dev);
       int (*inode_rename) (struct inode *old_dir, struct dentry *old_dentry,
                            struct inode *new_dir, struct dentry *new_dentry);
       int (*inode_readlink) (struct dentry *dentry);
       int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
       int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd);
       int (*inode_setattr) (struct dentry *dentry, struct iattr *attr);
       int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry);
        void (*inode_delete) (struct inode *inode);
       int (*inode_setxattr) (struct dentry *dentry, char *name, void *value,
                            size_t size, int flags);
       void (*inode_post_setxattr) (struct dentry *dentry, char *name, void *value,
                                 size_t size, int flags);
       int (*inode_getxattr) (struct dentry *dentry, char *name);
       int (*inode_listxattr) (struct dentry *dentry);
       int (*inode_removexattr) (struct dentry *dentry, char *name);
       const char *(*inode_xattr_getsuffix) (void);
      int (*inode_getsecurity)(const struct inode *inode, const char *name, void *buffer, size_t size, int err);
      int (*inode_setsecurity)(struct inode *inode, const char *name, const void *value, size_t size, int flags);
      int (*inode_listsecurity)(struct inode *inode, char *buffer, size_t buffer_size);

       int (*file_permission) (struct file * file, int mask);
       int (*file_alloc_security) (struct file * file);
       void (*file_free_security) (struct file * file);
       int (*file_ioctl) (struct file * file, unsigned int cmd,
                        unsigned long arg);
       int (*file_mmap) (struct file * file,
                       unsigned long reqprot,
                       unsigned long prot, unsigned long flags);
       int (*file_mprotect) (struct vm_area_struct * vma,
                           unsigned long reqprot,
                           unsigned long prot);
       int (*file_lock) (struct file * file, unsigned int cmd);
       int (*file_fcntl) (struct file * file, unsigned int cmd,
                        unsigned long arg);
       int (*file_set_fowner) (struct file * file);
       int (*file_send_sigiotask) (struct task_struct * tsk,
                                struct fown_struct * fown, int sig);
       int (*file_receive) (struct file * file);

       int (*task_create) (unsigned long clone_flags);
       int (*task_alloc_security) (struct task_struct * p);
       void (*task_free_security) (struct task_struct * p);
       int (*task_setuid) (uid_t id0, uid_t id1, uid_t id2, int flags);
       int (*task_post_setuid) (uid_t old_ruid /* or fsuid */ ,
                             uid_t old_euid, uid_t old_suid, int flags);
       int (*task_setgid) (gid_t id0, gid_t id1, gid_t id2, int flags);
       int (*task_setpgid) (struct task_struct * p, pid_t pgid);
       int (*task_getpgid) (struct task_struct * p);
       int (*task_getsid) (struct task_struct * p);
       void (*task_getsecid) (struct task_struct * p, u32 * secid);
       int (*task_setgroups) (struct group_info *group_info);
       int (*task_setnice) (struct task_struct * p, int nice);
       int (*task_setioprio) (struct task_struct * p, int ioprio);
       int (*task_getioprio) (struct task_struct * p);
       int (*task_setrlimit) (unsigned int resource, struct rlimit * new_rlim);
       int (*task_setscheduler) (struct task_struct * p, int policy,
                              struct sched_param * lp);
       int (*task_getscheduler) (struct task_struct * p);
       int (*task_movememory) (struct task_struct * p);
       int (*task_kill) (struct task_struct * p,
                       struct siginfo * info, int sig, u32 secid);
       int (*task_wait) (struct task_struct * p);
       int (*task_prctl) (int option, unsigned long arg2,
                        unsigned long arg3, unsigned long arg4,
                        unsigned long arg5);
       void (*task_reparent_to_init) (struct task_struct * p);
       void (*task_to_inode)(struct task_struct *p, struct inode *inode);

       int (*ipc_permission) (struct kern_ipc_perm * ipcp, short flag);

       int (*msg_msg_alloc_security) (struct msg_msg * msg);
       void (*msg_msg_free_security) (struct msg_msg * msg);

       int (*msg_queue_alloc_security) (struct msg_queue * msq);
       void (*msg_queue_free_security) (struct msg_queue * msq);

<SPAN lang=EN-US><FONT size=3><FONT face="Times New Roman"><FONT color=#000066>       int (*msg_queue_associate) (struct msg_queue * msq, int msqf
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表