patch-2.4.23 linux-2.4.23/drivers/cdrom/cdrom.c

Next file: linux-2.4.23/drivers/char/Config.in
Previous file: linux-2.4.23/drivers/bluetooth/hci_usb.h
Back to the patch index
Back to the overall index

diff -urN linux-2.4.22/drivers/cdrom/cdrom.c linux-2.4.23/drivers/cdrom/cdrom.c
@@ -1882,20 +1882,26 @@
 	if (cgc->buflen < 0 || cgc->buflen >= 131072)
 		return -EINVAL;
 
-	if ((ubuf = cgc->buffer)) {
+	usense = cgc->sense;
+	cgc->sense = &sense;
+	if (usense && !access_ok(VERIFY_WRITE, usense, sizeof(*usense))) {
+		return -EFAULT;
+	}
+
+	ubuf = cgc->buffer;
+	if (cgc->data_direction == CGC_DATA_READ ||
+	    cgc->data_direction == CGC_DATA_WRITE) {
 		cgc->buffer = kmalloc(cgc->buflen, GFP_KERNEL);
 		if (cgc->buffer == NULL)
 			return -ENOMEM;
 	}
 
-	usense = cgc->sense;
-	cgc->sense = &sense;
-	if (usense && !access_ok(VERIFY_WRITE, usense, sizeof(*usense)))
-		return -EFAULT;
 
 	if (cgc->data_direction == CGC_DATA_READ) {
-		if (!access_ok(VERIFY_READ, ubuf, cgc->buflen))
+		if (!access_ok(VERIFY_READ, ubuf, cgc->buflen)) {
+			kfree(cgc->buffer);
 			return -EFAULT;
+		}
 	} else if (cgc->data_direction == CGC_DATA_WRITE) {
 		if (copy_from_user(cgc->buffer, ubuf, cgc->buflen)) {
 			kfree(cgc->buffer);
@@ -1907,7 +1913,10 @@
 	__copy_to_user(usense, cgc->sense, sizeof(*usense));
 	if (!ret && cgc->data_direction == CGC_DATA_READ)
 		__copy_to_user(ubuf, cgc->buffer, cgc->buflen);
-	kfree(cgc->buffer);
+	if (cgc->data_direction == CGC_DATA_READ ||
+	    cgc->data_direction == CGC_DATA_WRITE) {
+		kfree(cgc->buffer);
+	}
 	return ret;
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)