Skip to contentSkip to conversation

Strange about copy_from_user API

DISCUSSION Qiuyu Zhang 1 participant 1 message Jul 9, 2004

lore
Share & tools
lore
#0 lore raw

Thx,

I describe what I do and my code simply.

I am try to do a module driver. So far I can insmod the module and config ip address etc. There is a existed queue in user space which is alloc by a user application. When I send a ping packet by the device I create, it will call dev->hard_start_xmit. In this function I need put the data into user space queue. Similarly, I also need read the data from queue when user put a data into queue. That's what I want to do.

Code description:
struct Queue

{
      int read;
      int write;
      int length;
      char *data;
};

At first, the module driver is inserted into kernel by calling insmod. And then user space application call a function to tell (register) module driver what is the pointer of the queue. The function be called by user application is as following

int regQ2kernel( char *devname , char *queue){
     struct ifrequ ifr;
      int sockfd;
      if((sockfd =  socket(AF_INET,SOCK_DGRAM,0))<0){
             ....
     } 
      strncpy(ifr.ifr_name, devname, sizeof(ifr.ifr_name));
      ifr.ifr_data = pQueue;
      if((ret= ioctl(sockfd, SIOREGIFFLAGS, (int)&ifr))<0}{

      }

      close(sockfd);
       return 1;
}

When the user application call the above function, the module driver in kernel can get the pointer of queue. And then I just store the pointer of queue.

After I configure IP address and startup the module driver, I send a ping packet to the device. The packet arrived to the device correctly, then I need copy the data to queue in user space.

Here, I have questions.

1) when I got the pointer of queue, can I access the item in the struct directly such as read, write etc? I try to do it. Sometimes it will crash OS.

2) Due to the above reason, I want to copy the struct of queue to kernel space and then access the item of the Queue. But I cannot get the correct content .

static int usbModem_dev_xmit(struct sk_buff *skb, struct net_device *dev){

     struct Queue *p =  (struct Queue *)dev->priv;
     struct Queue kQueue;
     copy_from_user(&kQueue, *p, sizeof(struct Queue));
      ......
     // here , the data of kQueue is not the data in Queue in user

space, I don't know why.

}

The strange thing is that when I use copy_from_user at ioctl function, everything is correct. How could figure it out?

So far the quesiton is clear ?

Thanks again.

Quoted 29 lines · Richard B. Johnson
Quoted 11 lines · Qiuyu Zhang

Hi all,
I am working on writing a module driver.

I am trying to use API copy_from_user to copy a bunch of memory from user space to kernel space. I write a ioctl function to register the pointer of the memory to kernel. And in the ioctl function I can use copy_from_user to get the correct data, but the strange thing is that when I use copy_from_user in other kernel function such as dev_hard_xmit function , I cannot
get the correct result. I don't konw what the reason is . Thx. -

Without looking at the code it's hard to figure out what you may be doing. However, copy_from_user() and copy_to_user() may not ever be executed with a spin-lock held. Generally, if you need to put user data into kernel "things", you need to buffer it, i.e., copy_from_user() into a kmalloc(ed) buffer, then work with it in kernel space.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.26 on an i686 machine (5570.56 BogoMips).
Note 96.31% of all statistics are fiction.