Linux在加载和卸载内核模块后冻结

Linux在加载和卸载内核模块后冻结,linux,module,kernel,Linux,Module,Kernel,我正在尝试执行一个内核模块,该模块旨在检查当前连接的USB设备,并将它们与允许的USB设备列表进行比较。我编写了以下代码: #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <asm/segment.h> #include <asm/uaccess.h> #include <linux/buffer_head.h&g

我正在尝试执行一个内核模块,该模块旨在检查当前连接的USB设备,并将它们与允许的USB设备列表进行比较。我编写了以下代码:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <linux/buffer_head.h>

static int __init dummy_init(void)
{
    struct file * fp;
    struct file * ftmp;
    struct file * faux;

    loff_t file_size;
    int no_words;

    char* usb_content;
    char* pch;

    char vendor_id[5];

    char** word_mat;
    int word_size;
    int count;
    int check;

    char product_id[5];
    char* to_write;

    ftmp = filp_open("/var/tmp/usb_temp.txt", O_CREAT |  O_RDWR | O_APPEND, \
                                S_IRWXU | S_IRWXG | S_IRWXO);

    fp  = filp_open("/sys/kernel/debug/usb/devices", O_CREAT |  O_RDWR | O_APPEND, \
                                S_IRWXU | S_IRWXG | S_IRWXO);

    faux = filp_open("/var/tmp/rejection_list.txt", O_CREAT |  O_RDWR, \
                S_IRWXU | S_IRWXG | S_IRWXO);

    if(ftmp != NULL)
    {
         loff_t ppos = 0;

         file_size = vfs_llseek(ftmp,0,SEEK_END);

         usb_content  = kvmalloc(file_size, GFP_ATOMIC);

         if(usb_content == NULL)
         {
             printk(KERN_ERR "Error allocating memory for USB buffer!");
         }

         vfs_llseek(ftmp,0,SEEK_SET);

         kernel_read(ftmp, usb_content, file_size, &ppos);

         usb_content[file_size] = '\0';

         no_words = ((file_size * 2)/10);

         word_mat = kvmalloc(no_words, GFP_ATOMIC);

         count = 0;

         while( (pch = strsep(&usb_content," \n")) != NULL )
         {
            word_size = strlen(pch);
            word_mat[count] = kvmalloc(word_size+1, GFP_ATOMIC);
            strcpy(word_mat[count], pch);
            count++;
         }

         kvfree(usb_content);

         ppos = 0;

         if(fp == NULL)
         {
            printk(KERN_ERR "Cannot open Kernel USB files!\n");
         }  

         else
         {
            usb_content  = kvmalloc(2000, GFP_ATOMIC);

            if(usb_content == NULL)
            {
                printk(KERN_ERR "Error allocating memory for USB buffer!");
            }

            vfs_llseek(fp,0,SEEK_SET);

            kernel_read(fp, usb_content, 2000, &ppos);

            ppos = 0;

            while( (pch = strsep(&usb_content,"\n")) != NULL )
            {
                if(strstr(pch,"Vendor") != NULL)
                {
                    check = 0;

                    vendor_id[0] = pch[11];
                    vendor_id[1] = pch[12];
                    vendor_id[2] = pch[13]; 
                    vendor_id[3] = pch[14];
                    vendor_id[4] = '\0';

                    product_id[0] = pch[23];
                    product_id[1] = pch[24];
                    product_id[2] = pch[25];
                    product_id[3] = pch[26];
                    product_id[4] = '\0';

                    printk(KERN_INFO "Checking for %s %s\n",vendor_id,product_id);


                    for(count = 0; count < no_words; count = count+2)
                    {
                        if(vendor_id[0] == word_mat[count][0] && vendor_id[1] == word_mat[count][1] && vendor_id[2] == word_mat[count][2] && vendor_id[3] == word_mat[count][3] && product_id[0] == word_mat[count+1][0] && product_id[1] == word_mat[count+1][1] && product_id[2] == word_mat[count+1][2] && product_id[3] == word_mat[count+1][3])
                        {
                            printk(KERN_INFO "Approved for %s %s\n",vendor_id,product_id);
                            check = 1;
                            break;
                        }
                    }

                    if(check == 0)
                    {
                        printk(KERN_INFO "Calling script for blocking %s %s...\n", vendor_id, product_id);

                        to_write = kvmalloc(10, GFP_ATOMIC);

                        strncpy(to_write, vendor_id, 4);
                        strcat(to_write, " ");
                        strncat(to_write,product_id,4);
                        strcat(to_write, "\n");

                        kernel_write(faux,to_write,10,&ppos);

                        kvfree(to_write);

                    }
                }
            }

            kvfree(usb_content);

            for(count = 0; count < no_words; count++)
            {
                kvfree(word_mat[count]);
            }

            kvfree(word_mat);
        }
    }

    else{   
            printk(KERN_ERR "Error! Cannot open file\n");
    }

    filp_close(ftmp, NULL);
    filp_close(fp, NULL);
    filp_close(faux, NULL);
}

static void __exit dummy_exit(void)
{
        printk(KERN_INFO "Unloaded successfully!");
}

