[MPlayer-matrox] r264 - mga_vid/trunk/mga_vid.c

attila subversion at mplayerhq.hu
Fri May 23 20:58:38 CEST 2008


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 file\n",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 buffer\n");
+		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 space\n");
+		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;
 }
 



More information about the MPlayer-matrox mailing list