Quantcast
Channel: Active questions tagged kernel - Stack Overflow
Viewing all articles
Browse latest Browse all 6501

Linux freezes after loading and unloading a kernel module

$
0
0

I am attempting to do a kernel module that is meant to check which USB devices are currently connected, and compare them to a list of allowed USB devices. I've written the following code:

#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);

The module is loaded by a service each time an USB is inserted. My problem is that after a couple of insmod-rmmod operations Linux freezes and I must restart the machine.

P.S. I have previously tried to declare all variables global, but has not worked.


Viewing all articles
Browse latest Browse all 6501

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>