Pages

Friday, May 18, 2012

Writing Linux Security Module

Linux Security Modules (LSM) is a framework allowing Linux to support various security models. LSM has been a part of the kernel starting with Linux v. 2.6. Currently, the official kernel hosts such security modules as SELinux, AppArmor, Tomoyo, and Smack.

The modules run simultaneously with the native Linux security model Discretionary Access Control (DAC). LSM checks are triggered by the actions allowed by DAC.

The LSM mechanism can be implemented in various ways. Generally, it is adding mandatory access control (as, for example, in SELinux case). Besides you can invent your own security model and implement it as a module using the framework. As an example let's consider implementation of a module that will grant privileges on system actions if a specific USB device is connected.

Let's take a look at the diagram and try to understand the way the LSM hook works (using the system call open as an example).


Nothing extraordinary. LSM’s main purpose is to provide security modules with a mechanism to control access to kernel objects (hooks are inserted into the kernel code right before object calls). Before the kernel addresses an internal object, a check function provided by LSM is called.

In other words, LSM allows the modules to understand whether subject S is allowed to perform action OP over kernel's internal object OBJ.
This is really great.

It is reasonable to write a security module skeleton at first. It will be very modest and will always agree with DAC. The source codes we require are located in the security directory among the kernel source codes.

Digging the sources


Go to include/linux/security.h (my kernel version is 2.6.39.4). The most important thing here is the huge structure security_ops.
Here is its fragment:
struct security_operations 
{
char name[SECURITY_NAME_MAX + 1];

int (*ptrace_access_check) (struct task_struct *child, unsigned int mode);
         int (*ptrace_traceme) (struct task_struct *parent);
int (*capget) (struct task_struct *target,
            kernel_cap_t *effective,
            kernel_cap_t *inheritable, kernel_cap_t *permitted);};
It is a list of predefined and documented callback functions available for security module checks. By default, these functions usually return 0, thus allowing any actions. However, some of them use the POSIX security module. These are the Common Capabilities functions, which you can  review in the security/commoncap.c file.

In this case we are interested in the following function from include/linux/security.c:

/**
 * register_security – registers the security module with the kernel.
 * @ops: a pointer to the structure security_options that will be used. 
 *
 * This function allows a security module to register itself with the
 * kernel security subsystem.  Some rudimentary checking is done on the @ops
 * value passed to this function. You'll need to check first if your LSM
 * is allowed to register its @ops by calling security_module_enable(@ops).
 *
 * If the security module has been already registered with the kernel, an error
 * will be returned. In case of success, 0 will be returned
 */
int __init register_security(struct security_operations *ops) 
{
    if (verify(ops)) 
        {
        printk(KERN_DEBUG "%s could not verify "
               "security_operations structure.\n", __func__);
        return -EINVAL;
    }

    if (security_ops != &default_security_ops)
        return -EAGAIN;

    security_ops = ops;

    return 0;
}

Writing the skeleton


I have BackTrack 5 R1 (kernel version 2.6.39.4) at hand. Let's consider a ready security module, for example, SELinux (the /security/selinux/ directory). Its main mechanism is described in the hooks.c file. Basing on this file, I have created the skeleton of a new security module (a little bit later we'll make something interesting out of it).

We fill the monstrous structure of security_ops with pointers to our functions. You only have to replace SELinux with the name of your module (in my example it is PtLSM) for all the functions. Then edit the bodies of all the functions: those that return void should be empty and those that return int should return 0. As a result we have LSM that does nothing and allows everything that the native security mechanism allows (the module source code: pastebin.com/Cst0VVQh).

Here is a little and sad digression. For security reasons, the kernel ceased to export characters necessary for writing security modules in the form of loadable kernel modules (Linux Kernel Module, LKM) starting with version 2.6.24. For instance, the function register_security, which allows registering a module and its hooks, was removed from export. That is why we are going to compile the kernel with our own module.

Create a directory with the name of the module PtLSM: /usr/src/linux-2.6.39.4/security/ptlsm/.
To build the module, perform the following actions:

1. Create Makefile:

obj-$(CONFIG_SECURITY_PTLSM) += ptlsm.o

2. Create Kconfig:

config SECURITY_PTLSM
bool «Positive Protection»
default n
help
This module does nothing in a positive kind of way.

If you are unsure how to answer this question, answer N.

3. Edit /security/Makefile and /security/Kconfig to make the new module known all over the world. Add strings as in other modules.

My files with added PtLSM:
1) Makefile — pastebin.com/k7amsnQK
2) Kconfig — pastebin.com/YDsPBGAz

Then make menuconfig in the directory with the kernel source codes, choose PtLSM among the Security Options.



Now make, make modules_install, and make install. The module is placed in the kernel, and using the dmesg utility you can check what the module records to the log.

Writing a super cool module


It is time to make our module incredibly cool! Let the module disable any actions on the computer, if a USB device with a defined Vendor ID and Product ID is not connected to it (I use IDs of Galaxy S II as an example).


I have changed the body of the function ptlsm_inode_create, which checks whether this or that process can create files. If the function finds the device of ‘the supreme power,’ then it will allow execution. Similar checks can be performed for any other actions.
static int ptlsm_inode_create(struct inode *dir, struct dentry *dentry, int mask)
static int ptlsm_inode_create(struct inode *dir, struct dentry *dentry, int mask)
{
    if (find_usb_device() != 0)
    {
        printk(KERN_ALERT "You shall not pass!\n");
        return -EACCES;
    }
    else {
        printk(KERN_ALERT "Found supreme USB device\n");
    }

    return 0;
}
Now would be useful to write the find_usb_device function. It will analyze all USB devices in the system and choose the one with the necessary ID. Information about USB devices is stored in the form of trees, the roots of which are called root hub devices. The list of all the roots is in usb_bus_list.
static int find_usb_device(void)
{
    struct list_head* buslist;
    struct usb_bus* bus;
    int retval = -ENODEV;

    mutex_lock(&usb_bus_list_lock);

    for (buslist = usb_bus_list.next; buslist != &usb_bus_list; buslist = buslist->next) 
    {
        bus = container_of(buslist, struct usb_bus, bus_list);
        retval = match_device(bus->root_hub);
        if (retval == 0)
        {
            break;
        }
    }    

    mutex_unlock(&usb_bus_list_lock);
    return retval;
}
And finally let’s consider the function match_device which checks Vendor ID and Product ID.

static int match_device(struct usb_device* dev)
{
    int retval = -ENODEV;
    int child;

    if ((dev->descriptor.idVendor == vendor_id) &&
        (dev->descriptor.idProduct == product_id)) 
    {
        return 0;
    }

    for (child = 0; child < dev->maxchild; ++child) 
    {
        if (dev->children[child]) 
        {
            retval = match_device(dev->children[child]);
            if (retval == 0)
            {
                return retval;
            }
        }
    }

    return retval;
}

Let's add a few headings to work with USB.

#include <linux/usb.h>
#include <linux/usb/hcd.h>

Repeat the actions to insert the module. And buy a cool cell phone, to use your computer.


Author: Dmitry Sadovnikov, Positive Research.

14 comments:

  1. This comment has been removed by a blog administrator.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. I have read your blog and i got a very useful and knowledgeable information from your blog.its really a very nice article.You have done a great job . If anyone want to get Sharepoint training in Chennai, Please visit Greens Technologies Sharepoint training located at Chennai Adyar which offer Best Sharepoint training in Chennai

    ReplyDelete
  4. Excellent post!!! Java is most popular and efficient programming language available in the market today. It helps developers to create stunning desktop/web applications loaded with stunning functionalities. J2EE Training in Chennai | JAVA Training in Chennai

    ReplyDelete
  5. I prefer salesforce tool for CRM. It is a cloud based crm tool preferred by many professionals.
    Salesforce training in Chennai|Salesforce training institute in Chennai

    ReplyDelete
  6. Cloud has beome the common word that is being used by most of the professional these day. The reason for relying on this technology is security. Your content too lecture the same. Thanks for sharing this worth able information in here. Keep blogging article like this.

    Hadoop Training Chennai
    | Big Data Course in Chennai | Manual testing training in Chennai

    ReplyDelete
  7. Hibernate and spring are the frameworks of Java. A java developer should be well aware of these frameworks in order to master the technology and work efficeiently.
    spring training in chennai | hibernate training in chennai
    FITA Academy reviews

    ReplyDelete
  8. Java is the most robust secured and multi threaded programming language which is the reason why most the the developers go for java. A single java code can be used for various platforms.
    JAVA training in chennai | java training institutes in chennai | FITA Academy Chennai

    ReplyDelete
  9. In the particular article You might understand how for getting started building net applications Contact Page

    ReplyDelete
  10. Java is a programing language which needs no introduction. Java is immensly popular anguage which is used in building softwares in mobile app or desktop. Even today java is used to program tools like hadoop, owing to this java has becom imensley popular and one of the most preffered language around the world.
    Java training in Chennai | Java training institute in Chennai | Java course in Chennai

    ReplyDelete
  11. Hadoop is one of the best cloud based tool for analysisng the big data. With the increase in the usage of big data there is a quite a demand for hadoop professionals.
    Big data training in Chennai | Hadoop training Chennai | Hadoop training in Chennai

    ReplyDelete
  12. The war between humans, orcs and elves continues earn to die . Lead your race through a series of epic battles, using your crossbow to fend off foes and sending out units to destroy castleshappy wheels . Researching and upgrading wisely will be crucial to your success! There are 5 ages total and each one will bring you new units to train to fight in the war for you cause.
    earn to die 2
    Whatever you do, don’t neglect your home base because you cannot repair it and once it is destroyed, you lose! Age of War is the first game of the series and really sets the tone for the Age of War games . Also try out the Age of Defense series as it is pretty similar.
    In this game, you start at the cavern men’s age, then evolvetank trouble ! There is a total of 5 ages, each with its units and turrets. Take control of 16 different units and 15 different turrets to defend your base and destroy your enemy.
    The goal of the game also differs depending on the level. In most levels the goal is to reach a finish line or to collect tokens. Many levels feature alternate or nonexistent goals for the player. The game controls are shown just under gold miner. Movement mechanisms primarily include acceleration and tilting controls. cubefield
    It consists of a total of 17 levels and the challenge you face in each level increases as you go up. unfair mario The game basically has a red ball that has to be moved across the various obstacles in its path to the goal. slitherio

    ReplyDelete
  13. Great! Thanks for sharing the information. That is very helpful for increasing my knowledge in this fiel
    Red Ball | | duck life | Slitherio
    Red Ball 2 | Red Ball 3 | Red Ball 4

    ReplyDelete