Next Previous Contents

4. Protect Important Process.

Processes are the active entries in the operation system. There are two specified process in the kernel, process id 0 (swapd) and process 1(init). The init process is parent of all process runing after the system booting.

4.1 unkillable process.

As you can see that if someone gains the root privilege, he can easily kill any process by sending special signal to that process . In order to kill a process, he must past the pid of the process in the kernel, and then use the pid to kill it.

The system call used to kill process is kill(), which is impletementedsys_kill() in kernel.

Let's look at the code with LIDS protection.



/* in /usr/src/linux/kernel/signal.c */
asmlinkage int
sys_kill(int pid, int sig)
{
        struct siginfo info;
                
#ifdef CONFIG_LIDS_INIT_CHILDREN_LOCK                                                   pid_t this_pid;
        int i;                              
#ifdef CONFIG_LIDS_ALLOW_KILL_INIT_CHILDREN 
        if (!(current->flags & PF_KILLINITC)) 
#endif                  
        if (lids_load && lids_local_load && LIDS_FISSET(lids_flags,LIDS_FLAGS_LOCK_INIT_CHILDREN)) {
                this_pid = pid>0?pid:-pid;
                for(i=0;i<lids_last_pid;i++) {
                        if( this_pid == lids_protected_pid[i]) {
                                lids_security_alert("Try to kill pid=%d,sig=%d\n",pid,sig);
                                return -EPERM;
                        }
                }
        }
#endif
...
}

You can see that there are two tags in kernel,CONFIG_LIDS_INIT_CHILDREN_LOCK and CONFIG_LIDS_ALLOW_KILL_INIT_CHILDREN.

With the CONFIG_LIDS_INIT_CHILDREN_LOCK on, LIDS can protect the initial runing up process. For example, if you running inetd on the system, you bring it up before sealing the kernel. After that, you can not kill it. But if someone telnet to the server, inetd will bring up a child process to serve the user, this child process can not be protect by LIDS, because the user can be exit and then kill the process at any time.

4.2 hidden process.

Another method to protect process is to hide the process. when a hacker compromise you system, he will login, and then look around if there are some known processes are watching him, and then he will kill them. If you hide the process by this feature, the hacker will not know anything about the process and then you can log anything he done on the system.

How to hide process.

In order to hide the process, you need to provide the full pathname while configurate the kernel.

When the kernel boot up, LIDS will pick up the filename's inode into a structure named proc_to_hide[],



/* include/linux/sched.h */

#ifdef CONFIG_LIDS_HIDE_PROC
#define PF_HIDDEN       0x04000000      /* Hidden process */
#endif

/* in fs/lids.c */

#ifdef CONFIG_LIDS_HIDE_PROC
struct allowed_ino proc_to_hide[LIDS_MAX_ALLOWED];
int last_hide=0;
#endif
....

/* in fs/lids.c , init_vfs_security(),
   fill up the hidden process in proc_to_hide[]  
 */
#ifdef CONFIG_LIDS_HIDE_PROC
        lids_fill_table(proc_to_hide,&last_hide,LIDS_MAX_ALLOWED,CONFIG_LIDS_HIDDEN_PROC_PATH);
#endif

PF_HIDDEN is used to make the kernel to check if the process can be seen when user issue a "display process information" command, for example the command "ps -a". If a process has been marked as hidden process by LIDS, when it exec, the process will get an attribute of PF_HIDDEN. Then, when the system output processes information to the user program, it will check if the current output process own a flag PF_HIDDEN. If found, it will not output any information about the process.


/* in fs/exec.c */
int do_execve(char * filename, char ** argv, char ** envp, struct pt_regs * regs)
{
        ...
        if (retval >= 0) {
#ifdef CONFIG_LIDS_HIDE_PROC
                        if (lids_search_proc_to_hide(dentry->d_inode))
                                current->flags |= PF_HIDDEN;
        ...

Since every process in linux has a entry in /proc filesystem, we also need to make the proc file entry of the hidden process insivible to users.



/* fs/proc/root.c , to make the proc fs invisibe to the hidden process*/
static struct dentry *proc_root_lookup(struct inode * dir, struct dentry * dentry)
{
...
        inode = NULL;

#ifdef CONFIG_LIDS_HIDE_PROC
        if ( pid && p && (! ((p->flags & PF_HIDDEN) && lids_load && lids_local_load)) ) {
#else
        if (pid && p) {
#endif
                unsigned long ino = (pid >> 16) + PROC_PID_INO;
                inode = proc_get_inode(dir->i_sb, ino, &proc_pid);
                if (!inode)
                        return ERR_PTR(-EINVAL);
                inode->i_flags|=S_IMMUTABLE;
        }
...
}

Then if the process is marked as PF_HIDDEN, it will not display in the proc filesystem.


Next Previous Contents