Commit 0015eb6e authored by Dmitry Antipov's avatar Dmitry Antipov Committed by Steve French
Browse files

smb: client, common: fix fortify warnings



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: default avatarDmitry Antipov <dmantipov@yandex.ru>
Acked-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 88010155
Loading
Loading
Loading
Loading
+14 −10
Original line number Diff line number Diff line
@@ -882,11 +882,13 @@ typedef struct smb_com_open_rsp {
	__u8 OplockLevel;
	__u16 Fid;
	__le32 CreateAction;
	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 */
	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 */
+4 −2
Original line number Diff line number Diff line
@@ -1244,8 +1244,10 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
		*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;
+3 −5
Original line number Diff line number Diff line
@@ -3472,12 +3472,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);
+9 −7
Original line number Diff line number Diff line
@@ -319,6 +319,7 @@ struct smb2_file_reparse_point_info {
} __packed;

struct smb2_file_network_open_info {
	struct_group(network_open_info,
		__le64 CreationTime;
		__le64 LastAccessTime;
		__le64 LastWriteTime;
@@ -326,6 +327,7 @@ struct smb2_file_network_open_info {
		__le64 AllocationSize;
		__le64 EndOfFile;
		__le32 Attributes;
	);
	__le32 Reserved;
} __packed; /* level 34 Query also similar returned in close rsp and open rsp */

+10 −7
Original line number Diff line number Diff line
@@ -702,13 +702,16 @@ struct smb2_close_rsp {
	__le16 StructureSize; /* 60 */
	__le16 Flags;
	__le32 Reserved;
	struct_group(network_open_info,
		__le64 CreationTime;
		__le64 LastAccessTime;
		__le64 LastWriteTime;
		__le64 ChangeTime;
	__le64 AllocationSize;	/* Beginning of FILE_STANDARD_INFO equivalent */
		/* Beginning of FILE_STANDARD_INFO equivalent */
		__le64 AllocationSize;
		__le64 EndOfFile;
		__le32 Attributes;
	);
} __packed;