ChangeSet 1.1243.50.3, 2003/06/06 15:02:42-07:00, joe@wavicle.org

[PATCH] USB: vicam.c patch

I noticed a version of vicam.c a few revisions ago had all the /proc fs
writing removed because I was incorrectly using potentially tainted user
space pointers.  Here's a patch which I think fixes the pointer issue and
restores the /proc fs interface to vicam.  If this fix is still
problematic, please let me know and I'll fix whatever comes up.


 drivers/usb/media/vicam.c |   57 ++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 53 insertions(+), 4 deletions(-)


diff -Nru a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c
--- a/drivers/usb/media/vicam.c	Tue Jun 10 17:12:06 2003
+++ b/drivers/usb/media/vicam.c	Tue Jun 10 17:12:06 2003
@@ -1101,6 +1101,52 @@
 				((struct vicam_camera *)data)->gain);
 }
 
+static int
+vicam_write_proc_shutter(struct file *file, const char *buffer,
+			 unsigned long count, void *data)
+{
+	u16 stmp;
+	char kbuf[8];
+	struct vicam_camera *cam = (struct vicam_camera *) data;
+
+	if (count > 6)
+		return -EINVAL;
+
+	if (copy_from_user(kbuf, buffer, count))
+		return -EFAULT;
+
+	stmp = (u16) simple_strtoul(kbuf, NULL, 10);
+	if (stmp < 4 || stmp > 32000)
+		return -EINVAL;
+
+	cam->shutter_speed = stmp;
+
+	return count;
+}
+
+static int
+vicam_write_proc_gain(struct file *file, const char *buffer,
+		      unsigned long count, void *data)
+{
+	u16 gtmp;
+	char kbuf[8];
+
+	struct vicam_camera *cam = (struct vicam_camera *) data;
+
+	if (count > 4)
+		return -EINVAL;
+
+	if (copy_from_user(kbuf, buffer, count))
+		return -EFAULT;
+
+	gtmp = (u16) simple_strtoul(kbuf, NULL, 10);
+	if (gtmp > 255)
+		return -EINVAL;
+	cam->gain = gtmp;
+
+	return count;
+}
+
 static void
 vicam_create_proc_root(void)
 {
@@ -1142,18 +1188,21 @@
 	if ( !cam->proc_dir )
 		return; // FIXME: We should probably return an error here
 	
-	ent =
-	    create_proc_entry("shutter", S_IFREG | S_IRUGO, cam->proc_dir);
+	ent = create_proc_entry("shutter", S_IFREG | S_IRUGO | S_IWUSR,
+				cam->proc_dir);
 	if (ent) {
 		ent->data = cam;
 		ent->read_proc = vicam_read_proc_shutter;
+		ent->write_proc = vicam_write_proc_shutter;
 		ent->size = 64;
 	}
 
-	ent = create_proc_entry("gain", S_IFREG | S_IRUGO , cam->proc_dir);
-	if ( ent ) {
+	ent = create_proc_entry("gain", S_IFREG | S_IRUGO | S_IWUSR,
+				cam->proc_dir);
+	if (ent) {
 		ent->data = cam;
 		ent->read_proc = vicam_read_proc_gain;
+		ent->write_proc = vicam_write_proc_gain;
 		ent->size = 64;
 	}
 }
