diff mbox

[v2,media] dvb: avoid warning in dvb_net

Message ID 20161027150848.3623829-1-arnd@arndb.de (mailing list archive)
State New, archived
Headers show

Commit Message

Arnd Bergmann Oct. 27, 2016, 3:08 p.m. UTC
With gcc-5 or higher on x86, we can get a bogus warning in the
dvb-net code:

drivers/media/dvb-core/dvb_net.c: In function ‘dvb_net_ule’:
arch/x86/include/asm/string_32.h:77:14: error: ‘dest_addr’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
drivers/media/dvb-core/dvb_net.c:633:8: note: ‘dest_addr’ was declared here

The problem here is that gcc doesn't track all of the conditions
to prove it can't end up copying uninitialized data.
This changes the logic around so we zero out the destination
address earlier when we determine that it is not set here.
This allows the compiler to figure it out.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
v2: fix typo pointed out by Jarod Wilson <jarod@redhat.com>

 drivers/media/dvb-core/dvb_net.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

Comments

Mauro Carvalho Chehab Nov. 19, 2016, 2:56 p.m. UTC | #1
As Arnd reported:

	With gcc-5 or higher on x86, we can get a bogus warning in the
	dvb-net code:

	drivers/media/dvb-core/dvb_net.c: In function ‘dvb_net_ule’:
	arch/x86/include/asm/string_32.h:77:14: error: ‘dest_addr’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
	drivers/media/dvb-core/dvb_net.c:633:8: note: ‘dest_addr’ was declared here

Inspecting the code is really hard, as the function Arnd patched is really
complex.

IMHO, the best is to first simplify the logic, by breaking parts of it into
sub-routines, and then apply a proper fix.

This patch series does that.

Arnd,

After splitting the function, I think that the GCC 5 warning is not bogus,
as this code:
		skb_copy_from_linear_data(h->priv->ule_skb, dest_addr,
					  ETH_ALEN);

is called before initializing dest_dir, but, even if I'm wrong, it is not a bad
idea to zero the dest_addr before handing the logic.

PS.: I took a lot of care to avoid breaking something on this series, as I don't
have any means here to test DVB net.  So, I'd appreciate if you could take
a look and see if everything looks fine.

Thanks!
Mauro


Mauro Carvalho Chehab (3):
  [media] dvb_net: prepare to split a very complex function
  [media] dvb-net: split the logic at dvb_net_ule() into other functions
  [media] dvb_net: simplify the logic that fills the ethernet address

 drivers/media/dvb-core/dvb_net.c | 927 ++++++++++++++++++++++-----------------
 1 file changed, 526 insertions(+), 401 deletions(-)
Arnd Bergmann Nov. 21, 2016, 4:35 p.m. UTC | #2
On Saturday, November 19, 2016 12:56:57 PM CET Mauro Carvalho Chehab wrote:
> As Arnd reported:
> 
> 	With gcc-5 or higher on x86, we can get a bogus warning in the
> 	dvb-net code:
> 
> 	drivers/media/dvb-core/dvb_net.c: In function ‘dvb_net_ule’:
> 	arch/x86/include/asm/string_32.h:77:14: error: ‘dest_addr’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
> 	drivers/media/dvb-core/dvb_net.c:633:8: note: ‘dest_addr’ was declared here
> 
> Inspecting the code is really hard, as the function Arnd patched is really
> complex.
> 
> IMHO, the best is to first simplify the logic, by breaking parts of it into
> sub-routines, and then apply a proper fix.
> 
> This patch series does that.
> 
> Arnd,
> 
> After splitting the function, I think that the GCC 5 warning is not bogus,
> as this code:
> 		skb_copy_from_linear_data(h->priv->ule_skb, dest_addr,
> 					  ETH_ALEN);
>
> is called before initializing dest_dir, but, even if I'm wrong, it is not a bad
> idea to zero the dest_addr before handing the logic.

My conclusion after looking at it for a while was that it is correct, the
relevant code is roughtly:

	if (!priv->ule_dbit) {
		drop = ...;
		if (drop)
			goto done;
		else
			skb_copy_from_linear_data(priv->ule_skb, dest_addr, ETH_ALEN);
	}

	...

	if (!priv->ule_dbit) {
		memcpy(ethh->h_dest, dest_addr, ETH_ALEN)
	}

done:
	...


So it is always copied from the skb data before it gets used.

> PS.: I took a lot of care to avoid breaking something on this series, as I don't
> have any means here to test DVB net.  So, I'd appreciate if you could take
> a look and see if everything looks fine.

I have replaced my patch with your series in my randconfig builds and see no
new warnings so far.

The first patch looks correct to me, but I can't really verify the
second one by inspection. It looks like a nice cleanup and I'd assume
you did it correctly too. The third patch is probably not needed now,
I think with the 'goto' removed, gcc will be able to figure it out
already. It probably adds a few extra cycles to copy the zero data,
which shouldn't be too bad either.

	Arnd

