首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将LKM移植到LSM -意外行为

将LKM移植到LSM -意外行为
EN

Stack Overflow用户
提问于 2020-05-06 15:27:58
回答 1查看 80关注 0票数 0

我有一个,它检查是否存在特定的USB设备,并在匹配时执行打印。这段代码运行良好,并如我所期望的那样执行。

代码语言:javascript
复制
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/list.h>
#include <linux/slab.h>

MODULE_LICENSE("GPL");

static int HARD_VEND;
static int HARD_PROD;
static char *HARD_SERI;

struct USBCred
{
    int vendor;
    int product;
    char serial[128];
};

static struct USBCred create_creds_device(struct usb_device *dev)
{
    struct USBCred creds;

    creds.vendor = dev->descriptor.idVendor;
    creds.product = dev->descriptor.idProduct;

    if((dev->serial) == NULL)
    {
        strcpy(creds.serial, "(null)");
    } else {
        strcpy(creds.serial, dev->serial);
    }

    return creds;
}

static struct USBCred create_creds_hub(struct usb_bus *bus)
{
    struct USBCred creds;

    creds.vendor = bus->root_hub->descriptor.idVendor;
    creds.product = bus->root_hub->descriptor.idProduct;

    if((bus->root_hub->serial) == NULL)
    {
        strcpy(creds.serial, "(null)");
    } else {
        strcpy(creds.serial, bus->root_hub->serial);
    }

    return creds;
}


static int check_usb_creds(struct USBCred usb_data) 
{
    if(usb_data.vendor != HARD_VEND && usb_data.product != HARD_PROD && strcmp(usb_data.serial, HARD_SERI))
    {
        return 1;
    } else 
    {
        printk(KERN_INFO "*********** RootPug Module - Match ***********");
        printk(KERN_INFO "Vendor ID = %x, HC Vendor ID  = %x", usb_data.vendor, HARD_VEND);
        printk(KERN_INFO "Product ID = %x, HC Product ID = %x", usb_data.product, HARD_PROD);
        printk(KERN_INFO "Serial = %s, HC Serial= %s", usb_data.serial, HARD_SERI);
        return 0; 
    }
}

static int __init usb_fun_init (void)  
{  
    int id;
    int chix;

    struct USBCred cred;

    struct usb_bus *bus; 
    struct usb_device *dev, *childdev = NULL;

    HARD_VEND = 0x26bd;
        HARD_PROD = 0x9917;
        HARD_SERI = "070172966462EB10";

    mutex_lock(&usb_bus_idr_lock);

    idr_for_each_entry(&usb_bus_idr, bus, id)
        {        
        cred = create_creds_hub(bus);
        //print_USBCred(cred);
        check_usb_creds(cred);

        dev = bus->root_hub;
        usb_hub_for_each_child(dev, chix, childdev)
        {
            if(childdev)
            {           
                usb_lock_device(childdev);
                cred = create_creds_device(childdev);
                //print_USBCred(cred);
                check_usb_creds(cred);
                usb_unlock_device(childdev);
                        }
        }
    }

    mutex_unlock(&usb_bus_idr_lock);    
    return 0;  
}

static void __exit usb_fun_exit (void)  
{  
    printk(KERN_INFO "***************** RootPug Module - Exit *****************\n");  
} 

module_init(usb_fun_init);
module_exit(usb_fun_exit); 

当转移到LSM时,LSM没有问题地注册,钩子注册正确,但是代码没有我想要的行为,我不明白为什么。我添加了调试语句,以了解代码到达哪一点,但似乎没有执行idr_for_each_entry(),因为没有打印该循环的调试状态。我使用了一个基于标志的系统来提供一种机制,让-EPERM作为默认的返回值,如果找到usb,就会被覆盖。

我不明白为什么只执行互斥,没有检查集线器或usb设备,但相同的代码作为一个LKM工作。所讨论的实际代码在appcl_inode_create钩子中。为了简洁起见,我忽略了其他挂钩,但它们目前除了返回期望值0之外什么也不做。

代码语言:javascript
复制
#include <linux/init.h>
#include <linux/kd.h>
#include <linux/kernel.h>
#include <linux/tracehook.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/lsm_hooks.h>
#include <linux/xattr.h>
#include <linux/security.h>
#include <linux/capability.h>
#include <linux/unistd.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/slab.h>
#include <linux/pagemap.h>
#include <linux/proc_fs.h>
#include <linux/magic.h>
#include <linux/ctype.h>
#include <linux/swap.h>
#include <linux/spinlock.h>
#include <linux/syscalls.h>
#include <linux/dcache.h>
#include <linux/file.h>
#include <linux/fdtable.h>
#include <linux/namei.h>
#include <linux/mount.h>
#include <linux/tty.h>
#include <linux/types.h>
#include <linux/atomic.h>
#include <linux/bitops.h>
#include <linux/interrupt.h>
#include <linux/parser.h>
#include <linux/nfs_mount.h>
#include <linux/string.h>
#include <linux/mutex.h>
#include <linux/posix-timers.h>
#include <linux/syslog.h>
#include <linux/user_namespace.h>
#include <linux/export.h>
#include <linux/msg.h>
#include <linux/shm.h>
#include <linux/gfp.h>

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/list.h>
#include <linux/cred.h>
#include <linux/fs.h>
#include <linux/fs_struct.h>
#include <linux/fsnotify.h>
#include <linux/path.h>
#include <linux/fdtable.h>
#include <linux/binfmts.h>
#include <linux/time.h>

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

