0

As I am not using copy_to_user and copy_from _user functions, the following kernel module should give kernel a panic message. But I am getting proper output. Architecture is x86 on ubuntu 14.04 LTE.

$ sudo mknod /dev/mem_char c 61 0
$ sudo chmod 777 /dev/char
$ echo 123asa >/dev/mem_char

dmesg output:

[  494.821648] mem_driver: module license 'unspecified' taints kernel.
[  494.821653] Disabling lock debugging due to kernel taint
[  494.821678] mem_driver: module verification failed: signature and/or  required key missing - tainting kernel
[  573.581104] data from user : 123asa
[  573.581104]  tushar!!
[  573.581104] eload
[  573.581104] t
[  573.581104] /bin/grub-script-check
[  573.581104] bkdf2
[  573.581104] e

Module code:

#include<linux/module.h>
#include<linux/fs.h>
#include<linux/init.h>

ssize_t mem_read (struct file *, char __user *,size_t, loff_t *);
ssize_t mem_write (struct file *, const char __user *, size_t, loff_t *);
int mem_open (struct inode *, struct file *);
int mem_release (struct inode *, struct file *);

int major_no=61;    //if major no=0 then dynamic mean kernel alocate it 

struct file_operations fops={
    .open=mem_open,
    .read=mem_read,
    .write=mem_write,
    .release=mem_release,
};

ssize_t mem_read (struct file *fp, char __user *buff,size_t len,  loff_t *off)
{
    printk("buffer :%s \n",buff);
    return 0;
}
ssize_t mem_write (struct file *fp, const char __user *buff, size_t len, loff_t *off)
{
    //  char kbuff;
    //  printk("Function name : %s \n",__func__);
    printk("data from user : %s\n",buff);
    //    kmalloc();      
    return len;
}
int mem_open (struct inode *ip, struct file *fp)
{
    // printk("Function name : %s \n",__func__);
    return 0;
}
int mem_release (struct inode *ip, struct file *fp)
{
    // printk("Function name : %s \n",__func__);
    return 0;
}
static int mem_init(void)
{
    int ret;
    //        printk("mem_init\n");
    ret =register_chrdev(major_no,"mem_driver",&fops);
    if(ret<0)
    {
        //       printk("registetation fails with major no : %d",major_no);
        return ret; 
    }
    // printk("mem_driver register with major no %d\n",major_no);      
    return 0;
}
static void mem_exit(void)
{
    //  printk("exit\n");
    unregister_chrdev(major_no,"mem_driver");   
}
module_init(mem_init);
module_exit(mem_exit);
3
  • why must it, please show your working. C + kernel is definition of "undefined behaviour". Linux runs on computers without MMU, you have not even told us what architecture you are running on.
    – sourcejedi
    Sep 3, 2016 at 20:33
  • Also this question sounds like it should be moved to stackoverflow (programming). With the possible exception if you're trying to learn something specific about Linux architecture - e.g. what it means for security - and you're not trying to learning about Linux programming as such.
    – sourcejedi
    Sep 3, 2016 at 20:37
  • @sourcejedi : hi updated my code details please help me on this.module is registered with major no 61 and minor no 0 and have entry in /proc/devices Sep 4, 2016 at 4:21

1 Answer 1

1

There is no reason for a kernel panic, since in your test the module printed data from an accessible address until a null was found (you should have used the length of the data to limit the printk).

However, you might try the same test another time and it would panic because your program (echo) has been paged out of memory! In such a case, accessing the data causes a page fault, which is the normal way to have the data paged back into memory, but because you have not used copy_from_user(), the kernel has to assume the page fault is a programming error and will panic.

This is the primary value of using copy_from_user() on many architectures: it marks this bit of code as potentially producing "legal" page faults, which should be handled normally (as when they occur in user space) as a request to page back in data. Otherwise it is just a sort of optimised memcpy().

The function also does some preliminary checks on the validity of the address. See this explanation.


The echo 123asa is conceptually implemented in user space by code like

char data[1024];
memcpy(data,"123asa\n",7);
write(1,data,7);

where the string copied into data is 7 characters long, and has no reason to end with an 8th null character \0. So data[7] onwards will contain random uninitialised data.

When in your module you do printk("%s\n",buff), the format %s will print characters from buff until it reaches a null character, which could be a long way away. You should instead restrict the length to that provided as in

printk("%*s\n",len,buff);
6
  • will u explain more "untill a null was found" mean? please Sep 5, 2016 at 5:29
  • I updated my answer.
    – meuh
    Sep 5, 2016 at 6:01
  • still no panic message i replaced printk("data from user : %s \n",buff) to printk("data from user : %*s \n",len,buff) output :data from user : (null)* Sep 5, 2016 at 6:15
  • You will not get a panic unless your program is swapped out of memory at the time of the printk, which is pretty unlikely.
    – meuh
    Sep 5, 2016 at 7:22
  • What you mean swapped out of memory ? And how I can get panic in the above same code ? Because with same concept (the one I written code)it is excepted that panic occur Sep 5, 2016 at 7:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .