Coccinelle archive on lore.kernel.org
 help / color / Atom feed
* Re: [Cocci] [PATCH] net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol()
       [not found] <1572076456-12463-1-git-send-email-zhang.lin16@zte.com.cn>
@ 2019-10-26 19:40 ` Joe Perches
  2019-10-26 20:17   ` Julia Lawall
  2019-11-21 10:23   ` Enrico Weigelt, metux IT consult
  0 siblings, 2 replies; 8+ messages in thread
From: Joe Perches @ 2019-10-26 19:40 UTC (permalink / raw)
  To: zhanglin, davem, cocci, Andrew Morton, Thomas Gleixner, Linus Torvalds
  Cc: mkubecek, jakub.kicinski, ast, jiang.xuexin, f.fainelli, daniel,
	john.fastabend, lirongqing, maxime.chevallier, vivien.didelot,
	dan.carpenter, wang.yi59, hawk, arnd, jiri, xue.zhihong,
	natechancellor, netdev, linux-kernel, linyunsheng, pablo, bpf

On Sat, 2019-10-26 at 15:54 +0800, zhanglin wrote:
> memset() the structure ethtool_wolinfo that has padded bytes
> but the padded bytes have not been zeroed out.
[]
> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
[]
> @@ -1471,11 +1471,13 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr)
>  
>  static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
>  {
> -	struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
> +	struct ethtool_wolinfo wol;
>  
>  	if (!dev->ethtool_ops->get_wol)
>  		return -EOPNOTSUPP;
>  
> +	memset(&wol, 0, sizeof(struct ethtool_wolinfo));
> +	wol.cmd = ETHTOOL_GWOL;
>  	dev->ethtool_ops->get_wol(dev, &wol);
>  
>  	if (copy_to_user(useraddr, &wol, sizeof(wol)))

It seems likely there are more of these.

Is there any way for coccinelle to find them?

There are ~4000 structs in include/uapi and
there are ~3000 uses of copy_to_user in the tree.

$ git grep -P '\bstruct\s+\w+\s*{' include/uapi/ | cut -f2 -d" "|sort|uniq|wc -l
3785
$ git grep -w copy_to_user|wc -l
2854

A trivial grep and manual search using:

$ git grep -B20 -w copy_to_user | grep -A20 -P '\bstruct\s+\w+\s*=\s*{'

shows at least 1 (I didn't look very hard and stopped after finding 1):

   include/uapi/linux/utsname.h:struct oldold_utsname {
   include/uapi/linux/utsname.h-   char sysname[9];
   include/uapi/linux/utsname.h-   char nodename[9];
   include/uapi/linux/utsname.h-   char release[9];
   include/uapi/linux/utsname.h-   char version[9];
   include/uapi/linux/utsname.h-   char machine[9];
   include/uapi/linux/utsname.h-};

and 

   kernel/sys.c-	struct oldold_utsname tmp = {};
   kernel/sys.c-
   kernel/sys.c-	if (!name)
   kernel/sys.c-		return -EFAULT;
   kernel/sys.c-
   kernel/sys.c-	down_read(&uts_sem);
   kernel/sys.c-	memcpy(&tmp.sysname, &utsname()->sysname, __OLD_UTS_LEN);
   kernel/sys.c-	memcpy(&tmp.nodename, &utsname()->nodename, __OLD_UTS_LEN);
   kernel/sys.c-	memcpy(&tmp.release, &utsname()->release, __OLD_UTS_LEN);
   kernel/sys.c-	memcpy(&tmp.version, &utsname()->version, __OLD_UTS_LEN);
   kernel/sys.c-	memcpy(&tmp.machine, &utsname()->machine, __OLD_UTS_LEN);
   kernel/sys.c-	up_read(&uts_sem);
   kernel/sys.c:	if (copy_to_user(name, &tmp, sizeof(tmp)))

where there is likely 3 bytes of padding after 45 bytes of data
in the struct.


_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Cocci] [PATCH] net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol()
  2019-10-26 19:40 ` [Cocci] [PATCH] net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol() Joe Perches
@ 2019-10-26 20:17   ` Julia Lawall
  2019-11-21 10:23   ` Enrico Weigelt, metux IT consult
  1 sibling, 0 replies; 8+ messages in thread
From: Julia Lawall @ 2019-10-26 20:17 UTC (permalink / raw)
  To: Joe Perches
  Cc: mkubecek, jakub.kicinski, ast, natechancellor, jiang.xuexin,
	cocci, f.fainelli, daniel, john.fastabend, lirongqing,
	maxime.chevallier, vivien.didelot, dan.carpenter, wang.yi59,
	hawk, arnd, jiri, xue.zhihong, zhanglin, Thomas Gleixner, bpf,
	netdev, linux-kernel, linyunsheng, pablo, Andrew Morton,
	Linus Torvalds, davem



On Sat, 26 Oct 2019, Joe Perches wrote:

> On Sat, 2019-10-26 at 15:54 +0800, zhanglin wrote:
> > memset() the structure ethtool_wolinfo that has padded bytes
> > but the padded bytes have not been zeroed out.
> []
> > diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> []
> > @@ -1471,11 +1471,13 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr)
> >
> >  static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
> >  {
> > -	struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
> > +	struct ethtool_wolinfo wol;
> >
> >  	if (!dev->ethtool_ops->get_wol)
> >  		return -EOPNOTSUPP;
> >
> > +	memset(&wol, 0, sizeof(struct ethtool_wolinfo));
> > +	wol.cmd = ETHTOOL_GWOL;
> >  	dev->ethtool_ops->get_wol(dev, &wol);
> >
> >  	if (copy_to_user(useraddr, &wol, sizeof(wol)))
>
> It seems likely there are more of these.
>
> Is there any way for coccinelle to find them?
>
> There are ~4000 structs in include/uapi and
> there are ~3000 uses of copy_to_user in the tree.
>
> $ git grep -P '\bstruct\s+\w+\s*{' include/uapi/ | cut -f2 -d" "|sort|uniq|wc -l
> 3785
> $ git grep -w copy_to_user|wc -l
> 2854
>
> A trivial grep and manual search using:
>
> $ git grep -B20 -w copy_to_user | grep -A20 -P '\bstruct\s+\w+\s*=\s*{'
>
> shows at least 1 (I didn't look very hard and stopped after finding 1):
>
>    include/uapi/linux/utsname.h:struct oldold_utsname {
>    include/uapi/linux/utsname.h-   char sysname[9];
>    include/uapi/linux/utsname.h-   char nodename[9];
>    include/uapi/linux/utsname.h-   char release[9];
>    include/uapi/linux/utsname.h-   char version[9];
>    include/uapi/linux/utsname.h-   char machine[9];
>    include/uapi/linux/utsname.h-};
>
> and
>
>    kernel/sys.c-	struct oldold_utsname tmp = {};
>    kernel/sys.c-
>    kernel/sys.c-	if (!name)
>    kernel/sys.c-		return -EFAULT;
>    kernel/sys.c-
>    kernel/sys.c-	down_read(&uts_sem);
>    kernel/sys.c-	memcpy(&tmp.sysname, &utsname()->sysname, __OLD_UTS_LEN);
>    kernel/sys.c-	memcpy(&tmp.nodename, &utsname()->nodename, __OLD_UTS_LEN);
>    kernel/sys.c-	memcpy(&tmp.release, &utsname()->release, __OLD_UTS_LEN);
>    kernel/sys.c-	memcpy(&tmp.version, &utsname()->version, __OLD_UTS_LEN);
>    kernel/sys.c-	memcpy(&tmp.machine, &utsname()->machine, __OLD_UTS_LEN);
>    kernel/sys.c-	up_read(&uts_sem);
>    kernel/sys.c:	if (copy_to_user(name, &tmp, sizeof(tmp)))
>
> where there is likely 3 bytes of padding after 45 bytes of data
> in the struct.

I looked into this at one point, but didn't get as far as generating
patches.  I think that the approach was roughly to collect the types of
the fields, and then generate code that would use BUILD_BUG_ON to complain
if the sum of the sizes was not the same as the size of the structure.
The problem was that I wasn't sure what was a real problem, nor what was
the best way to solve it.

julia
_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Cocci] [PATCH] net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol()
  2019-10-26 19:40 ` [Cocci] [PATCH] net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol() Joe Perches
  2019-10-26 20:17   ` Julia Lawall
@ 2019-11-21 10:23   ` Enrico Weigelt, metux IT consult
  2019-11-21 11:19     ` Michal Kubecek
  1 sibling, 1 reply; 8+ messages in thread
From: Enrico Weigelt, metux IT consult @ 2019-11-21 10:23 UTC (permalink / raw)
  To: Joe Perches, zhanglin, davem, cocci, Andrew Morton,
	Thomas Gleixner, Linus Torvalds
  Cc: mkubecek, jakub.kicinski, ast, jiang.xuexin, f.fainelli, daniel,
	john.fastabend, lirongqing, maxime.chevallier, vivien.didelot,
	pablo, wang.yi59, hawk, arnd, jiri, xue.zhihong, natechancellor,
	netdev, linux-kernel, linyunsheng, dan.carpenter, bpf

On 26.10.19 21:40, Joe Perches wrote:
> On Sat, 2019-10-26 at 15:54 +0800, zhanglin wrote:
>> memset() the structure ethtool_wolinfo that has padded bytes
>> but the padded bytes have not been zeroed out.
> []
>> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> []
>> @@ -1471,11 +1471,13 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr)
>>  
>>  static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
>>  {
>> -	struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
>> +	struct ethtool_wolinfo wol;
>>  
>>  	if (!dev->ethtool_ops->get_wol)
>>  		return -EOPNOTSUPP;
>>  
>> +	memset(&wol, 0, sizeof(struct ethtool_wolinfo));
>> +	wol.cmd = ETHTOOL_GWOL;
>>  	dev->ethtool_ops->get_wol(dev, &wol);
>>  
>>  	if (copy_to_user(useraddr, &wol, sizeof(wol)))
> 
> It seems likely there are more of these.
> 
> Is there any way for coccinelle to find them?

Just curios: is static struct initialization (on stack) something that
should be avoided ? I've been under the impression that static
initialization allows thinner code and gives the compiler better chance
for optimizations.


--mtx

---
Enrico Weigelt, metux IT consult
Free software and Linux embedded engineering
info@metux.net -- +49-151-27565287
_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Cocci] [PATCH] net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol()
  2019-11-21 10:23   ` Enrico Weigelt, metux IT consult
@ 2019-11-21 11:19     ` Michal Kubecek
  2019-11-21 11:58       ` Julia Lawall
  2019-11-21 12:07       ` Dan Carpenter
  0 siblings, 2 replies; 8+ messages in thread
