From patchwork Thu May 27 05:02:09 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ang Way Chuang X-Patchwork-Id: 102558 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o4R52MZH016219 for ; Thu, 27 May 2010 05:02:23 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751549Ab0E0FCQ (ORCPT ); Thu, 27 May 2010 01:02:16 -0400 Received: from mail-pw0-f46.google.com ([209.85.160.46]:47669 "EHLO mail-pw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751305Ab0E0FCP (ORCPT ); Thu, 27 May 2010 01:02:15 -0400 Received: by pwi7 with SMTP id 7so548860pwi.19 for ; Wed, 26 May 2010 22:02:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:cc:subject:content-type :content-transfer-encoding; bh=vT3ll6fJoqs7yWGK1uHssoz/wtWnjInBDM1vf/Qqr9o=; b=VDeQqsTeEAvoTKgVtfERbmJjK7C4EwRnttMqx4xFms6zaywfR8uyD4XntJ62t43PRu cmB+yXW8HxCIy3TyLBRRcO9XRYW4qB8+zTPjYnYnFAov1N7QCxZE7aSwBCJjwLi+pviX RImLttUmdhJk9hcq2u8vyUCkG9A4V5bnQ3VeA= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:cc:subject :content-type:content-transfer-encoding; b=UH0b5n76GjosQcVHNIao4bPhLOuGVF6+BqDyLImG5yvCyjZ4/8nD8TTUKtbiG0/8lq n2VZijfL/HiE1XqLfOK96kPvpqaTZwLZpSzQ6mETREjwEB41/Nz1aE6xNnjh8alqMq28 Z7xEi72ZhvRRF4Z+jUjqkBQRfwmT+HCdEyyAA= Received: by 10.141.91.4 with SMTP id t4mr7488478rvl.78.1274936534772; Wed, 26 May 2010 22:02:14 -0700 (PDT) Received: from [10.207.161.7] ([202.170.57.250]) by mx.google.com with ESMTPS id i19sm709001rvn.11.2010.05.26.22.02.11 (version=TLSv1/SSLv3 cipher=RC4-MD5); Wed, 26 May 2010 22:02:13 -0700 (PDT) Message-ID: <4BFDFCD1.6020208@gmail.com> Date: Thu, 27 May 2010 13:02:09 +0800 From: Ang Way Chuang User-Agent: Thunderbird 2.0.0.24 (X11/20100411) MIME-Version: 1.0 To: linux-media@vger.kernel.org CC: Jarod Wilson Subject: [PATCH] dvb-core: Fix ULE decapsulation bug when less than 4 bytes of ULE SNDU is packed into the remaining bytes of a MPEG2-TS frame Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 27 May 2010 05:02:23 +0000 (UTC) diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index f6dac2b..6c3a8a0 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -351,6 +351,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) const u8 *ts, *ts_end, *from_where = NULL; u8 ts_remain = 0, how_much = 0, new_ts = 1; struct ethhdr *ethh = NULL; + bool error = false; #ifdef ULE_DEBUG /* The code inside ULE_DEBUG keeps a history of the last 100 TS cells processed. */ @@ -460,10 +461,16 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) /* Drop partly decoded SNDU, reset state, resync on PUSI. */ if (priv->ule_skb) { - dev_kfree_skb( priv->ule_skb ); + error = true; + dev_kfree_skb(priv->ule_skb); + } + + if (error || priv->ule_sndu_remain) { dev->stats.rx_errors++; dev->stats.rx_frame_errors++; + error = false; } + reset_ule(priv); priv->need_pusi = 1; continue; @@ -535,6 +542,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) from_where += 2; } + priv->ule_sndu_remain = priv->ule_sndu_len + 2; /* * State of current TS: * ts_remain (remaining bytes in the current TS cell) @@ -544,6 +552,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) */ switch (ts_remain) { case 1: + priv->ule_sndu_remain--; priv->ule_sndu_type = from_where[0] << 8; priv->ule_sndu_type_1 = 1; /* first byte of ule_type is set. */ ts_remain -= 1; from_where += 1; @@ -557,6 +566,7 @@ static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) default: /* complete ULE header is present in current TS. */ /* Extract ULE type field. */ if (priv->ule_sndu_type_1) { + priv->ule_sndu_type_1 = 0; priv->ule_sndu_type |= from_where[0]; from_where += 1; /* points to payload start. */ ts_remain -= 1;