[media] DVB: improve handling of TS packets containing a raised TEI bit
authorMichael Krufky <mkrufky@kernellabs.com>
Mon, 21 May 2012 20:47:15 +0000 (17:47 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Mon, 13 Aug 2012 22:51:33 +0000 (19:51 -0300)
When the TEI bit is raised, we should not trust any of the contents of
the packet in question, including but not limited to its PID number.

Considering that we don't trust the PID number of this packet, we should
not proceed to check the packet counter (if dvb_demux_tscheck is set).

We should expect to see at least one discontinuity after a bad packet is
received, so any time a TEI is detected, a following TS packet counter
mismatch is to be expected.

There is no real reason to ever allow bad packets to pass through the
kernel demux, other than for purposes of attempting error correction via
software or statistical information.

However, since we have always passed these bad packets though the demux,
we should not change this default behavior.

Without altering module options, this patch merely prevents the
TS packet counter check on packets containing a raised TEI.

If module option dvb_demux_feed_err_pkts is set to 0, the kernel demux
will drop these error packets entirely, preventing any possibility of
corruption caused by userspace programs that are expecting valid data.

Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/dvb/dvb-core/dvb_demux.c

index d82469f842e2e023a85c88f8917081b5bce2c776..17cb81fd194ccd779d497f4e63b306f8e30e1ecf 100644 (file)
@@ -50,6 +50,11 @@ module_param(dvb_demux_speedcheck, int, 0644);
 MODULE_PARM_DESC(dvb_demux_speedcheck,
                "enable transport stream speed check");
 
+static int dvb_demux_feed_err_pkts = 1;
+module_param(dvb_demux_feed_err_pkts, int, 0644);
+MODULE_PARM_DESC(dvb_demux_feed_err_pkts,
+                "when set to 0, drop packets with the TEI bit set (1 by default)");
+
 #define dprintk_tscheck(x...) do {                              \
                if (dvb_demux_tscheck && printk_ratelimit())    \
                        printk(x);                              \
@@ -426,14 +431,18 @@ static void dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
                };
        };
 
+       if (buf[1] & 0x80) {
+               dprintk_tscheck("TEI detected. "
+                               "PID=0x%x data1=0x%x\n",
+                               pid, buf[1]);
+               /* data in this packet cant be trusted - drop it unless
+                * module option dvb_demux_feed_err_pkts is set */
+               if (!dvb_demux_feed_err_pkts)
+                       return;
+       } else /* if TEI bit is set, pid may be wrong- skip pkt counter */
        if (demux->cnt_storage && dvb_demux_tscheck) {
                /* check pkt counter */
                if (pid < MAX_PID) {
-                       if (buf[1] & 0x80)
-                               dprintk_tscheck("TEI detected. "
-                                               "PID=0x%x data1=0x%x\n",
-                                               pid, buf[1]);
-
                        if ((buf[3] & 0xf) != demux->cnt_storage[pid])
                                dprintk_tscheck("TS packet counter mismatch. "
                                                "PID=0x%x expected 0x%x "