(已解决)Linux 安全模块:有没有办法检查/审计共享库加载?

问题描述 投票:0回答:0

我正在开发基于 xattr(文件的扩展属性)的 linux 安全模块,我想实施安全措施以防止加载没有特定 xattr 的共享库。这需要我 hook file_opencheck the file's magic number 以确定它是否是共享库,然后进行基于 xattr 的安全检查。

以下代码是我的实现(还没有完全完成)。钩子 file_open

xattracl_file_open(struct file *file)
调用
xattracl_magic_check_elf(struct file* file)
通过读取其前 4 个字节来检查
file
是否为 ELF 格式。

但是我发现了两个问题。首先,我无法直接从这个结构

file
获取文件路径,它将始终打印为
(efault)
,因此我使用了自定义的
xattracl_get_realpath(struct path *path)
(类似于tomoyo LSM模块所做的)。其次,每次读到的4个字节,好像都是不同的值,完全看不懂

然后我尝试调用

flip_open()
因为我可以获得真实路径名并获取“真实”结构文件以读取其 4 个字节,这将不起作用,因为挂钩的 file_open() 将递归调用自身并导致内核恐慌

代码(为了便于阅读省略了部分):

// ............

// Read magic number from a file's first 4B
// Param:
//  struct file *file: the file to be checked
// Return:
//  (int)-ENOMEM/-ENOENT/0/1 for memory allocation error/file reading error/being ELF/not ELF
int xattracl_file_magic_check_elf(struct file *file){
    const char *realpath=xattracl_get_realpath(&file->f_path);
    if(!realpath){
        return -ENOMEM;
    }
    char *value=(char*)kmalloc(4,GFP_NOFS);
    if(!value){
        return -ENOMEM;
    }
    kernel_read(file,value,4,0)==-1);
    int iself=(value[0]==0x7F)&&(value[1]==0x45)&&(value[2]==0x4C)&&(value[3]==0x46);
    printk(KERN_INFO"[xattracl] (file_magic_check_elf) file:%s magic:%02X%02X%02X%02X iself:%d\n",realpath,value[0],value[1],value[2],value[3],iself);
    filp_close(realfile,NULL);
    kfree(realpath);
    kfree(value);
    return iself;
}

// Hooked file_open for ELF loading control
// Param:
//  struct file *file: the file to be checked
// Return:
//  (static int)-ENOMEM/-EPERM/0 for memory allocation error/denying loading/allowing loading
static int xattracl_file_open(struct file *file){
    // If file is not ELF, allow loading.
    int iself=xattracl_file_magic_check_elf(file);
    if(!iself){
        // Only return 0 for testing
        // return -EPERM;
        return 0;
    }
    // Get the file's xattr
    struct dentry *dentry=file->f_path.dentry;
    struct inode *inode=d_backing_inode(dentry);
    char *value=(char*)kmalloc(XATTRACL_XATTR_VALUE_SIZE,GFP_NOFS);
    if(!value){
        return -ENOMEM;
    }
    int size=__vfs_getxattr(dentry,inode,XATTRACL_XATTR_NAME,value,XATTRACL_XATTR_VALUE_SIZE);
    value[MAX(size,0)]=0;
    // Users can only load shared libraries with XATTRACL_XATTR_NAME:XATTRACL_XATTR_ACTION_ALLOW
    int action=strcmp(value,XATTRACL_XATTR_ACTION_ALLOW)?-EPERM:0;
    printk(KERN_INFO"[xattracl] (file_open) file:%s type:%s "XATTRACL_XATTR_NAME":%s action:%s\n",dentry->d_name.name,iself?"OTHER":"ELF",value,action?"deny":"allow");
    kfree(value);
    // Only return 0 for testing
    // return action;
    return 0;
}

// ............

static struct security_hook_list xattracl_hooks[] __lsm_ro_after_init={
    // ............
    LSM_HOOK_INIT(file_open,xattracl_file_open),
    // ............
};

// ............

这种奇怪现象的 dmesg 日志:



[pairman@fedora Downloads]$ dmesg | grep /usr/lib64/libc.so.6

[  176.002714] [xattracl] (file_magic_check_elf) file:/usr/lib64/libc.so.6, magic:35205B31 elf:0

[  176.006182] [xattracl] (file_magic_check_elf) file:/usr/lib64/libc.so.6, magic:CDDF5D32 elf:0

[  177.045407] [xattracl] (file_magic_check_elf) file:/usr/lib64/libc.so.6, magic:4DA46A31 elf:0

[  177.045412] [xattracl] (file_magic_check_elf) file:/usr/lib64/libc.so.6, magic:354E8438 elf:0

[  177.050782] [xattracl] (file_magic_check_elf) file:/usr/lib64/libc.so.6, magic:CDDF5D32 elf:0

[  177.053388] [xattracl] (file_magic_check_elf) file:/usr/lib64/libc.so.6, magic:5DDB5E31 elf:0

[  179.175885] [xattracl] (file_magic_check_elf) file:/usr/lib64/libc.so.6, magic:4DA46A31 elf:0

[  179.175907] [xattracl] (file_magic_check_elf) file:/usr/lib64/libc.so.6, magic:354E8438 elf:0

[pairman@fedora Downloads]$ xxd /usr/lib64/libc.so.6 | head -1

00000000: 7f45 4c46 0201 0103 0000 0000 0000 0000  .ELF............



一直在找selinux和apparnor的类似场景和源码,没找到有用的东西

  1. 解释为什么我不能直接从

    file
    (即
    (efault)
    )获取文件路径,为什么它的内容看起来随机、不正确并且每次都在变化,以及我如何正确获取文件的幻数不打电话
    file_open
    .

  2. 是否有其他方法以正确的 linux-security-module 方式检查和审计共享库加载?这样我就不必淹没在这种痛苦中。

file linux-kernel shared-libraries xattr linux-security-module
© www.soinside.com 2019 - 2024. All rights reserved.