#include "include/appcl_lsm.h"
//#include "include/audit.h"

MODULE_LICENSE("GPLv3");
MODULE_AUTHOR("Jack Cuthbertson");


static int HARD_VEND;
static int HARD_PROD;
static char *HARD_SERI;

struct USBCred
{
    int vendor;
    int product;
    char serial[128];
};

static struct USBCred create_creds_device(struct usb_device *dev)
{
    struct USBCred creds;

    creds.vendor = dev->descriptor.idVendor;
    creds.product = dev->descriptor.idProduct;

    if((dev->serial) == NULL)
    {
        strcpy(creds.serial, "(null)");
    } else {
        strcpy(creds.serial, dev->serial);
    }

    return creds;
}

static struct USBCred create_creds_hub(struct usb_bus *bus)
{
    struct USBCred creds;

    creds.vendor = bus->root_hub->descriptor.idVendor;
    creds.product = bus->root_hub->descriptor.idProduct;

    if((bus->root_hub->serial) == NULL)
    {
        strcpy(creds.serial, "(null)");
    } else {
        strcpy(creds.serial, bus->root_hub->serial);
    }

    return creds;
}


static int check_usb_creds(struct USBCred usb_data) 
{
    if(usb_data.vendor != HARD_VEND && usb_data.product != HARD_PROD && strcmp(usb_data.serial, HARD_SERI))
    {
            printk(KERN_INFO "*********** RootPlug Module - Non Match ***********");
            printk(KERN_INFO "Vendor ID = %x, HC Vendor ID  = %x", usb_data.vendor, HARD_VEND);
        printk(KERN_INFO "Product ID = %x, HC Product ID = %x", usb_data.product, HARD_PROD);
        printk(KERN_INFO "Serial = %s, HC Serial= %s", usb_data.serial, HARD_SERI);
        return 1;
    } else 
    {
        printk(KERN_INFO "*********** RootPlug Module - Match ***********");
        printk(KERN_INFO "Vendor ID = %x, HC Vendor ID  = %x", usb_data.vendor, HARD_VEND);
        printk(KERN_INFO "Product ID = %x, HC Product ID = %x", usb_data.product, HARD_PROD);
        printk(KERN_INFO "Serial = %s, HC Serial= %s", usb_data.serial, HARD_SERI);
        return 0; 
    }
}

static int appcl_lsm_inode_create(struct inode *dir, struct dentry *dentry, umode_t mode)
{
int id;
int chix;

int flag = -EPERM;

struct USBCred cred;

struct usb_bus *bus; 
struct usb_device *dev, *childdev = NULL;

    HARD_VEND = 0x26bd;
    HARD_PROD = 0x9917;
    HARD_SERI = "070172966462EB10";

    printk(KERN_ALERT "Rootplug: Beginning check\n");

    mutex_lock(&usb_bus_idr_lock);
    printk(KERN_ALERT "Rootplug: Mutex locked the bus list\n");

    //loop though all usb buses
    idr_for_each_entry(&usb_bus_idr, bus, id)
    {        
        printk(KERN_ALERT "Rootplug: Checking hubs.\n");        
        cred = create_creds_hub(bus);

        //Check creds of usb buses
        if(check_usb_creds(cred) == 0)
        {
            mutex_unlock(&usb_bus_idr_lock);
            printk(KERN_ALERT "Rootplug: Unlock hub success!\n");
            flag = 0;
        } else {
            printk(KERN_ALERT "Rootplug: Unlock hub fail!\n");
        }


        dev = bus->root_hub;
        usb_hub_for_each_child(dev, chix, childdev)
        {
            if(childdev)
            {   
                printk(KERN_ALERT "Rootplug: Checking USB devices\n");      
                usb_lock_device(childdev);
                cred = create_creds_device(childdev);

                if(check_usb_creds(cred) == 0)
                {
                    usb_unlock_device(childdev);
                    mutex_unlock(&usb_bus_idr_lock);
                    printk(KERN_ALERT "Rootplug: Unlock USB success!\n");       
                } else {
                    usb_unlock_device(childdev);
            printk(KERN_ALERT "Rootplug: Unlock USB Failure!\n");       
                }

            } else {

                printk(KERN_ALERT "Rootplug: No child dev\n");
            }
        }
    }

    mutex_unlock(&usb_bus_idr_lock);
    printk(KERN_ALERT "Rootplug: Unlock failed - Flag: %i\n", flag);
    return flag;
}