From: Michal Kubecek @ 2019-11-21 11:19 UTC (permalink / raw)
  To: Enrico Weigelt, metux IT consult
  Cc: jakub.kicinski, ast, natechancellor, jiang.xuexin, cocci,
	f.fainelli, daniel, john.fastabend, lirongqing,
	maxime.chevallier, vivien.didelot, dan.carpenter, wang.yi59,
	hawk, arnd, jiri, xue.zhihong, zhanglin, Thomas Gleixner, bpf,
	netdev, linux-kernel, linyunsheng, pablo, Joe Perches,
	Andrew Morton, Linus Torvalds, davem

On Thu, Nov 21, 2019 at 11:23:34AM +0100, Enrico Weigelt, metux IT consult wrote:
> On 26.10.19 21:40, Joe Perches wrote:
> > On Sat, 2019-10-26 at 15:54 +0800, zhanglin wrote:
> >> memset() the structure ethtool_wolinfo that has padded bytes
> >> but the padded bytes have not been zeroed out.
> > []
> >> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> > []
> >> @@ -1471,11 +1471,13 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr)
> >>  
> >>  static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
> >>  {
> >> -	struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
> >> +	struct ethtool_wolinfo wol;
> >>  
> >>  	if (!dev->ethtool_ops->get_wol)
> >>  		return -EOPNOTSUPP;
> >>  
> >> +	memset(&wol, 0, sizeof(struct ethtool_wolinfo));
> >> +	wol.cmd = ETHTOOL_GWOL;
> >>  	dev->ethtool_ops->get_wol(dev, &wol);
> >>  
> >>  	if (copy_to_user(useraddr, &wol, sizeof(wol)))
> > 
> > It seems likely there are more of these.
> > 
> > Is there any way for coccinelle to find them?
> 
> Just curios: is static struct initialization (on stack) something that
> should be avoided ? I've been under the impression that static
> initialization allows thinner code and gives the compiler better chance
> for optimizations.

Not in general. The (potential) problem here is that the structure has
padding and it is as a whole (i.e. including the padding) copied to
userspace. While I'm not aware of a compiler that wouldn't actually
initialize the whole data block including the padding in this case, the
C standard provides no guarantee about that so that to be sure we cannot
leak leftover kernel data to userspace, we need to explicitly initialize
the whole block.

If the structure is not going to be copied to userspace (or otherwise
exposed), using the initializer is fully sufficient and looks cleaner.

Michal Kubecek
_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Cocci] [PATCH] net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol()
  2019-11-21 11:19     ` Michal Kubecek
@ 2019-11-21 11:58       ` Julia Lawall
  2019-11-21 12:07       ` Dan Carpenter
  1 sibling, 0 replies; 8+ messages in thread
From: Julia Lawall @ 2019-11-21 11:58 UTC (permalink / raw)
  To: Michal Kubecek
  Cc: jakub.kicinski, ast, jiang.xuexin, natechancellor, f.fainelli,
	daniel, john.fastabend, lirongqing, maxime.chevallier,
	vivien.didelot, dan.carpenter, wang.yi59, hawk, arnd, jiri,
	xue.zhihong, zhanglin, Thomas Gleixner, cocci, Andrew Morton,
	netdev, linux-kernel, linyunsheng, pablo, Joe Perches, bpf,
	Linus Torvalds, davem



On Thu, 21 Nov 2019, Michal Kubecek wrote:

> On Thu, Nov 21, 2019 at 11:23:34AM +0100, Enrico Weigelt, metux IT consult wrote:
> > On 26.10.19 21:40, Joe Perches wrote:
> > > On Sat, 2019-10-26 at 15:54 +0800, zhanglin wrote:
> > >> memset() the structure ethtool_wolinfo that has padded bytes
> > >> but the padded bytes have not been zeroed out.
> > > []
> > >> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> > > []
> > >> @@ -1471,11 +1471,13 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr)
> > >>
> > >>  static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
> > >>  {
> > >> -	struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
> > >> +	struct ethtool_wolinfo wol;
> > >>
> > >>  	if (!dev->ethtool_ops->get_wol)
> > >>  		return -EOPNOTSUPP;
> > >>
> > >> +	memset(&wol, 0, sizeof(struct ethtool_wolinfo));
> > >> +	wol.cmd = ETHTOOL_GWOL;
> > >>  	dev->ethtool_ops->get_wol(dev, &wol);
> > >>
> > >>  	if (copy_to_user(useraddr, &wol, sizeof(wol)))
> > >
> > > It seems likely there are more of these.
> > >
> > > Is there any way for coccinelle to find them?
> >
> > Just curios: is static struct initialization (on stack) something that
> > should be avoided ? I've been under the impression that static
> > initialization allows thinner code and gives the compiler better chance
> > for optimizations.
>
> Not in general. The (potential) problem here is that the structure has
> padding and it is as a whole (i.e. including the padding) copied to
> userspace. While I'm not aware of a compiler that wouldn't actually
> initialize the whole data block including the padding in this case, the
> C standard provides no guarantee about that so that to be sure we cannot
> leak leftover kernel data to userspace, we need to explicitly initialize
> the whole block.

I'm not sure that it is likely that the compiler will do anything other
than ensure that all the fields are initialized.  Among the files that I
could compile, the only case with actual padding and no memset, memcpy,
copy_from_user or structure assignment that I could find was

drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c

There is the code struct drm_amdgpu_info_device dev_info = {};

but I couldn't see any thing in the assembly language that seemed to zero
the structure.  gcc probably thought its job was done because all fields
are subsequently initialized.  But the size of the structure does not seem
to be the same as the sum of the size of the fields.

The set of fields was collected with Coccinelle, which could be unreliable
for this task.

julia

>
> If the structure is not going to be copied to userspace (or otherwise
> exposed), using the initializer is fully sufficient and looks cleaner.
>
> Michal Kubecek
> _______________________________________________
> Cocci mailing list
> Cocci@systeme.lip6.fr
> https://systeme.lip6.fr/mailman/listinfo/cocci
>
_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Cocci] [PATCH] net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol()
  2019-11-21 11:19     ` Michal Kubecek
  2019-11-21 11:58       ` Julia Lawall
@ 2019-11-21 12:07       ` Dan Carpenter
  2019-11-21 13:38         ` Michal Kubecek
  1 sibling, 1 reply; 8+ messages in thread
From: Dan Carpenter @ 2019-11-21 12:07 UTC (permalink / raw)
  To: Michal Kubecek
  Cc: jakub.kicinski, ast, natechancellor, jiang.xuexin, cocci,
	f.fainelli, daniel, john.fastabend, lirongqing,
	maxime.chevallier, vivien.didelot, pablo, wang.yi59, hawk, arnd,
	jiri, xue.zhihong, zhanglin, Thomas Gleixner, bpf, netdev,
	linux-kernel, linyunsheng, Joe Perches, Andrew Morton,
	Linus Torvalds, davem

On Thu, Nov 21, 2019 at 12:19:17PM +0100, Michal Kubecek wrote:
> On Thu, Nov 21, 2019 at 11:23:34AM +0100, Enrico Weigelt, metux IT consult wrote:
> > On 26.10.19 21:40, Joe Perches wrote:
> > > On Sat, 2019-10-26 at 15:54 +0800, zhanglin wrote:
> > >> memset() the structure ethtool_wolinfo that has padded bytes
> > >> but the padded bytes have not been zeroed out.
> > > []
> > >> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> > > []
> > >> @@ -1471,11 +1471,13 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr)
> > >>  
> > >>  static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
> > >>  {
> > >> -	struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
> > >> +	struct ethtool_wolinfo wol;
> > >>  
> > >>  	if (!dev->ethtool_ops->get_wol)
> > >>  		return -EOPNOTSUPP;
> > >>  
> > >> +	memset(&wol, 0, sizeof(struct ethtool_wolinfo));
> > >> +	wol.cmd = ETHTOOL_GWOL;
> > >>  	dev->ethtool_ops->get_wol(dev, &wol);
> > >>  
> > >>  	if (copy_to_user(useraddr, &wol, sizeof(wol)))
> > > 
> > > It seems likely there are more of these.
> > > 
> > > Is there any way for coccinelle to find them?
> > 
> > Just curios: is static struct initialization (on stack) something that
> > should be avoided ? I've been under the impression that static
> > initialization allows thinner code and gives the compiler better chance
> > for optimizations.
> 
> Not in general. The (potential) problem here is that the structure has
> padding and it is as a whole (i.e. including the padding) copied to
> userspace. While I'm not aware of a compiler that wouldn't actually
> initialize the whole data block including the padding in this case, the
> C standard provides no guarantee about that so that to be sure we cannot
> leak leftover kernel data to userspace, we need to explicitly initialize
> the whole block.

GCC will not always initialize the struct holes.  This patch fixes a
real bug that GCC on my system (v7.4)

regards,
dan carpenter

_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Cocci] [PATCH] net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol()
  2019-11-21 12:07       ` Dan Carpenter
