Using copy_to_user with a buffer bigger than 4K

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

 



-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,

I'm writing a kernel module (char device) to communicate some data
(execution trace) from the kernel space to the user space.

My traces are contains in a 512K buffer allocate with vmalloc.

When I try to send them to userspace using copy_to_user, it failed.

So I try to send them in 4K part to avoid this issue. But it failed too.

I copy my code at the end of the mail if anyone have an idea

piga_buffer_user_len is the size of my buffer.
piga_buffer_user is my buffer.
buf is the char * from userspace.

On the user size, I simply do a read with a buffer of 512K (more than
enough because piga_buffer_user_len is always less than that).

Thanks in advance

PS: the code crash on the copy_to_user that reach the 4K size i.e. if I
do one with 4000b it will past but if i do a second one after of 100b it
will crash.

    while (piga_buffer_user_len) {
        if (count < piga_buffer_user_len) {
            printk(KERN_INFO "PIGA-Kernel: Size buffer %d below
requested %d\n",count,piga_buffer_user_len);
            retval = -EFAULT;
        } else {
            int offset;
            //offset = src & (PAGE_SIZE-1);
            offset=0;

            if (piga_buffer_user_len > (PAGE_SIZE-offset)) {
                char * kzbuf;
                kzbuf = kzalloc((PAGE_SIZE-offset), GFP_KERNEL);
                memcpy(kzbuf,piga_buffer_user, (PAGE_SIZE-offset));

                printk(KERN_INFO "PIGA-Kernel: (%p) Partial copy buffer
(%p:%p)
size(%ld)\n",buf,piga_buffer_user,(piga_buffer_user+PAGE_SIZE),(PAGE_SIZE-offset));
                reter = copy_to_user(buf, kzbuf, (PAGE_SIZE-offset));
                if (reter != 0) {
                    char *ctm = vmalloc(PAGE_SIZE);
                    memcpy(ctm,kzbuf,PAGE_SIZE-offset);
                    printk(KERN_INFO "PIGA-Kernel: error in copying to
userspace (%s)\n",ctm);
                    vfree(ctm);
                    retval = -EFAULT;
                    break;
                }
                kfree(kzbuf);
                piga_buffer_user_len -= (PAGE_SIZE-offset);
                piga_buffer_user += (PAGE_SIZE-offset);
                //src += (PAGE_SIZE-offset);
                buf += (PAGE_SIZE-offset);
            } else {
                char * kzbuf;
                kzbuf = kzalloc((PAGE_SIZE-offset), GFP_KERNEL);
                memcpy(kzbuf,piga_buffer_user, piga_buffer_user_len);
                printk(KERN_INFO "PIGA-Kernel: (%p) Final copy
buffer\n",buf);
                piga_buffer_user_len = 0;
                reter = copy_to_user(buf, kzbuf, piga_buffer_user_len);
                if (reter != 0) {
                    retval = -EFAULT;
                    break;
                }
                kfree(kzbuf);
                buf += piga_buffer_user_len;
            }
        }
    }
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFI/ugTrzp//Utz6jwRAiSxAJ95kk5pFl3bZAHl8s5c+TSWAHBWDgCfUjbJ
ab+RBtlbUQtY2oVGaIjf/TM=
=DVZ1
-----END PGP SIGNATURE-----

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[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