static struct security_hook_list appcl_hooks[] = {
    /*
     * XATTR HOOKS
     */
    LSM_HOOK_INIT(inode_setxattr, appcl_lsm_inode_setxattr),
    LSM_HOOK_INIT(inode_post_setxattr, appcl_lsm_inode_post_setxattr),
    LSM_HOOK_INIT(inode_getxattr, appcl_lsm_inode_getxattr),
    LSM_HOOK_INIT(inode_removexattr, appcl_lsm_inode_removexattr),
    LSM_HOOK_INIT(d_instantiate, appcl_lsm_d_instantiate),
    LSM_HOOK_INIT(inode_setsecurity, appcl_lsm_inode_setsecurity),
    LSM_HOOK_INIT(inode_init_security, appcl_lsm_inode_init_security),
    /*
     * INODE HOOKS
     */
    LSM_HOOK_INIT(inode_alloc_security, appcl_lsm_inode_alloc_security),
    LSM_HOOK_INIT(inode_free_security, appcl_lsm_inode_free_security),
    /*
     * General permission mask
     */
    LSM_HOOK_INIT(inode_permission, appcl_lsm_inode_permission),
    /*
     * Specific permission hooks
     */
    LSM_HOOK_INIT(inode_create, appcl_lsm_inode_create),
    LSM_HOOK_INIT(inode_rename, appcl_lsm_inode_rename),
    LSM_HOOK_INIT(inode_link, appcl_lsm_inode_link),
    LSM_HOOK_INIT(inode_unlink, appcl_lsm_inode_unlink),
    LSM_HOOK_INIT(inode_symlink, appcl_lsm_inode_symlink),
    LSM_HOOK_INIT(inode_mkdir, appcl_lsm_inode_mkdir),
    LSM_HOOK_INIT(inode_rmdir, appcl_lsm_inode_rmdir),
    LSM_HOOK_INIT(inode_mknod, appcl_lsm_inode_mknod),
    LSM_HOOK_INIT(inode_readlink, appcl_lsm_inode_readlink),
    LSM_HOOK_INIT(inode_follow_link, appcl_lsm_inode_follow_link),
    //LSM_HOOK_INIT(inode_setattr, appcl_lsm_inode_setattr),
    //LSM_HOOK_INIT(inode_getattr, appcl_lsm_inode_getattr),
    /*
     * FILE HOOKS
     */
    LSM_HOOK_INIT(file_alloc_security, appcl_lsm_file_alloc_security),
    LSM_HOOK_INIT(file_free_security, appcl_lsm_file_free_security),
    LSM_HOOK_INIT(file_permission, appcl_lsm_file_permission),
    //LSM_HOOK_INIT(file_fcntl, appcl_lsm_file_fcntl),
    LSM_HOOK_INIT(file_open, appcl_lsm_file_open),
    LSM_HOOK_INIT(file_receive, appcl_lsm_file_receive),
    /*
     * CRED HOOKS
     */
    LSM_HOOK_INIT(cred_alloc_blank, appcl_lsm_cred_alloc_blank),
    LSM_HOOK_INIT(cred_free, appcl_lsm_cred_free),
    LSM_HOOK_INIT(cred_prepare, appcl_lsm_cred_prepare),
    LSM_HOOK_INIT(cred_transfer, appcl_lsm_cred_transfer),
    LSM_HOOK_INIT(bprm_set_creds, appcl_lsm_bprm_set_creds),
    /*
     * SUPERBLOCK HOOKS
     */
    LSM_HOOK_INIT(sb_alloc_security, appcl_lsm_sb_alloc_security),
    LSM_HOOK_INIT(sb_free_security, appcl_lsm_sb_free_security),
};

static __init int appcl_init(void)
{
    printk(KERN_ALERT "Rootplug: Module loading... \n");

    /*
     * Set security attributes for initial task
     */

    security_add_hooks(appcl_hooks, ARRAY_SIZE(appcl_hooks), "appcl");

    printk(KERN_ALERT "Rootplug: module initialised\n");

    return 0;
}

DEFINE_LSM(appcl) = {
        .name = "appcl",
        .init = appcl_init,
};
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-05-10 08:35:04

处理匹配的函数对printk函数使用了不同的警报级别。因此,在引导过程的那个阶段,消息没有显示到控制台。

当时的情况:

代码语言:javascript
复制
printk(KERN_INFO "message");

应:

代码语言:javascript
复制
printk(KERN_ALERT "message");

调用了匹配函数,在使用强制返回0的钩子重新编译内核之后,我可以从/var/log/*中看到该函数正在执行,并输出正确的信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61639046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档