[PATCH] Memory leak in dem

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



There is a memory lead in the demuxer, it's possible to open the dvr0 device
several times, each time after the first will leak the dvr buffer.  This patch
fixes that by only allowing a single read mode open, which is what the API says
should be the case.  It's still possible to open multiple times in write mode.
This doesn't seem to cause a problem and could be a useful thing to do.  It
would allow separate processes/threads to send audio/video/subtitles to a
decoder.

This is my first time using mercurial, so hopefully I got the patch format
correct.
# HG changeset patch
# User xyzzy@xxxxxxxxxxxxxxxxxxx
# Node ID 6396b65320e33fa6507622cbf58f6c0d2bf0da1f
# Parent  e4f6344a95f9b9027f555f95dfa2e6af023d95e4
Fix memory leak in dvr open

From: Trent Piepho <xyzzy@xxxxxxxxxxxxx>

The dvr device could be opened multiple times simultaneously in O_RDONLY mode. 
Each open after the first would allocate a new dvr buffer (1880 KB) and leak
the old buffer.  The first close would de-allocate the dvr buffer and cause
all other open dvrs to stop working.  This patch allows only a single O_RDONLY
open of the drv device, as per the API specification.  Multiple O_WRONLY opens
are still allowed and don't appear to cause any problems.

Signed-off-by: Trent Piepho <xyzzy@xxxxxxxxxxxxx>

diff -r e4f6344a95f9 -r 6396b65320e3 linux/drivers/media/dvb/dvb-core/dmxdev.c
--- a/linux/drivers/media/dvb/dvb-core/dmxdev.c	Mon Mar 27 11:00:40 2006 -0300
+++ b/linux/drivers/media/dvb/dvb-core/dmxdev.c	Mon Mar 27 13:31:49 2006 -0800
@@ -141,12 +141,18 @@ static int dvb_dvr_open(struct inode *in
 	}
 
 	if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
-		void *mem = vmalloc(DVR_BUFFER_SIZE);
+		void *mem;
+		if (!dvbdev->readers) {
+			mutex_unlock(&dmxdev->mutex);
+			return -EBUSY;
+		}
+		mem = vmalloc(DVR_BUFFER_SIZE);
 		if (!mem) {
 			mutex_unlock(&dmxdev->mutex);
 			return -ENOMEM;
 		}
 		dvb_ringbuffer_init(&dmxdev->dvr_buffer, mem, DVR_BUFFER_SIZE);
+		dvbdev->readers--;
 	}
 
 	if ((file->f_flags & O_ACCMODE) == O_WRONLY) {
@@ -184,6 +190,7 @@ static int dvb_dvr_release(struct inode 
 						dmxdev->dvr_orig_fe);
 	}
 	if ((file->f_flags & O_ACCMODE) == O_RDONLY) {
+		dvbdev->readers++;
 		if (dmxdev->dvr_buffer.data) {
 			void *mem = dmxdev->dvr_buffer.data;
 			mb();
@@ -1029,8 +1036,7 @@ static struct file_operations dvb_dvr_fo
 
 static struct dvb_device dvbdev_dvr = {
 	.priv = NULL,
-	.users = 1,
-	.writers = 1,
+	.readers = 1,
 	.fops = &dvb_dvr_fops
 };
 
_______________________________________________

linux-dvb@xxxxxxxxxxx
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb

[Index of Archives]     [Linux Media]     [Video 4 Linux]     [Asterisk]     [Samba]     [Xorg]     [Xfree86]     [Linux USB]

  Powered by Linux