usb: gadget: f_fs: fix fortify warning
authorDmitry Antipov <dmantipov@yandex.ru>
Thu, 14 Dec 2023 09:04:15 +0000 (12:04 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 15 Dec 2023 12:55:45 +0000 (13:55 +0100)
When compiling with gcc version 14.0.0 20231206 (experimental)
and CONFIG_FORTIFY_SOURCE=y, I've noticed the following warning:

...
In function 'fortify_memcpy_chk',
    inlined from '__ffs_func_bind_do_os_desc' at drivers/usb/gadget/function/f_fs.c:2934:3:
./include/linux/fortify-string.h:588:25: warning: call to '__read_overflow2_field'
declared with attribute warning: detected read beyond size of field (2nd parameter);
maybe use struct_group()? [-Wattribute-warning]
  588 |                         __read_overflow2_field(q_size_field, size);
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This call to 'memcpy()' is interpreted as an attempt to copy both
'CompatibleID' and 'SubCompatibleID' of 'struct usb_ext_compat_desc'
from an address of the first one, which causes an overread warning.
Since we actually want to copy both of them at once, use the
convenient 'struct_group()' and 'sizeof_field()' here.

Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Link: https://lore.kernel.org/r/20231214090428.27292-1-dmantipov@yandex.ru
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/usb/gadget/function/f_fs.c
include/uapi/linux/usb/functionfs.h

index efe3e3b857695e6dc80e5c217294f3343153845c..dafedc33928ddd6f61617f8c3927b9bad5e32a39 100644 (file)
@@ -2931,9 +2931,8 @@ static int __ffs_func_bind_do_os_desc(enum ffs_os_desc_type type,
 
                t = &func->function.os_desc_table[desc->bFirstInterfaceNumber];
                t->if_id = func->interfaces_nums[desc->bFirstInterfaceNumber];
-               memcpy(t->os_desc->ext_compat_id, &desc->CompatibleID,
-                      ARRAY_SIZE(desc->CompatibleID) +
-                      ARRAY_SIZE(desc->SubCompatibleID));
+               memcpy(t->os_desc->ext_compat_id, &desc->IDs,
+                      sizeof_field(struct usb_ext_compat_desc, IDs));
                length = sizeof(*desc);
        }
                break;
index d77ee6b65328e876baf02a25fc04f4a3d0e72b7b..078098e73fd3e20776c8ba39a2d8c4594f10ea5f 100644 (file)
@@ -73,8 +73,10 @@ struct usb_os_desc_header {
 struct usb_ext_compat_desc {
        __u8    bFirstInterfaceNumber;
        __u8    Reserved1;
-       __u8    CompatibleID[8];
-       __u8    SubCompatibleID[8];
+       __struct_group(/* no tag */, IDs, /* no attrs */,
+               __u8    CompatibleID[8];
+               __u8    SubCompatibleID[8];
+       );
        __u8    Reserved2[6];
 };