(repost) bugfix [patch] for drivers/char/mem.c

Steven Hand (Steven.Hand@cl.cam.ac.uk)
Thu, 27 May 1999 10:56:11 +0100


This is a multipart MIME message.

--==_Exmh_-7167040260
Content-Type: text/plain; charset=us-ascii

I've sent this before, but the bug still seems to be around in
2.3.4, so I'm trying again. Note that there are a number of other
serious lacks in the implementation of /dev/mem and /dev/kmem, most
particularly with regard to the fact that read()'ing and mmap()'ing
the files are not logically equivalent (in terms of the data one
receives, the size, the implicit offset, etc, etc).

Anyway.

When read()'ing from /dev/kmem, the file position is incorrectly updated, which
bites you if you perform >1 read on the file before close()'ing it. AFAICS, the
bug has been around since at least 2.1.127.

The tiny patch attached below is against 2.2.7(*) and should fix the problem.
Notice that the first part of the patch is simply an optimisation to avoid
calling vread() and iterating along every vmalloc'd area in the case that
copy_to_user() has already done its stuff. The line involving the update
of *ppos is the important one.

S.

(* I've no 2.3.4 kernel around, and I think the below patch is simple
enough to be applied by inspection. )

--==_Exmh_-7167040260
Content-Type: text/plain ; name="kmem_patch"; charset=us-ascii
Content-Description: kmem_patch
Content-Disposition: attachment; filename="kmem_patch"

--- v2.2.7/linux/drivers/char/mem.c Mon May 10 22:29:38 1999
+++ linux/drivers/char/mem.c Mon May 10 22:27:59 1999
@@ -247,11 +247,14 @@
count -= read;
}

- virtr = vread(buf, (char *)p, count);
- if (virtr < 0)
- return virtr;
- *ppos += p + virtr;
- return virtr + read;
+ if(count) {
+ if((virtr = vread(buf, (char *)p, count)) < 0)
+ return virtr;
+ read += virtr;
+ }
+
+ *ppos += read;
+ return read;
}

/*

--==_Exmh_-7167040260--

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