Mailing List archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[linux-dvb] Re: [PATCH] fix oops from removing running dvb_net
HI Again,
this is my update of the patch (After some endurance
testing on my stability mainframe it again froze, I
saw that the argument range check was missing, argh
what a careless coding)
Here's the patch version 03, it should do the job well
for kernels 2.4 for dvb-s and budgets. For budgets on
2.6 a more work is needed (can someone help me there
for the inspiration) to secure budgets on 2.6 because the
budget-core is loaded separately and MOD_INC_USE_COUNT
gets bound to budget-core and not to actual budget driver
...
Emard
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvb_net.c dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c
--- dvb-kernel.orig/linux/drivers/media/dvb/dvb-core/dvb_net.c 2003-12-12 22:22:19.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/dvb-core/dvb_net.c 2003-12-13 18:58:46.000000000 +0100
@@ -306,7 +306,7 @@ static int dvb_net_feed_start(struct net
return 0;
}
-static void dvb_net_feed_stop(struct net_device *dev)
+static int dvb_net_feed_stop(struct net_device *dev)
{
struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
int i;
@@ -337,7 +337,11 @@ static void dvb_net_feed_stop(struct net
priv->demux->release_section_feed(priv->demux, priv->secfeed);
priv->secfeed=0;
} else
+ {
printk("%s: no feed to stop\n", dev->name);
+ return -1;
+ }
+ return 0;
}
@@ -360,7 +364,8 @@ static void wq_set_multicast_list (void
struct net_device *dev = data;
struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv;
- dvb_net_feed_stop(dev);
+ if(dvb_net_feed_stop(dev))
+ return; // no feed to stop
priv->rx_mode = RX_MODE_UNI;
@@ -387,8 +392,8 @@ static void wq_set_multicast_list (void
}
}
- dvb_net_feed_start(dev);
- }
+ dvb_net_feed_start(dev);
+}
static void dvb_net_set_multicast_list (struct net_device *dev)
@@ -592,6 +597,11 @@ static int dvb_net_remove_if(struct dvb_
if (priv->in_use)
return -EBUSY;
+ if (netif_running(&dvbnet->device[num]))
+ {
+ printk("dvb_net.c: WARNING attempt to remove netif in use\n");
+ return -EBUSY;
+ }
dvb_net_stop(&dvbnet->device[num]);
flush_scheduled_work();
kfree(priv);
@@ -649,8 +659,11 @@ static int dvb_net_do_ioctl(struct inode
struct dvb_net_priv *priv_data;
struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg;
- if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX ||
- !dvbnet->state[dvbnetif->if_num])
+ if(dvbnetif->if_num < 0 ||
+ dvbnetif->if_num >= DVB_NET_DEVICES_MAX)
+ return -EFAULT;
+
+ if(!dvbnet->state[dvbnetif->if_num])
return -EFAULT;
netdev=(struct net_device*)&dvbnet->device[dvbnetif->if_num];
@@ -659,9 +672,22 @@ static int dvb_net_do_ioctl(struct inode
break;
}
case NET_REMOVE_IF:
+ {
+ int deviceno = (int) (long) parg;
+
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
- return dvb_net_remove_if(dvbnet, (int) (long) parg);
+
+ if(deviceno < 0 ||
+ deviceno >= DVB_NET_DEVICES_MAX)
+ return -EFAULT;
+
+ if(!dvbnet->state[deviceno])
+ return -EFAULT;
+
+ return dvb_net_remove_if(dvbnet, deviceno);
+
+ }
default:
return -EINVAL;
}
Only in dvb-kernel/linux/drivers/media/dvb/dvb-core: dvb_net.c.orig
Only in dvb-kernel/linux/drivers/media/dvb/dvb-core: dvb_net.c~
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/av7110.c dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/av7110.c 2003-12-12 22:22:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/av7110.c 2003-12-13 00:04:41.000000000 +0100
@@ -3124,7 +3124,7 @@ static void dvb_feed_start_pid(struct dv
int i;
DEB_EE(("av7110: %p\n",av7110));
-
+
npids[0]=npids[1]=npids[2]=npids[3]=0xffff;
npids[4]=0xffff;
i=dvbdmxfeed->pes_type;
@@ -3162,7 +3162,7 @@ static void dvb_feed_stop_pid(struct dvb
int i;
DEB_EE(("av7110: %p\n",av7110));
-
+
if (dvbdmxfeed->pes_type<=1) {
AV_Stop(av7110, dvbdmxfeed->pes_type ?
RP_VIDEO : RP_AUDIO);
@@ -3231,7 +3231,7 @@ static int av7110_start_feed(struct dvb_
if (feed->type == DMX_TYPE_SEC) {
int i;
-
+ MOD_INC_USE_COUNT;
for (i=0; i<demux->filternum; i++) {
if (demux->filter[i].state!=DMX_STATE_READY)
continue;
@@ -3275,7 +3275,7 @@ static int av7110_stop_feed(struct dvb_d
if (feed->type == DMX_TYPE_SEC) {
int i;
-
+ MOD_DEC_USE_COUNT;
for (i=0; i<demux->filternum; i++)
if (demux->filter[i].state==DMX_STATE_GO &&
demux->filter[i].filter.parent==&feed->feed.sec) {
diff -pur dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-core.c dvb-kernel/linux/drivers/media/dvb/ttpci/budget-core.c
--- dvb-kernel.orig/linux/drivers/media/dvb/ttpci/budget-core.c 2003-12-12 22:22:18.000000000 +0100
+++ dvb-kernel/linux/drivers/media/dvb/ttpci/budget-core.c 2003-12-12 21:47:17.000000000 +0100
@@ -10,7 +10,7 @@ int budget_debug = 0;
static int stop_ts_capture(struct budget *budget)
{
DEB_EE(("budget: %p\n",budget));
-
+ MOD_DEC_USE_COUNT;
if (--budget->feeding)
return budget->feeding;
@@ -25,7 +25,7 @@ static int start_ts_capture (struct budg
struct saa7146_dev *dev=budget->dev;
DEB_EE(("budget: %p\n",budget));
-
+ MOD_INC_USE_COUNT;
if (budget->feeding)
return ++budget->feeding;
Home |
Main Index |
Thread Index