copy_to_user

Dexter Haslem dexter.haslem at gmail.com
Wed Dec 22 20:18:27 EST 2010


On 12/22/2010 5:59 PM, Hemanth Kumar wrote:
> Hi All,
>
>             I have small problem with copy_to_user in read function,below is my code,when I try to read from userspace I get segmentation fault,
> Can any please point me where I went wrong,
>
>
> #include<linux/kernel.h>
> #include<linux/module.h>
> #include<linux/init.h>
> #include<linux/types.h>
> #include<linux/proc_fs.h>
> #include<linux/fs.h>
> #include<linux/kdev_t.h>
> #include<linux/jiffies.h>
> #include<linux/cdev.h>
> #include<asm/uaccess.h>
> #include<linux/mutex.h>
>
> struct mutex timer;
> static struct cdev my_cdev;
> dev_t devn;
> int maj = 300;
> int min = 0;
> int count = 1;
> char modname[] = "mytimer";
> short x[10] = {1,2,3,4,5,6,7,8,9,10};
>
>
>
>
> ssize_t my_read(struct file *file,char *buf,size_t count,loff_t *pos){
>       unsigned long res;
>       void *k = (void *)&x;
>            void *l = (void *)&x+1;
>            void *j = (void *)&x+2;
>
>                       mutex_lock(&timer);
>                               res =    copy_to_user(buf,k,sizeof(short));
>                               res =    copy_to_user(buf,l,sizeof(short));
>                               res =    copy_to_user(buf,j,sizeof(short));
>
>                         /*    res =  copy_to_user(buf,&x+4,sizeof(short));
>                               res =    copy_to_user(buf,&x+5,sizeof(short));
>                               res =    copy_to_user(buf,&x+6,sizeof(short));
>                               res =    copy_to_user(buf,&x+7,sizeof(short));
>                               res =    copy_to_user(buf,&x+8,sizeof(short));
>                               res =    copy_to_user(buf,&x+9,sizeof(short));
>                          */
>                   mutex_unlock(&timer);
>
>     return 20;
>
> }
>
>
> static struct file_operations my_fops = {
>                   .owner = THIS_MODULE,
>                   .read = my_read,
>
> };
>
>
> static int __init my_init(void){
>          int ret;
>     devn = MKDEV(maj,min);
>
>       ret = register_chrdev_region(devn,count,modname);
>
>        cdev_init(&my_cdev,&my_fops);
>        cdev_add(&my_cdev,devn,count);
>
>        printk("<1>  Register timer maj = %d\n",maj);
>
>
>
>
>   return 0;
> }
>
>
>
> static void __exit my_exit(void){
>
>        cdev_del(&my_cdev);
>         unregister_chrdev_region(devn,count);
>          printk("<1>  Bye Bye \n");
>
> }
>
>
> module_init(my_init);
> module_exit(my_exit);
> MODULE_LICENSE("Dual BSD/GPL");
>
>
>
>
> my userspace App:
>
> #include<stdio.h>
> #include<fcntl.h>
> #include<stdlib.h>
> #include<unistd.h>
>
> int main()
> {
>           int nbytes ;
>           char n[20];
>           short a = *((short *)&n[0]);
>           short b = *((short *)&n[2]);
>           short c = *((short *)&n[4]);
>
>          int     fd = open( "/dev/mytimer", O_RDONLY );
>          if ( fd<  0 ) { perror( "/dev/mytimer" ); exit(1); }
>
> while ( 1 )
>                  {
>
>                   nbytes = read( fd, n, 40 );
>                  if ( nbytes<  0 ) break;
>
>                  printf( "\r a = %d \n ", a);
>                  printf("\r b = %d \n",b);
>                  printf("\r c = %d \n",c);
>
>                  sleep(1);
>                  fflush( stdout );
>                  }
> return 0;
> }
>
>
>
>
> Best regards,
>
>
>
>
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Hi,

At first glance, you have char n[20], but read 40 bytes in the read 
call. char is only 1 byte on x86 I believe so that might be your problem.

-- 
-Dexter Haslem



More information about the Kernelnewbies mailing list