[btw, your mchehab@s-opensource.com keeps bouncing for me, I had to
 remove that from Cc to get my reply to make it out]
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Mauro Carvalho Chehab Nov. 25, 2016, 8:50 a.m. UTC | #3
Em Mon, 21 Nov 2016 17:35:42 +0100
Arnd Bergmann <arnd@arndb.de> escreveu:

> On Saturday, November 19, 2016 12:56:57 PM CET Mauro Carvalho Chehab wrote:
> > As Arnd reported:
> > 
> > 	With gcc-5 or higher on x86, we can get a bogus warning in the
> > 	dvb-net code:
> > 
> > 	drivers/media/dvb-core/dvb_net.c: In function ‘dvb_net_ule’:
> > 	arch/x86/include/asm/string_32.h:77:14: error: ‘dest_addr’ may be used uninitialized in this function [-Werror=maybe-uninitialized]
> > 	drivers/media/dvb-core/dvb_net.c:633:8: note: ‘dest_addr’ was declared here
> > 
> > Inspecting the code is really hard, as the function Arnd patched is really
> > complex.
> > 
> > IMHO, the best is to first simplify the logic, by breaking parts of it into
> > sub-routines, and then apply a proper fix.
> > 
> > This patch series does that.
> > 
> > Arnd,
> > 
> > After splitting the function, I think that the GCC 5 warning is not bogus,
> > as this code:
> > 		skb_copy_from_linear_data(h->priv->ule_skb, dest_addr,
> > 					  ETH_ALEN);
> >
> > is called before initializing dest_dir, but, even if I'm wrong, it is not a bad
> > idea to zero the dest_addr before handing the logic.  
> 
> My conclusion after looking at it for a while was that it is correct, the
> relevant code is roughtly:
> 
> 	if (!priv->ule_dbit) {
> 		drop = ...;
> 		if (drop)
> 			goto done;
> 		else
> 			skb_copy_from_linear_data(priv->ule_skb, dest_addr, ETH_ALEN);
> 	}
> 
> 	...
> 
> 	if (!priv->ule_dbit) {
> 		memcpy(ethh->h_dest, dest_addr, ETH_ALEN)
> 	}
> 
> done:
> 	...
> 
> 
> So it is always copied from the skb data before it gets used.
> 
> > PS.: I took a lot of care to avoid breaking something on this series, as I don't
> > have any means here to test DVB net.  So, I'd appreciate if you could take
> > a look and see if everything looks fine.  
> 
> I have replaced my patch with your series in my randconfig builds and see no
> new warnings so far.
> 
> The first patch looks correct to me, but I can't really verify the
> second one by inspection. It looks like a nice cleanup and I'd assume
> you did it correctly too. The third patch is probably not needed now,
> I think with the 'goto' removed, gcc will be able to figure it out
> already. It probably adds a few extra cycles to copy the zero data,
> which shouldn't be too bad either.

Thanks for looking into it. I'll apply only the first two
patches for now. If gcc starts complaining again, we can apply
it later.


> [btw, your mchehab@s-opensource.com keeps bouncing for me, I had to
>  remove that from Cc to get my reply to make it out]

Gah! I guess I'll need to switch to use some other e-mail instead.
Maybe it is time to use mchehab@kernel.org for everything.

Thanks,
Mauro
--
To unsubscribe from this list: send the line "unsubscribe linux-media" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/media/dvb-core/dvb_net.c b/drivers/media/dvb-core/dvb_net.c
index 088914c4623f..c32156426463 100644
--- a/drivers/media/dvb-core/dvb_net.c
+++ b/drivers/media/dvb-core/dvb_net.c
@@ -688,6 +688,9 @@  static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
 							      ETH_ALEN);
 						skb_pull(priv->ule_skb, ETH_ALEN);
 					}
+				} else {
+					 /* otherwise use zero destination address */
+					eth_zero_addr(dest_addr);
 				}
 
 				/* Handle ULE Extension Headers. */
@@ -715,13 +718,8 @@  static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len )
 				if (!priv->ule_bridged) {
 					skb_push(priv->ule_skb, ETH_HLEN);
 					ethh = (struct ethhdr *)priv->ule_skb->data;
-					if (!priv->ule_dbit) {
-						 /* dest_addr buffer is only valid if priv->ule_dbit == 0 */
-						memcpy(ethh->h_dest, dest_addr, ETH_ALEN);
-						eth_zero_addr(ethh->h_source);
-					}
-					else /* zeroize source and dest */
-						memset( ethh, 0, ETH_ALEN*2 );
+					memcpy(ethh->h_dest, dest_addr, ETH_ALEN);
+					eth_zero_addr(ethh->h_source);
 
 					ethh->h_proto = htons(priv->ule_sndu_type);
 				}