@ 2019-11-21 13:38         ` Michal Kubecek
  2019-11-21 20:40           ` Julia Lawall
  0 siblings, 1 reply; 8+ messages in thread
From: Michal Kubecek @ 2019-11-21 13:38 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: jakub.kicinski, ast, natechancellor, jiang.xuexin, cocci,
	f.fainelli, daniel, john.fastabend, lirongqing,
	maxime.chevallier, vivien.didelot, pablo, wang.yi59, hawk, arnd,
	jiri, xue.zhihong, zhanglin, Thomas Gleixner, bpf, netdev,
	linux-kernel, linyunsheng, Joe Perches, Andrew Morton,
	Linus Torvalds, davem

On Thu, Nov 21, 2019 at 03:07:33PM +0300, Dan Carpenter wrote:
> On Thu, Nov 21, 2019 at 12:19:17PM +0100, Michal Kubecek wrote:
> > On Thu, Nov 21, 2019 at 11:23:34AM +0100, Enrico Weigelt, metux IT consult wrote:
> > > On 26.10.19 21:40, Joe Perches wrote:
> > > > On Sat, 2019-10-26 at 15:54 +0800, zhanglin wrote:
> > > >> memset() the structure ethtool_wolinfo that has padded bytes
> > > >> but the padded bytes have not been zeroed out.
> > > > []
> > > >> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> > > > []
> > > >> @@ -1471,11 +1471,13 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr)
> > > >>  
> > > >>  static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
> > > >>  {
> > > >> -	struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
> > > >> +	struct ethtool_wolinfo wol;
> > > >>  
> > > >>  	if (!dev->ethtool_ops->get_wol)
> > > >>  		return -EOPNOTSUPP;
> > > >>  
> > > >> +	memset(&wol, 0, sizeof(struct ethtool_wolinfo));
> > > >> +	wol.cmd = ETHTOOL_GWOL;
> > > >>  	dev->ethtool_ops->get_wol(dev, &wol);
> > > >>  
> > > >>  	if (copy_to_user(useraddr, &wol, sizeof(wol)))
> > > > 
> > > > It seems likely there are more of these.
> > > > 
> > > > Is there any way for coccinelle to find them?
> > > 
> > > Just curios: is static struct initialization (on stack) something that
> > > should be avoided ? I've been under the impression that static
> > > initialization allows thinner code and gives the compiler better chance
> > > for optimizations.
> > 
> > Not in general. The (potential) problem here is that the structure has
> > padding and it is as a whole (i.e. including the padding) copied to
> > userspace. While I'm not aware of a compiler that wouldn't actually
> > initialize the whole data block including the padding in this case, the
> > C standard provides no guarantee about that so that to be sure we cannot
> > leak leftover kernel data to userspace, we need to explicitly initialize
> > the whole block.
> 
> GCC will not always initialize the struct holes.  This patch fixes a
> real bug that GCC on my system (v7.4)

Just checked (again) to be sure. No matter if the function is inlined or
not, gcc 7.4.1 initializes the structure by one movl (of 0x5) and two
movq (of 0x0), i.e. initializes all sizeof(struct ethtool_wolinfo) = 20
bytes including the padding.

One could certainly construct examples where a real life compiler would
only initialize the fields. That's why I said "in this case".

Michal Kubecek


_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [Cocci] [PATCH] net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol()
  2019-11-21 13:38         ` Michal Kubecek
@ 2019-11-21 20:40           ` Julia Lawall
  0 siblings, 0 replies; 8+ messages in thread
From: Julia Lawall @ 2019-11-21 20:40 UTC (permalink / raw)
  To: Michal Kubecek
  Cc: jakub.kicinski, ast, jiang.xuexin, natechancellor, f.fainelli,
	daniel, john.fastabend, lirongqing, maxime.chevallier,
	vivien.didelot, pablo, wang.yi59, hawk, arnd, jiri, xue.zhihong,
	zhanglin, Thomas Gleixner, cocci, Andrew Morton, netdev,
	linux-kernel, linyunsheng, Dan Carpenter, Joe Perches, bpf,
	Linus Torvalds, davem



On Thu, 21 Nov 2019, Michal Kubecek wrote:

> On Thu, Nov 21, 2019 at 03:07:33PM +0300, Dan Carpenter wrote:
> > On Thu, Nov 21, 2019 at 12:19:17PM +0100, Michal Kubecek wrote:
> > > On Thu, Nov 21, 2019 at 11:23:34AM +0100, Enrico Weigelt, metux IT consult wrote:
> > > > On 26.10.19 21:40, Joe Perches wrote:
> > > > > On Sat, 2019-10-26 at 15:54 +0800, zhanglin wrote:
> > > > >> memset() the structure ethtool_wolinfo that has padded bytes
> > > > >> but the padded bytes have not been zeroed out.
> > > > > []
> > > > >> diff --git a/net/core/ethtool.c b/net/core/ethtool.c
> > > > > []
> > > > >> @@ -1471,11 +1471,13 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr)
> > > > >>
> > > > >>  static int ethtool_get_wol(struct net_device *dev, char __user *useraddr)
> > > > >>  {
> > > > >> -	struct ethtool_wolinfo wol = { .cmd = ETHTOOL_GWOL };
> > > > >> +	struct ethtool_wolinfo wol;
> > > > >>
> > > > >>  	if (!dev->ethtool_ops->get_wol)
> > > > >>  		return -EOPNOTSUPP;
> > > > >>
> > > > >> +	memset(&wol, 0, sizeof(struct ethtool_wolinfo));
> > > > >> +	wol.cmd = ETHTOOL_GWOL;
> > > > >>  	dev->ethtool_ops->get_wol(dev, &wol);
> > > > >>
> > > > >>  	if (copy_to_user(useraddr, &wol, sizeof(wol)))
> > > > >
> > > > > It seems likely there are more of these.
> > > > >
> > > > > Is there any way for coccinelle to find them?
> > > >
> > > > Just curios: is static struct initialization (on stack) something that
> > > > should be avoided ? I've been under the impression that static
> > > > initialization allows thinner code and gives the compiler better chance
> > > > for optimizations.
> > >
> > > Not in general. The (potential) problem here is that the structure has
> > > padding and it is as a whole (i.e. including the padding) copied to
> > > userspace. While I'm not aware of a compiler that wouldn't actually
> > > initialize the whole data block including the padding in this case, the
> > > C standard provides no guarantee about that so that to be sure we cannot
> > > leak leftover kernel data to userspace, we need to explicitly initialize
> > > the whole block.
> >
> > GCC will not always initialize the struct holes.  This patch fixes a
> > real bug that GCC on my system (v7.4)
>
> Just checked (again) to be sure. No matter if the function is inlined or
> not, gcc 7.4.1 initializes the structure by one movl (of 0x5) and two
> movq (of 0x0), i.e. initializes all sizeof(struct ethtool_wolinfo) = 20
> bytes including the padding.
>
> One could certainly construct examples where a real life compiler would
> only initialize the fields. That's why I said "in this case".

Looking again at the case that I mentioned, I see:

# drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c:691:          struct drm_amdgpu_info_device dev_info = {};
        call    __sanitizer_cov_trace_pc        #
        leaq    840(%rsp), %rdi #, tmp1126
        xorl    %eax, %eax      # tmp1127
        movl    $46, %ecx       #, tmp1128
        rep stosq

So I guess the rep stosq is doing the memset.

julia

>
> Michal Kubecek
>
>
> _______________________________________________
> Cocci mailing list
> Cocci@systeme.lip6.fr
> https://systeme.lip6.fr/mailman/listinfo/cocci
>
_______________________________________________
Cocci mailing list
Cocci@systeme.lip6.fr
https://systeme.lip6.fr/mailman/listinfo/cocci

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, back to index

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1572076456-12463-1-git-send-email-zhang.lin16@zte.com.cn>
2019-10-26 19:40 ` [Cocci] [PATCH] net: Zeroing the structure ethtool_wolinfo in ethtool_get_wol() Joe Perches
2019-10-26 20:17   ` Julia Lawall
2019-11-21 10:23   ` Enrico Weigelt, metux IT consult
2019-11-21 11:19     ` Michal Kubecek
2019-11-21 11:58       ` Julia Lawall
2019-11-21 12:07       ` Dan Carpenter
2019-11-21 13:38         ` Michal Kubecek
2019-11-21 20:40           ` Julia Lawall

Coccinelle archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/cocci/0 cocci/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 cocci cocci/ https://lore.kernel.org/cocci \
		cocci@systeme.lip6.fr
	public-inbox-index cocci

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/fr.lip6.systeme.cocci


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git