The OpenNET Project
 
Search (keywords):  SOFT ARTICLES TIPS & TRICKS SECURITY
LINKS NEWS MAN DOCUMENTATION


[UNIX] Linux 2.6 Kernel Capability LSM Module Local Privilege Elevation


<< Previous INDEX Search src Set bookmark Go to bookmark Next >>
Date: 27 Dec 2004 16:16:05 +0200
From: SecuriTeam <support@securiteam.com.>
To: [email protected]
Subject: [UNIX] Linux 2.6  Kernel Capability LSM Module Local Privilege Elevation

The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com
- - promotion

The SecuriTeam alerts list - Free, Accurate, Independent.

Get your security news from a reliable source.
http://www.securiteam.com/mailinglist.html 

- - - - - - - - -




  Linux 2.6  Kernel Capability LSM Module Local Privilege Elevation
------------------------------------------------------------------------


SUMMARY

POSIX.1e Capability is a very important component of Linux kernel. In the 
original Linux kernel, system security relied on it and DAC. In new the 
kernel version, Linux Security Modules (LSM) framework was introduced to 
provide a lightweight, general-purpose framework for access control. Some 
Linux security projects were ported to LSM and accepted by kernel source, 
such as POSIX.1e Capability and SE-Linux. Users can compile Capability as 
a Linux Loadable Kernel Module, and insert it into kernel at any time he 
or she wants to. Under this situation, after inserting Capability module, 
due to an error in handling of credentials existing processes (normal user 
processes) will posses root privileges.

DETAILS

When privileged operations are controlled by the Capability LSM module, it 
mediates privileged operations based on the credentials of processes. The 
credentials consists of three fields of task_struct, namely, 
cap_permitted, cap_inheritable and cap_effective.

Before a user processes carries out a privileged operation (such as 
sethostname, override DAC, raw IO etc.), the operating system will check 
cap_effective field (in cap_capable hooks function of security/commoncap.c 
(2.6.*) or security/capability.c (2.5.72-lsm1)):

        if (cap_raised (tsk->cap_effective, cap)))
                return 0;
        else
                return -EPERM;


In general, only root processes can possess Capability privileges.

When the Capability is enabled in the kernel and no other LSM security 
modules are loaded, the kernel uses default security function operations 
(security/dummy.c) to mediate privilege operation.

The logic of dummy operations is very simple: if a process wants to 
perform a privileged operation, the euid property of it must be zero 
(root), or fsuid property must be zero when this privileged operation 
involved with file system.

However, dummy operations do nothing about credentials of processes, the 
credentials of any process is a clone of its parent process. As results, 
the credentials of all process, even normal user process, are the same as 
that of the Init process. As the Init process is a privileged process, it 
is assigned total Capability privileges when the system starts.

Unfortunately, after Capability LSM module is loaded, it does not 
recomputed the credentials of existing processes (before the insertion of 
Capability module).

Before the insertion, only root processes could have performed privileged 
operations controlled, as it is defined by the dummy operations. After 
insertion, the control of privileged operations is switched from the dummy 
operations to the Capability module based on the process's credentials.

As a result, all existing processes gain the same privileges as that set 
to the Init process, even if they are normal user processes.

Example:
Before loading Capability module, run a vim editor as a normal user. In 
vim, enter command ":r /etc/shadow" vim response "can't open file 
/etc/shadow" the request to access a root file is denied.

Don't end vim, switch to another console and login as root, insert 
Capability module into kernel.
#modprobe capability 

After inserting, go back to vim and try to open file /etc/shadow again, 
you will find you can read, edit and save(w!) this file as a normal user! 
The reason for this wrong access control is error credentials of vim so as 
to it has Capability privilege CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH.

Let's view the credentials with a shell command.

$cat /proc/2454/status (2454 is the pid of vim)

Name: vim
State: S (sleeping)
SleepAVG: 91%
Tgid: 2454
Pid: 2454
PPid: 1552
TracerPid: 0
Uid: 500 500 500 500
Gid: 500 500 500 500
FDSize: 256
Groups: 500
VmSize: 9356 kB
VmLck: 0 kB
VmRSS: 2728 kB
VmData: 856 kB
VmStk: 16 kB
VmExe: 1676 kB
VmLib: 3256 kB
Threads: 1
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 8000000000003000
SigCgt: 00000000ef824eff
CapInh: 0000000000000000
CapPrm: 00000000ffffffff
CapEff: 00000000fffffeff 

The last three lines are the credentials of vim, it has all Capability 
privileges besides CAP_SETPCAP.

Above test was performed under 2.6.* and 2.5.72-lsm1.

Workaround:
In order to fix this bug, we may have two methods. One is moving the 
computation of credentials from Capability module to kernel. The other is 
adding some code in Capability module to re-compute credentials of existed 
process. flashsky choose the second method, add following code in 
security/capability.c:

static void recompute_capability_creds(struct task_struct *task)
{
        if(task->pid <= 1)
                return;
 

        task_lock(task);
        task->keep_capabilities = 0;
         
        if ((task->uid && task->euid && task->suid) && 
!task->keep_capabilities)
                cap_clear (task->cap_permitted);
        else
                task->cap_permitted = CAP_INIT_EFF_SET;
 
 
 
        if (task->euid != 0){
                cap_clear (task->cap_effective);
        }
        else{
                task->cap_effective = CAP_INIT_EFF_SET;
        }
         
        if(task->fsuid)
                task->cap_effective &= ~CAP_FS_MASK;
        else
                task->cap_effective |= CAP_FS_MASK;
         
        task_unlock(task);
         
        return;
} 


And add following code in Capability init function capability_init before 
it return:
 struct task_struct *task;
 
        read_lock(&tasklist_lock);
        for_each_process(task){
                recompute_capability_creds(task);
        }
        read_unlock(&tasklist_lock);
         
        return 0; 


After modifying capability.c, we need "make" and "make modules_install" 
again. Unload Capability module (rmmod capability; rmmod commoncap) and 
retry the above example, all the accesses to a root file by normal user 
existed process are always denied before and after inserting Capability 
module.

Test and view the credentials again.

$cat /proc/(pid of vim)/status

Name: vim
State: S (sleeping)
SleepAVG: 91%
Tgid: 2864
Pid: 2864
PPid: 1552
TracerPid: 0
Uid: 500 500 500 500
Gid: 500 500 500 500
FDSize: 256
Groups: 500
VmSize: 9360 kB
VmLck: 0 kB
VmRSS: 2816 kB
VmData: 860 kB
VmStk: 16 kB
VmExe: 1676 kB
VmLib: 3256 kB
Threads: 1
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 8000000000003000
SigCgt: 00000000ef824eff
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000 


ADDITIONAL INFORMATION

The information has been provided by  <mailto:liangbin@venustech.com.cn.> 
LiangBin.




This bulletin is sent to members of the SecuriTeam mailing list. To unsubscribe from the list, send mail with an empty subject line and body to: [email protected] In order to subscribe to the mailing list, simply forward this email to: [email protected]

DISCLAIMER: The information in this bulletin is provided "AS IS" without warranty of any kind. In no event shall we be liable for any damages whatsoever including direct, indirect, incidental, consequential, loss of business profits or special damages.

<< Previous INDEX Search src Set bookmark Go to bookmark Next >>



Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру