smb: client, common: fix fortify warnings
authorDmitry Antipov <dmantipov@yandex.ru>
Tue, 28 Nov 2023 10:53:47 +0000 (13:53 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 20 Jan 2024 10:51:38 +0000 (11:51 +0100)
[ Upstream commit 0015eb6e12384ff1c589928e84deac2ad1ceb236 ]

When compiling with gcc version 14.0.0 20231126 (experimental)
and CONFIG_FORTIFY_SOURCE=y, I've noticed the following:

In file included from ./include/linux/string.h:295,
                 from ./include/linux/bitmap.h:12,
                 from ./include/linux/cpumask.h:12,
                 from ./arch/x86/include/asm/paravirt.h:17,
                 from ./arch/x86/include/asm/cpuid.h:62,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:60,
                 from ./arch/x86/include/asm/preempt.h:9,
                 from ./include/linux/preempt.h:79,
                 from ./include/linux/spinlock.h:56,
                 from ./include/linux/wait.h:9,
                 from ./include/linux/wait_bit.h:8,
                 from ./include/linux/fs.h:6,
                 from fs/smb/client/smb2pdu.c:18:
In function 'fortify_memcpy_chk',
    inlined from '__SMB2_close' at fs/smb/client/smb2pdu.c:3480:4:
./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);
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

and:

In file included from ./include/linux/string.h:295,
                 from ./include/linux/bitmap.h:12,
                 from ./include/linux/cpumask.h:12,
                 from ./arch/x86/include/asm/paravirt.h:17,
                 from ./arch/x86/include/asm/cpuid.h:62,
                 from ./arch/x86/include/asm/processor.h:19,
                 from ./arch/x86/include/asm/cpufeature.h:5,
                 from ./arch/x86/include/asm/thread_info.h:53,
                 from ./include/linux/thread_info.h:60,
                 from ./arch/x86/include/asm/preempt.h:9,
                 from ./include/linux/preempt.h:79,
                 from ./include/linux/spinlock.h:56,
                 from ./include/linux/wait.h:9,
                 from ./include/linux/wait_bit.h:8,
                 from ./include/linux/fs.h:6,
                 from fs/smb/client/cifssmb.c:17:
In function 'fortify_memcpy_chk',
    inlined from 'CIFS_open' at fs/smb/client/cifssmb.c:1248: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);
      |                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In both cases, the fortification logic inteprets calls to 'memcpy()' as an
attempts to copy an amount of data which exceeds the size of the specified
field (i.e. more than 8 bytes from __le64 value) and thus issues an overread
warning. Both of these warnings may be silenced by using the convenient
'struct_group()' quirk.

Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/smb/client/cifspdu.h
fs/smb/client/cifssmb.c
fs/smb/client/smb2pdu.c
fs/smb/client/smb2pdu.h
fs/smb/common/smb2pdu.h

index 83ccc51..c0513fb 100644 (file)
@@ -882,11 +882,13 @@ typedef struct smb_com_open_rsp {
        __u8 OplockLevel;
        __u16 Fid;
        __le32 CreateAction;
-       __le64 CreationTime;
-       __le64 LastAccessTime;
-       __le64 LastWriteTime;
-       __le64 ChangeTime;
-       __le32 FileAttributes;
+       struct_group(common_attributes,
+               __le64 CreationTime;
+               __le64 LastAccessTime;
+               __le64 LastWriteTime;
+               __le64 ChangeTime;
+               __le32 FileAttributes;
+       );
        __le64 AllocationSize;
        __le64 EndOfFile;
        __le16 FileType;
@@ -2264,11 +2266,13 @@ typedef struct {
 /* QueryFileInfo/QueryPathinfo (also for SetPath/SetFile) data buffer formats */
 /******************************************************************************/
 typedef struct { /* data block encoding of response to level 263 QPathInfo */
-       __le64 CreationTime;
-       __le64 LastAccessTime;
-       __le64 LastWriteTime;
-       __le64 ChangeTime;
-       __le32 Attributes;
+       struct_group(common_attributes,
+               __le64 CreationTime;
+               __le64 LastAccessTime;
+               __le64 LastWriteTime;
+               __le64 ChangeTime;
+               __le32 Attributes;
+       );
        __u32 Pad1;
        __le64 AllocationSize;
        __le64 EndOfFile;       /* size ie offset to first free byte in file */
index bad91ba..9ee348e 100644 (file)
@@ -1244,8 +1244,10 @@ openRetry:
                *oplock |= CIFS_CREATE_ACTION;
 
        if (buf) {
-               /* copy from CreationTime to Attributes */
-               memcpy((char *)buf, (char *)&rsp->CreationTime, 36);
+               /* copy commonly used attributes */
+               memcpy(&buf->common_attributes,
+                      &rsp->common_attributes,
+                      sizeof(buf->common_attributes));
                /* the file_info buf is endian converted by caller */
                buf->AllocationSize = rsp->AllocationSize;
                buf->EndOfFile = rsp->EndOfFile;
index 76a0b9d..5276992 100644 (file)
@@ -3401,12 +3401,10 @@ __SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
        } else {
                trace_smb3_close_done(xid, persistent_fid, tcon->tid,
                                      ses->Suid);
-               /*
-                * Note that have to subtract 4 since struct network_open_info
-                * has a final 4 byte pad that close response does not have
-                */
                if (pbuf)
-                       memcpy(pbuf, (char *)&rsp->CreationTime, sizeof(*pbuf) - 4);
+                       memcpy(&pbuf->network_open_info,
+                              &rsp->network_open_info,
+                              sizeof(pbuf->network_open_info));
        }
 
        atomic_dec(&tcon->num_remote_opens);
index 220994d..db08194 100644 (file)
@@ -319,13 +319,15 @@ struct smb2_file_reparse_point_info {
 } __packed;
 
 struct smb2_file_network_open_info {
-       __le64 CreationTime;
-       __le64 LastAccessTime;
-       __le64 LastWriteTime;
-       __le64 ChangeTime;
-       __le64 AllocationSize;
-       __le64 EndOfFile;
-       __le32 Attributes;
+       struct_group(network_open_info,
+               __le64 CreationTime;
+               __le64 LastAccessTime;
+               __le64 LastWriteTime;
+               __le64 ChangeTime;
+               __le64 AllocationSize;
+               __le64 EndOfFile;
+               __le32 Attributes;
+       );
        __le32 Reserved;
 } __packed; /* level 34 Query also similar returned in close rsp and open rsp */
 
index d58550c..63f969a 100644 (file)
@@ -700,13 +700,16 @@ struct smb2_close_rsp {
        __le16 StructureSize; /* 60 */
        __le16 Flags;
        __le32 Reserved;
-       __le64 CreationTime;
-       __le64 LastAccessTime;
-       __le64 LastWriteTime;
-       __le64 ChangeTime;
-       __le64 AllocationSize;  /* Beginning of FILE_STANDARD_INFO equivalent */
-       __le64 EndOfFile;
-       __le32 Attributes;
+       struct_group(network_open_info,
+               __le64 CreationTime;
+               __le64 LastAccessTime;
+               __le64 LastWriteTime;
+               __le64 ChangeTime;
+               /* Beginning of FILE_STANDARD_INFO equivalent */
+               __le64 AllocationSize;
+               __le64 EndOfFile;
+               __le32 Attributes;
+       );
 } __packed;