网络安全 频道

Linux入侵监测系统LIDS原理(2)

LIDS保护数据结构

 

   在分析完Linux文件系统后,让我们来看看LIDS是如何容VFS来保护文件和目录的。
在/usr/src/Linux/fs/lids.c

struct secure_ino {
unsigned long int ino; /* the inode number */
kdev_t dev; /* the dev number */
int type; /* the file type */
};
  上面的结构用一对来存储保护文件或目录的结点。“type”是用来标明保护结点文件类型的。

   LIDS有4种类型

   在/usr/src/Linux/include/Linux/fs.h
   #define LIDS_APPEND 1 /* APPEND ONLY FILE */
   #define LIDS_READONLY 2 /* Read Only File */
   #define LIDS_DEVICE 3 /* Protect MBR Writing to device */
   #define LIDS_IGNORE 4 /* Ignore the protection */

   通过secure_ino结构,我们能很容易的初使化保护的文件或是在内核里执行以下函数。


在/usr/src/Linux/fs/lids.c
int lids_add_inode(unsigned long int inode ,kdev_t dev , int type)
{

if ( last_secure == (LIDS_MAX_INODE-1))
return 0;

secure[last_secure].ino = inode;
secure[last_secure].dev = dev;
secure[last_secure].type = type;

secure[++last_secure].ino = 0;

#ifdef VFS_SECURITY_DEBUG
printk("lids_add_inode : return %d
",last_secure);
#endif
return last_secure;
}
  就象你在上面代码上可以看到的,给secure_ino加到一个结点上是非常容易的。被保护的结点会在系统启动的时候初使化。初使化程序在/usr/src/Linux/fs/lids.c的init_vfs_security()里。

   现在,让我们看看LIDS是如何来检查是否一个结点已经受到保护。


在/usr/src/Linux/fs/open.c
int do_truncate(struct dentry *dentry, unsigned long length)
{
struct inode *inode = dentry->d_inode;
int error;
struct iattr newattrs;

/* Not pretty: "inode->i_size" shouldnt really be "off_t". But it is. */
if ((off_t) length < 0)
return -EINVAL;

#ifdef CONFIG_LIDS
if (lids_load && lids_local_load) {
error = lids_check_base(dentry,LIDS_READONLY);
if (error) {
lids_security_alert("Try to truncate a protected file (dev %d %d,inode %ld)",
MAJOR(dentry->d_inode->i_dev),
MINOR(dentry->d_inode->i_dev),
dentry->d_inode->i_ino);
.....................
  这个是LIDS加到内核里做检测的一个例子。你会看到lids_check_base()是LIDS保护方法的一个核心函数。

   你可以在LIDS要保护的地方看到很多LIDS保护方法用到lids_check_base()函数,特别是在Linux内核的子目录下。


在/usr/src/Linux/fs/lids.c

int lids_check_base(struct dentry *base, int flag)
{
..................
inode = base->d_inode; /* get the inode number */
parent = base->d_parent; /* get the parent diretory */

.................
----> do {
if ( inode == parent->d_inode)
break;
if ((retval = lids_search_inode(inode))) {
if ( retval == LIDS_IGNORE   
(retval == LIDS_DEVICE && flag != LIDS_DEVICE))
break;
if ( flag == LIDS_READONLY   
( flag == LIDS_APPEND && retval >flag )   
( flag == LIDS_DEVICE && flag == retval )) {
return -EROFS;
}
break;
}
inode = parent->d_inode;
} while( ((parent = parent->d_parent ) != NULL) );

return 0;
}
lids_check_base()会检查一个给定文件的dentry和它的父目录是否被保护。
  注意:如果它的父目录被保护,它下面的文件也会被保护。

   例如,如果“/etc/”被保护,“/etc/passwd”也一样被保护。

     在内核保护系统调用

   为了保护系统,LIDS会在一些检查临界的系统调用的时候做检查。因此,我们可以保护系统调用和限制文件系统的用户调用。

   这些是一些例子,

   open(),open是通过禁止一些权利来保护文件的打开。 你可以在打开调用open_namei()调用的时候LIDS在检测它。
   mknod(),mknod是用来在指定目录下保护mknod。
   unlink(), 在内核代码检查do_unlink()。

0
相关文章