<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">
From: Alan Cox &lt;alan@redhat.com&gt;

Like a few other drivers the vc driver is doing unlocked careless
references to file offsets.  Its got kind of 2.2 locking that hasnt been
updated in the lseek function so someone at least tried.  

Fortunately we have a real lock for this and can just make lseek use that
too.

The 'assume 64bit load is atomic' bug seems to be very widely spread

Signed-off-by: Andrew Morton &lt;akpm@osdl.org&gt;
---

 25-akpm/drivers/char/vc_screen.c |   31 ++++++++++++++++++-------------
 1 files changed, 18 insertions(+), 13 deletions(-)

diff -puN drivers/char/vc_screen.c~vc-locking drivers/char/vc_screen.c
--- 25/drivers/char/vc_screen.c~vc-locking	Fri Jun 25 14:21:44 2004
+++ 25-akpm/drivers/char/vc_screen.c	Fri Jun 25 14:21:44 2004
@@ -66,15 +66,23 @@ vcs_size(struct inode *inode)
 	return size;
 }
 
+/* We share this temporary buffer with the console write code
+ * so that we can easily avoid touching user space while holding the
+ * console spinlock.
+ */
+extern char con_buf[PAGE_SIZE];
+#define CON_BUF_SIZE	PAGE_SIZE
+extern struct semaphore con_buf_sem;
+
 static loff_t vcs_lseek(struct file *file, loff_t offset, int orig)
 {
 	int size;
 
-	lock_kernel();
+	down(&amp;con_buf_sem);
 	size = vcs_size(file-&gt;f_dentry-&gt;d_inode);
 	switch (orig) {
 		default:
-			unlock_kernel();
+			up(&amp;con_buf_sem);
 			return -EINVAL;
 		case 2:
 			offset += size;
@@ -85,28 +93,21 @@ static loff_t vcs_lseek(struct file *fil
 			break;
 	}
 	if (offset &lt; 0 || offset &gt; size) {
-		unlock_kernel();
+		up(&amp;con_buf_sem);
 		return -EINVAL;
 	}
 	file-&gt;f_pos = offset;
-	unlock_kernel();
+	up(&amp;con_buf_sem);
 	return file-&gt;f_pos;
 }
 
-/* We share this temporary buffer with the console write code
- * so that we can easily avoid touching user space while holding the
- * console spinlock.
- */
-extern char con_buf[PAGE_SIZE];
-#define CON_BUF_SIZE	PAGE_SIZE
-extern struct semaphore con_buf_sem;
 
 static ssize_t
 vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 {
 	struct inode *inode = file-&gt;f_dentry-&gt;d_inode;
 	unsigned int currcons = iminor(inode);
-	long pos = *ppos;
+	long pos;
 	long viewed, attr, read;
 	int col, maxcol;
 	unsigned short *org = NULL;
@@ -114,6 +115,8 @@ vcs_read(struct file *file, char __user 
 
 	down(&amp;con_buf_sem);
 
+	pos = *ppos;
+
 	/* Select the proper current console and verify
 	 * sanity of the situation under the console lock.
 	 */
@@ -275,7 +278,7 @@ vcs_write(struct file *file, const char 
 {
 	struct inode *inode = file-&gt;f_dentry-&gt;d_inode;
 	unsigned int currcons = iminor(inode);
-	long pos = *ppos;
+	long pos;
 	long viewed, attr, size, written;
 	char *con_buf0;
 	int col, maxcol;
@@ -284,6 +287,8 @@ vcs_write(struct file *file, const char 
 
 	down(&amp;con_buf_sem);
 
+	pos = *ppos;
+
 	/* Select the proper current console and verify
 	 * sanity of the situation under the console lock.
 	 */
_
</pre></body></html>