Add a chain call module to the Linux Security module LSM (i)

Source: Internet
Author: User
Tags goto

A few days ago took a job of outsourcing, learned about the Linux security module, found some problems in the security module.

About the Linux security module LSM there is not much to say, everyone Google under the understanding.

The main introduction here is how to modify this module, so that it can be chained to the stack.

With respect to LSM, the older version provides a security module for registering users with the Register_security/mod_reg_security interface, and the Register_security registration interface only supports the existence of one security module, Mod_reg_ Security supports registering multiple safety modules, but calls between modules need to be maintained by the user (that is, a mechanism that does not provide coexistence of multiple security modules). More unfortunately, 2.6.19 (supposedly this version) after the kernel canceled the Mod_reg_security registration interface (Ghost know what reason, said to be for security reasons, anyway gave me to create a lot of trouble). Now the kernel module only left the Register_security registration interface.

The problem came, I was to help people write a security module, now the kernel does not let me insert security module, the play can not play.

What, there is a register_security interface, hehe, Linux security module SELinux (Red Hat, CentOS release comes with the security module) or AppArmor (Ubuntu comes with the security module) There are also Linux capability modules are accounted for it, always can not let users shut down their own security module with you to play (unless you are more than the NSA). I write the security module is mainly to provide user customization of some security mechanisms, in short, is the need for third-party rules.

Well, the nonsense is not much to say, the problem is now very obvious, our subject is out.

A brief introduction to the LSM module, which has to admire the Linux designers, the LSM module provides a simple interface, it provides a similar file system Abstraction layer, as long as the user to implement it provides the operation structure (security_operations structure), Registering the interface with its security module registers with the LSM module to implement its own security features. Register the interface code as follows, its main work is to check the user's security_operations structure instance, to some undefined interface, modify the default behavior, and the Security_ops address pointer to this structure, so that the security module to complete the registration work.

  

1  int__init register_security (structSecurity_operations *Ops)2  {3      if(verify (OPS)) {4PRINTK (Kern_debug"%s could not verify"5               "security_operations structure.\n", __func__);6          return-EINVAL;7      }8  9      if(Security_ops! = &default_security_ops)Ten          return-Eagain; One   ASecurity_ops =ops; -  -      return 0; the}

  

With that in view, let's analyze the next step in how to transform the LSM:

LSM provides a static pointer Security_ops as a channel to the Access module, and security modules such as SELinux are changed to their module structure address after the system is booted.

The first thing we think about is whether we can find this pointer and draw this pointer over to our security module. Hey, so our security module is alive.

Secondly, we can not just do our own module, do not manage the death of the system, at least you can not affect the original system security mechanism it. So, that is, we make our own security module live, but also let the original security module has been alive.

OK, the thought analysis clear, hands-on check can do it!

We're looking for security_ops. Address in the kernel:

  

Well, the static pointer address in the LSM is listed in the kernel symbol table, which means we can modify this address to refer to our security module.

This gives the kernel probe code that references this pointer

  

/** * Probe_kernel_read-wrapper for Kernel_read (). * @file: Pointer to "struct file". * @offset: Starting position . * @addr: Buffer. * @count: Size of @addr. * * Returns return value from Kernel_read (). */Static int__init Probe_kernel_read (structFile *file, unsignedLongOffset,Char*ADDR, unsignedLongcount) {#ifLinux_version_code < Kernel_version (2, 6, 8)/** I can ' t use Kernel_read () because Seq_read () returns-epipe * if &pos! = &file->f_pos. */mm_segment_t Old_fs; unsignedLongpos = file->F_pos; intresult; File->f_pos =offset; Old_fs=Get_fs ();    Set_fs (Get_ds ()); Result= Vfs_read (File, (void__user *) addr, count, &file->F_pos);    Set_fs (OLD_FS); File->f_pos =POS; returnresult;#else    returnkernel_read (file, offset, addr, count);#endif}/** * probe_find_symbol-find function ' s address from/proc/kallsyms. * @keyline: function to find. * * Returns Addr ESS of specified function on success, NULL otherwise. */void*__init Probe_find_symbol (Const Char*Keyline) {    structFile *file =NULL; Char*buf; unsignedLongEntry =0; {#ifLinux_version_code >= kernel_version (2, 6, 18)structFile_system_type *fstype = Get_fs_type ("proc"); structVfsmount *mnt = Vfs_kern_mount (Fstype,0,"proc", NULL);#elifLinux_version_code >= kernel_version (2, 6, 8)structFile_system_type *fstype =NULL; structVfsmount *mnt = Do_kern_mount ("proc",0,"proc", NULL);#else        structFile_system_type *fstype = Get_fs_type ("proc"); structVfsmount *mnt =Kern_mount (fstype);#endif        structDentry *Root; structDentry *Dentry; /** We embed Put_filesystem () here because it's not exported. */        if(Fstype) module_put (Fstype-owner); if(Is_err (MNT))Goto  out; Root= Dget (mnt->mnt_root);#ifLinux_version_code >= kernel_version (2, 6, 16)Mutex_lock (&root->d_inode->I_mutex); Dentry= Lookup_one_len ("kallsyms", Root,8); Mutex_unlock (&root->d_inode->I_mutex);#elseDown (&root->d_inode->I_sem); Dentry= Lookup_one_len ("kallsyms", Root,8); Up (&root->d_inode->I_sem);#endifdput (root); if(Is_err (dentry)) mntput (MNT); Else {#ifLinux_version_code >= kernel_version (3, 6, 0)structPath PATH ={mnt, dentry}; File= Dentry_open (&path, o_rdonly, current_cred ());#elsefile=Dentry_open (Dentry, mnt, O_rdonly#ifLinux_version_code >= kernel_version (2, 6, 29), current_cred ()#endif                       );#endif        }    }    if(Is_err (file) | |!file)Goto  out; BUF=Kmalloc (page_size, Gfp_kernel); if(buf) {intLen; intoffset =0;  while(len =probe_kernel_read (file, offset, buf, Page_size-1)) >0) {            Char*CP; Buf[len]=' /'; CP= STRRCHR (buf,'\ n'); if(!CP) Break; * (CP +1) =' /'; Offset+=strlen (BUF); CP=strstr (buf, Keyline); if(!CP)Continue; *CP =' /';  while(cp > BUF && * (CP-1) !='\ n') CP--; Entry= Simple_strtoul (CP, NULL, -);  Break;    } kfree (BUF); } filp_close (file, NULL); out:    return(void*) entry;}

The code is very simple, is to open the/proc/kallsyms file, to find the corresponding address of the symbol, of course, here consider the kernel version of the problem, the use of #if/#endif等, the code is more chaotic.

The next step is to design a reasonable chain call, so that the security module can be chained before the call, this is left to say again.

 

  

  

  

  

Add a chain call module to the Linux Security module LSM (i)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.