patch-2.1.43 linux/drivers/char/mem.c

Next file: linux/drivers/char/misc.c
Previous file: linux/drivers/char/lp_m68k.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.42/linux/drivers/char/mem.c linux/drivers/char/mem.c
@@ -35,6 +35,33 @@
 void pcwatchdog_init(void);
 #endif
 
+static long do_write_mem(struct file * file,
+	void *p, unsigned long realp, 					 
+	const char * buf, unsigned long count)
+{
+	unsigned long written;
+
+	written = 0;
+#if defined(__sparc__) || defined(__mc68000__)
+	/* we don't have page 0 mapped on sparc and m68k.. */
+	if (realp < PAGE_SIZE) {
+		unsigned long sz = PAGE_SIZE-realp;
+		if (sz > count) sz = count; 
+		/* Hmm. Do something? */
+		buf+=sz;
+		p+=sz;
+		count-=sz;
+		written+=sz;
+	}
+#endif
+	if (copy_from_user(p, buf, count) < 0) 
+		return -EFAULT;
+	written += count;
+	file->f_pos += written;
+	return count;
+}
+
+
 /*
  * This funcion reads the *physical* memory. The f_pos points directly to the 
  * memory location. 
@@ -45,7 +72,7 @@
 	unsigned long p = file->f_pos;
 	unsigned long end_mem;
 	unsigned long read;
-
+	
 	end_mem = __pa(high_memory);
 	if (p >= end_mem)
 		return 0;
@@ -54,15 +81,22 @@
 	read = 0;
 #if defined(__sparc__) || defined(__mc68000__)
 	/* we don't have page 0 mapped on sparc and m68k.. */
-	while (p < PAGE_SIZE && count > 0) {
-		put_user(0,buf);
-		buf++;
-		p++;
-		count--;
-		read++;
+	if (p < PAGE_SIZE) {
+		unsigned long sz = PAGE_SIZE-p;
+		if (sz > count) 
+			sz = count; 
+		if (sz > 0) {
+			if (clear_user(buf, sz))
+				return -EFAULT;
+			buf += sz; 
+			p += sz; 
+			count -= sz; 
+			read += sz; 
+		}
 	}
 #endif
-	copy_to_user(buf, __va(p), count);
+	if (copy_to_user(buf, __va(p), count) < 0)
+		return -EFAULT;
 	read += count;
 	file->f_pos += read;
 	return read;
@@ -73,35 +107,19 @@
 {
 	unsigned long p = file->f_pos;
 	unsigned long end_mem;
-	unsigned long written;
 
 	end_mem = __pa(high_memory);
 	if (p >= end_mem)
 		return 0;
 	if (count > end_mem - p)
 		count = end_mem - p;
-	written = 0;
-#if defined(__sparc__) || defined(__mc68000__)
-	/* we don't have page 0 mapped on sparc and m68k.. */
-	while (p < PAGE_SIZE && count > 0) {
-		/* Hmm. Do something? */
-		buf++;
-		p++;
-		count--;
-		written++;
-	}
-#endif
-	copy_from_user(__va(p), buf, count);
-	written += count;
-	file->f_pos += written;
-	return count;
+	return do_write_mem(file,__va(p),p,buf,count);
 }
 
 static int mmap_mem(struct inode * inode, struct file * file, struct vm_area_struct * vma)
 {
 	unsigned long offset = vma->vm_offset;
 
-	
 	if (offset & ~PAGE_MASK)
 		return -ENXIO;
 #if defined(__i386__)
@@ -117,7 +135,7 @@
 	if (remap_page_range(vma->vm_start, offset, vma->vm_end - vma->vm_start, vma->vm_page_prot))
 		return -EAGAIN;
 	vma->vm_inode = inode;
-	inode->i_count++;
+	atomic_inc(&inode->i_count);
 	return 0;
 }
 
@@ -166,27 +184,12 @@
 	const char * buf, unsigned long count)
 {
 	unsigned long p = file->f_pos;
-	unsigned long written;
 
 	if (p >= (unsigned long) high_memory)
 		return 0;
 	if (count > (unsigned long) high_memory - p)
 		count = (unsigned long) high_memory - p;
-	written = 0;
-#if defined(__sparc__) || defined(__mc68000__)
-	/* we don't have page 0 mapped on sparc and m68k.. */
-	while (p < PAGE_SIZE && count > 0) {
-		/* Hmm. Do something? */
-		buf++;
-		p++;
-		count--;
-		written++;
-	}
-#endif
-	copy_from_user((char *) p, buf, count);
-	written += count;
-	file->f_pos += written;
-	return count;
+	return do_write_mem(file,(void*)p,p,buf,count);
 }
 
 static long read_port(struct inode * inode, struct file * file,
@@ -195,8 +198,11 @@
 	unsigned int i = file->f_pos;
 	char * tmp = buf;
 
+	if (verify_area(VERIFY_WRITE,buf,count))
+		return -EFAULT; 
 	while (count-- > 0 && i < 65536) {
-		put_user(inb(i),tmp);
+		if (__put_user(inb(i),tmp) < 0) 
+			return -EFAULT;  
 		i++;
 		tmp++;
 	}
@@ -210,9 +216,12 @@
 	unsigned int i = file->f_pos;
 	const char * tmp = buf;
 
+	if (verify_area(VERIFY_READ,buf,count))
+		return -EFAULT;
 	while (count-- > 0 && i < 65536) {
 		char c;
-		get_user(c, tmp);
+		if (__get_user(c, tmp)) 
+			return -EFAULT; 
 		outb(c,i);
 		i++;
 		tmp++;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov