List Info

Thread: r264 - mga_vid/trunk/mga_vid.c




r264 - mga_vid/trunk/mga_vid.c
user name
2008-05-23 13:58:38
Author: attila
Date: Fri May 23 20:58:38 2008
New Revision: 264

Log:
fix possible segfault caused by directly accessing user
space memory


Modified:
   mga_vid/trunk/mga_vid.c

Modified: mga_vid/trunk/mga_vid.c
============================================================
==================
--- mga_vid/trunk/mga_vid.c	(original)
+++ mga_vid/trunk/mga_vid.c	Fri May 23 20:58:38 2008
 -868,7
+868,7  static ssize_t mga_vid_read(struct file 
 	if (*ppos >= card->param_buff_len)
 		return 0;
 	size = min(count, card->param_buff_len - (size_t)
(*ppos));
-	memcpy(buf, card->param_buff, size);
+	copy_to_user(buf, card->param_buff, size);
 	*ppos += size;
 	return size;
 }
 -876,33
+876,64  static ssize_t mga_vid_read(struct file 
 static ssize_t mga_vid_write(struct file *file, const char
*buf, size_t count, loff_t * ppos)
 {
 	mga_card_t *card = (mga_card_t *) file->private_data;
+	char * buffer;
 
-	if (memcmp(buf, PARAM_BRIGHTNESS, min(count,
strlen(PARAM_BRIGHTNESS))) == 0) {
+	if(count >= PAGE_SIZE)
+	{
+		// only one parameter is handled at a time,
+		// so writing more than one page does not
+		// make sense anyways
+                printk(KERN_ERR "mga_vid: writing more
than %lu bytes to the device filen",PAGE_SIZE);
+		return -EFBIG;
+	}
+
+	// allocate memory and copy data into our own buffer
+	buffer = kmalloc(count, GFP_KERNEL);
+	
+	if(!buffer)
+	{
+                printk(KERN_ERR "mga_vid: couln't
allocate buffern");
+		return -EIO;
+	}
+
+	memset(buffer, 0, count);
+	// copy_from_user returns the amount of data _still_ to be
copied
+	if(copy_from_user(buffer, buf, count))
+	{
+		// something strange happend, bail out
+                printk(KERN_ERR "mga_vid: couldn't
copy data from user spacen");
+		kfree(buffer);
+		return -EIO;
+	}
+
+	if (memcmp(buffer, PARAM_BRIGHTNESS, min(count,
strlen(PARAM_BRIGHTNESS))) == 0) {
 		short brightness;
-		brightness =
simple_strtol(&buf[strlen(PARAM_BRIGHTNESS)], NULL,
10);
+		brightness =
simple_strtol(&buffer[strlen(PARAM_BRIGHTNESS)], NULL,
10);
 		if (brightness > 127 || brightness < -128) {
 			brightness = 0;
 		}
 //              printk(KERN_DEBUG "mga_vid: brightness
modified ( %d ) n",brightness);
 		card->brightness = brightness;
 	} else
-	    if (memcmp(buf, PARAM_CONTRAST, min(count,
strlen(PARAM_CONTRAST))) == 0) {
+	    if (memcmp(buffer, PARAM_CONTRAST, min(count,
strlen(PARAM_CONTRAST))) == 0) {
 		short contrast;
-		contrast =
simple_strtol(&buf[strlen(PARAM_CONTRAST)], NULL, 10);
+		contrast =
simple_strtol(&buffer[strlen(PARAM_CONTRAST)], NULL,
10);
 		if (contrast > 127 || contrast < -128) {
 			contrast = 0;
 		}
 //              printk(KERN_DEBUG "mga_vid: contrast
modified ( %d ) n",contrast);
 		card->contrast = contrast;
 	} else
-	 if (memcmp(buf, PARAM_BLACKIE, min(count,
strlen(PARAM_BLACKIE))) == 0) {
+	 if (memcmp(buffer, PARAM_BLACKIE, min(count,
strlen(PARAM_BLACKIE))) == 0) {
 		short blackie;
-		blackie = simple_strtol(&buf[strlen(PARAM_BLACKIE)],
NULL, 10);
+		blackie =
simple_strtol(&buffer[strlen(PARAM_BLACKIE)], NULL,
10);
 //              printk(KERN_DEBUG "mga_vid: shadow
mode: ( %d ) n",blackie);
 		card->regs.blackie = (blackie > 0) ? 1 : 0;
 	} else
 		count = -EIO;
 	// TODO: reset settings
+	
+	kfree(buffer);
 	return count;
 }
 
_______________________________________________
MPlayer-matrox mailing list
MPlayer-matroxmplayerhq.hu
https://lists.mplayerhq.hu/mailman/listinfo/mplayer-ma
trox

[1]

about | contact  Other archives ( Real Estate discussion Medical topics )