linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Using map_user_kiobuf()
@ 2000-11-30 13:07 John Meikle
  2000-12-04 21:53 ` Stephen C. Tweedie
  0 siblings, 1 reply; 6+ messages in thread
From: John Meikle @ 2000-11-30 13:07 UTC (permalink / raw)
  To: linux-kernel

I have been experimenting with a module that returns data to either a user
space programme or another module.  A memory area is passed in, and the data
is written to it.  Because the memory may be allocated either by a module or
a user programme, a kiobuf seemed a good way of representing it.  A layer
converts user memory to a kiobuf using map_user_kiobuf().

To test if it would work, I wrote a short test that passed 1,000,000 bytes
of memory to a module that wrote a pattern into the memory.  The pattern was
checked in the user programme to ensure it worked.

The test does work in so much as the pattern checks okay, but kernel memory
appears to be corrupted.  Trying to run gcc dies with a segmentation
violation, and the output of "ps" has the command names replaced with time
strings ("00:00:00" or "00:00:05").  X won't shut down properly, and
Ctrl-Alt-Del fails to reboot.

The code in the module (without validation and error checking) is:

int test_kiobuf(char* buf)
{
    struct kiobuf *iobuf;
    int i;

    alloc_kiovec(1, &iobuf);
    map_user_kiobuf(WRITE, iobuf, buf, TEST_SIZE);

    for (i = 0 ; i < iobuf->length; i++)
    {
        int off = iobuf->offset + i;
        int page = off / 4096;
        unsigned char* buf = page_address(iobuf->maplist[page]);
        buf[off % 4096] = (i & 0xFF);
    }

    unmap_kiobuf(iobuf);
    free_kiovec(1, &iobuf);
    return 0;
}

The user space programme is:

#include <stdio.h>
#include <fcntl.h>
#include <sys/ioctl.h>

#define TEST_SIZE 1000000

int main(int argc, char *argv[])
{
    int fh;
    int i;
    unsigned char * buf;

    buf = (unsigned char *)malloc(TEST_SIZE);

    fh = open("/tmp/test", O_CREAT);

    if (ioctl(fh, 99, buf) != 0)
        perror("ioctl failed");
    else
    {
        for (i = 0; i < TEST_SIZE; i++)
        {
            if (buf[i] != (i & 0xFF))
                printf("%8.8X: %2.2X %2.2X\n", i, i & 0xFF, buf[i]);
        }
    }

    close(fh);
    free(buf);

    return 0;
}

If I change the user programme to initialise the memory to zero everything
works okay.  It also works if I use copy_to_user() to write a single byte in
each page at the beginning of the module code.

This is using kernel 2.4.0-test9.

Does anyone know what I am doing wrong?


John Meikle.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Using map_user_kiobuf()
  2000-11-30 13:07 Using map_user_kiobuf() John Meikle
@ 2000-12-04 21:53 ` Stephen C. Tweedie
  2000-12-05 10:15   ` John Meikle
  0 siblings, 1 reply; 6+ messages in thread
From: Stephen C. Tweedie @ 2000-12-04 21:53 UTC (permalink / raw)
  To: John Meikle; +Cc: linux-kernel, Stephen Tweedie

Hi,

On Thu, Nov 30, 2000 at 01:07:37PM -0000, John Meikle wrote:
> I have been experimenting with a module that returns data to either a user
> space programme or another module.  A memory area is passed in, and the data
> is written to it.  Because the memory may be allocated either by a module or
> a user programme, a kiobuf seemed a good way of representing it.  A layer
> converts user memory to a kiobuf using map_user_kiobuf().

There are a number of fixes pending for 2.4, and released for 2.2, but
nothing that would explain the sort of kernel corruption you are
reporting --- it sounds as if you are overrunning the end of the
kiobuf, but it's hard to know without seeing the real code.

> The code in the module (without validation and error checking) is:
> 
> int test_kiobuf(char* buf)
> {
>     struct kiobuf *iobuf;
>     int i;
> 
>     alloc_kiovec(1, &iobuf);
>     map_user_kiobuf(WRITE, iobuf, buf, TEST_SIZE);

Careful, you can't touch the buffer for a WRITE map.  The READ/WRITE
flag is from the point of view of the user, and user write() syscalls
don't touch the data in memory!  If you want to modify the user
buffer, you need to use READ instead.

Cheers,
 Stephen
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: Using map_user_kiobuf()
  2000-12-04 21:53 ` Stephen C. Tweedie
@ 2000-12-05 10:15   ` John Meikle
  2000-12-05 14:08     ` Chris Wedgwood
  0 siblings, 1 reply; 6+ messages in thread
From: John Meikle @ 2000-12-05 10:15 UTC (permalink / raw)
  To: Stephen C. Tweedie; +Cc: Linux Kernel Mail List

Steven,

Changing the WRITE to READ does solve the problem, thank you.

I am still confused about why the code failed the way it did.  The module
managed to write to the full 1,000,000, and the user programme could read it
and verify it was correct.  Just nothing else worked after that!

Am I the only one who finds the READ/WRITE option back to front?


Regards,

John.

-----Original Message-----
From: linux-kernel-owner@vger.kernel.org
[mailto:linux-kernel-owner@vger.kernel.org]On Behalf Of Stephen C.
Tweedie
Sent: 04 December 2000 21:54
To: John Meikle
Cc: linux-kernel@vger.kernel.org; Stephen Tweedie
Subject: Re: Using map_user_kiobuf()


Hi,

On Thu, Nov 30, 2000 at 01:07:37PM -0000, John Meikle wrote:
> I have been experimenting with a module that returns data to either a user
> space programme or another module.  A memory area is passed in, and the
data
> is written to it.  Because the memory may be allocated either by a module
or
> a user programme, a kiobuf seemed a good way of representing it.  A layer
> converts user memory to a kiobuf using map_user_kiobuf().

There are a number of fixes pending for 2.4, and released for 2.2, but
nothing that would explain the sort of kernel corruption you are
reporting --- it sounds as if you are overrunning the end of the
kiobuf, but it's hard to know without seeing the real code.

> The code in the module (without validation and error checking) is:
>
> int test_kiobuf(char* buf)
> {
>     struct kiobuf *iobuf;
>     int i;
>
>     alloc_kiovec(1, &iobuf);
>     map_user_kiobuf(WRITE, iobuf, buf, TEST_SIZE);

Careful, you can't touch the buffer for a WRITE map.  The READ/WRITE
flag is from the point of view of the user, and user write() syscalls
don't touch the data in memory!  If you want to modify the user
buffer, you need to use READ instead.

Cheers,
 Stephen
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Using map_user_kiobuf()
  2000-12-05 10:15   ` John Meikle
@ 2000-12-05 14:08     ` Chris Wedgwood
  2000-12-05 20:07       ` Albert D. Cahalan
  0 siblings, 1 reply; 6+ messages in thread
From: Chris Wedgwood @ 2000-12-05 14:08 UTC (permalink / raw)
  To: John Meikle; +Cc: Stephen C. Tweedie, Linux Kernel Mail List

On Tue, Dec 05, 2000 at 10:15:55AM -0000, John Meikle wrote:

    Changing the WRITE to READ does solve the problem, thank you.
    
    I am still confused about why the code failed the way it did.  The module
    managed to write to the full 1,000,000, and the user programme could read it
    and verify it was correct.  Just nothing else worked after that!
    
    Am I the only one who finds the READ/WRITE option back to front?
    
No, I was just thinking it should be change to USER_READ, USER_WRITE
or something a little more obvious. 

Stephen?



  --cw
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Using map_user_kiobuf()
  2000-12-05 14:08     ` Chris Wedgwood
@ 2000-12-05 20:07       ` Albert D. Cahalan
  2000-12-05 22:50         ` Chris Wedgwood
  0 siblings, 1 reply; 6+ messages in thread
From: Albert D. Cahalan @ 2000-12-05 20:07 UTC (permalink / raw)
  To: Chris Wedgwood; +Cc: John Meikle, Stephen C. Tweedie, Linux Kernel Mail List

>     Am I the only one who finds the READ/WRITE option back to front?
>     
> No, I was just thinking it should be change to USER_READ, USER_WRITE
> or something a little more obvious. 

Eh, read data from userspace and write data to userspace? Oops.

FROM_USER
TO_USER

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Using map_user_kiobuf()
  2000-12-05 20:07       ` Albert D. Cahalan
@ 2000-12-05 22:50         ` Chris Wedgwood
  0 siblings, 0 replies; 6+ messages in thread
From: Chris Wedgwood @ 2000-12-05 22:50 UTC (permalink / raw)
  To: Albert D. Cahalan; +Cc: John Meikle, Stephen C. Tweedie, Linux Kernel Mail List


Yes, this is better



   --cw


On Tue, Dec 05, 2000 at 03:07:26PM -0500, Albert D. Cahalan wrote:
    >     Am I the only one who finds the READ/WRITE option back to front?
    >     
    > No, I was just thinking it should be change to USER_READ, USER_WRITE
    > or something a little more obvious. 
    
    Eh, read data from userspace and write data to userspace? Oops.
    
    FROM_USER
    TO_USER
    
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2000-12-05 23:21 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-11-30 13:07 Using map_user_kiobuf() John Meikle
2000-12-04 21:53 ` Stephen C. Tweedie
2000-12-05 10:15   ` John Meikle
2000-12-05 14:08     ` Chris Wedgwood
2000-12-05 20:07       ` Albert D. Cahalan
2000-12-05 22:50         ` Chris Wedgwood

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).