Commit 0801c137 authored by Thorsten Blum's avatar Thorsten Blum Committed by Steve French
Browse files

ksmbd: Annotate struct copychunk_ioctl_req with __counted_by_le()



Add the __counted_by_le compiler attribute to the flexible array member
Chunks to improve access bounds-checking via CONFIG_UBSAN_BOUNDS and
CONFIG_FORTIFY_SOURCE.

Change the data type of the flexible array member Chunks from __u8[] to
struct srv_copychunk[] for ChunkCount to match the number of elements in
the Chunks array. (With __u8[], each srv_copychunk would occupy 24 array
entries and the __counted_by compiler attribute wouldn't be applicable.)

Use struct_size() to calculate the size of the copychunk_ioctl_req.

Read Chunks[0] after checking that ChunkCount is not 0.

Signed-off-by: default avatarThorsten Blum <thorsten.blum@linux.dev>
Acked-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 04afb0a3
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -7562,7 +7562,6 @@ static int fsctl_copychunk(struct ksmbd_work *work,
	ci_rsp->TotalBytesWritten =
		cpu_to_le32(ksmbd_server_side_copy_max_total_size());

	chunks = (struct srv_copychunk *)&ci_req->Chunks[0];
	chunk_count = le32_to_cpu(ci_req->ChunkCount);
	if (chunk_count == 0)
		goto out;
@@ -7570,12 +7569,12 @@ static int fsctl_copychunk(struct ksmbd_work *work,

	/* verify the SRV_COPYCHUNK_COPY packet */
	if (chunk_count > ksmbd_server_side_copy_max_chunk_count() ||
	    input_count < offsetof(struct copychunk_ioctl_req, Chunks) +
	     chunk_count * sizeof(struct srv_copychunk)) {
	    input_count < struct_size(ci_req, Chunks, chunk_count)) {
		rsp->hdr.Status = STATUS_INVALID_PARAMETER;
		return -EINVAL;
	}

	chunks = &ci_req->Chunks[0];
	for (i = 0; i < chunk_count; i++) {
		if (le32_to_cpu(chunks[i].Length) == 0 ||
		    le32_to_cpu(chunks[i].Length) > ksmbd_server_side_copy_max_chunk_size())
+7 −7
Original line number Diff line number Diff line
@@ -190,13 +190,6 @@ struct resume_key_ioctl_rsp {
	__u8 Context[4]; /* ignored, Windows sets to 4 bytes of zero */
} __packed;

struct copychunk_ioctl_req {
	__le64 ResumeKey[3];
	__le32 ChunkCount;
	__le32 Reserved;
	__u8 Chunks[]; /* array of srv_copychunk */
} __packed;

struct srv_copychunk {
	__le64 SourceOffset;
	__le64 TargetOffset;
@@ -204,6 +197,13 @@ struct srv_copychunk {
	__le32 Reserved;
} __packed;

struct copychunk_ioctl_req {
	__le64 ResumeKey[3];
	__le32 ChunkCount;
	__le32 Reserved;
	struct srv_copychunk Chunks[] __counted_by_le(ChunkCount);
} __packed;

struct copychunk_ioctl_rsp {
	__le32 ChunksWritten;
	__le32 ChunkBytesWritten;