module_init(dummy_init);
module_exit(dummy_exit);
#包括
#包括
#包括
#包括
#包括
#包括
静态int\uu init虚拟初始化(void)
{
结构文件*fp;
结构文件*ftmp;
结构文件*faux;
文件大小;
int无_字;
字符*usb_内容;
char*pch;
字符供应商_id[5];
字符**word\u mat;
int字大小;
整数计数;
整数检查;
char乘积_id[5];
char*写入;
ftmp=filp_open(“/var/tmp/usb_temp.txt”),O_create | O|RDWR | O|u APPEND\
S|IRWXU | S|IRWXG | S|IRWXO);
fp=filp_open(“/sys/kernel/debug/usb/devices”),O_create | O_RDWR | O|u APPEND\
S|IRWXU | S|IRWXG | S|IRWXO);
faux=filp_open(“/var/tmp/rejection_list.txt”),O_CREAT | O_RDWR\
S|IRWXU | S|IRWXG | S|IRWXO);
如果(ftmp!=NULL)
{
loff_t ppos=0;
文件大小=vfs\u llseek(ftmp,0,SEEK\u END);
usb_内容=kvmalloc(文件大小,GFP原子);
如果(usb_内容==NULL)
{
printk(KERN_ERR“为USB缓冲区分配内存时出错!”);
}
vfs_llseek(ftmp,0,SEEK_SET);
内核读取(ftmp、usb内容、文件大小和ppos);
usb_内容[文件大小]='\0';
无字=((文件大小*2)/10);
word_mat=kvmalloc(无单词,GFP_原子);
计数=0;
while((pch=strep(&usb_-content,“\n”))!=NULL)
{
单词大小=strlen(pch);
word_mat[count]=kvmalloc(word_size+1,GFP_原子);
strcpy(字数[count],pch);
计数++;
}
kvfree(usb_内容);
ppos=0;
如果(fp==NULL)
{
printk(KERN_ERR“无法打开内核USB文件!\n”);
}  
其他的
{
usb_内容=kvmalloc(2000年,GFP_原子);
如果(usb_内容==NULL)
{
printk(KERN_ERR“为USB缓冲区分配内存时出错!”);
}
vfs_llseek(fp,0,SEEK_SET);
内核读取(fp、usb内容、2000和ppos);
ppos=0;
while((pch=strep(&usb_-content,“\n”))!=NULL)
{
if(strstr(pch,“供应商”)!=NULL)
{
检查=0;
供应商标识[0]=pch[11];
供应商标识[1]=pch[12];
供应商标识[2]=pch[13];
供应商标识[3]=pch[14];
供应商id[4]='\0';
产品标识[0]=pch[23];
产品标识[1]=pch[24];
产品标识[2]=pch[25];
产品标识[3]=pch[26];
产品标识[4]='\0';
printk(内核信息“检查%s%s\n”、供应商id、产品id);
用于(计数=0;计数<无单词;计数=计数+2)
{
如果(供应商id[0]==文字材料[count][0]&供应商id[1]==文字材料[count][1]&供应商id[2]==文字材料[count][2]&供应商id[3]==文字材料[count][3]&产品id[0]==文字材料[count+1][0]&产品id[1]==文字材料[count 1][1]&产品id[2]==文字材料[count 1][2]&产品id][3]==文字材料[count 1][3]:
{
printk(内核信息“已批准用于%s%s\n”、供应商id、产品id);
检查=1;
打破
}
}
如果(检查==0)
{
printk(KERN_INFO“用于阻止%s%s的调用脚本…。\n”,供应商id,产品id);
to_write=kvmalloc(10,GFP_原子);
strncpy(待写入,供应商id,4);
strcat(写“”);
strncat(待写入,产品id,4);
strcat(写“\n”);
内核写入(伪造、写入、10和ppos);
kvfree(写入);
}
}
}
kvfree(usb_内容);
用于(计数=0;计数<无单词;计数++)
{
kvfree(字数[计数]);
}
kvfree(word_mat);
}
}
否则{
printk(KERN_ERR“Error!无法打开文件\n”);
}
filp_关闭(ftmp,空);
filp_关闭(fp,空);
filp_关闭(假,空);
}
静态无效\退出虚拟\退出(无效)
{
printk(KERN_INFO“卸载成功!”);
}
模块_init(虚拟_init);
模块出口(虚拟出口);
每次插入USB时,该模块由服务加载。我的问题是,在几个insmod rmmod操作之后,Linux冻结,我必须重新启动机器


另外,我以前曾尝试将所有变量声明为全局变量,但没有成功。

太多代码。。。你有没有尝试过简化它以发现问题?这被称为“调试”,我们希望询问者对创建进行基本调试。当您的模块
segfaults
失败时,随后的
rmmod
失败,系统挂起。您别无选择,只能尝试查找错误的根本原因。到目前为止你试过什么?。到目前为止,我已经尝试移动本地范围上的所有变量并删除不必要的操作。但这要视情况而定,有时在内核恐慌之前需要5个左右的insmod,否则只有2个。我的假设是存在内存泄漏,但似乎没有任何未释放的内容。