Re: copy_to_user() and copy_from_user(): confusing code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On Fri, Sep 24, 2010 at 5:41 PM, sri <bskmohan@xxxxxxxxx> wrote:
what part is not able to understand?

Here is a program I wrote
but it is dropping characters though I gave 14 bytes to kmalloc and buffer but still the program is unable to read and write as I expect it to do.
I did an strace on the program and have posted the log at the end


#include <linux/init.h>

#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_from/to_user */

MODULE_LICENSE("Dual BSD/GPL");


int bond_open(struct inode *inode, struct file *filp);
int bond_release(struct inode *inode, struct file *filp);
ssize_t bond_read(struct file *filp, char *buf, size_t count, loff_t *f_pos);
ssize_t bond_write(struct file *filp, char *buf, size_t count, loff_t *f_pos);
void bond_exit(void);
int bond_init(void);

struct file_operations bond_fops = {
  read: bond_read,
  write: bond_write,
  open: bond_open,
  release: bond_release
};

module_init(bond_init);
module_exit(bond_exit);

int bond_major = 60;

char *bond_buffer;

int bond_init(void) {
  int result;


  result = register_chrdev(bond_major, "bond", &bond_fops);
  if (result < 0) {
    printk(KERN_ALERT  "memory: cannot obtain major number %d\n", bond_major);
    return result;
  }


  bond_buffer = kmalloc(14, GFP_KERNEL); 
  if (!bond_buffer) { 
    result = -ENOMEM;
    goto fail; 
  } 
  memset(bond_buffer, 0, 14);

  printk(KERN_ALERT "Inserting bond module\n"); 
  return 0;

  fail: 
    bond_exit(); 
    return result;
}


void bond_exit(void) {

  unregister_chrdev(bond_major, "bond");


  if (bond_buffer) {
    kfree(bond_buffer);
  }

  printk( KERN_ALERT "Removing bond module\n");

}


int bond_open(struct inode *inode, struct file *filp) {


  return 0;
}


int bond_release(struct inode *inode, struct file *filp) {
 

  return 0;
}


ssize_t bond_read(struct file *filp, char *buf, 
                    size_t count, loff_t *f_pos) { 
 

  copy_to_user(buf,bond_buffer,count<14 ? count:14);


 /* if (*f_pos == 0) { 
    *f_pos+=1; 
    return 1; 
  } else { 
    return 0; 
  }*/
}

ssize_t bond_write( struct file *filp, char *buf,
                      size_t count, loff_t *f_pos) {

//  char *tmp;

  //tmp=buf+count-1;
  copy_from_user(bond_buffer,buf,count<14 ? count : 14);
  return 1;

Here is the Makefile

ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
.PHONY: build clean
build:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c
rm -rf modules.order Module.symvers
else
$(info Building with KERNELRELEASE =${KERNELRELEASE})
obj-m := bond.o

endif

and here is the strace 
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2a2f03b000
write(1, "abcde", 5)                    = 1
write(1, "bcde", 4)                     = 1
write(1, "cde", 3)                      = 1
write(1, "de", 2)                       = 1
write(1, "e", 1)                        = 1
close(1)                                = 0
munmap(0x7f2a2f03b000, 4096)            = 0
close(2)                                = 0
exit_group(0)                           = ?

so copy_from_user and copy_to_write are not doing what I expect them to do this is not clear to me.

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux