[ Sasha's backport helper bot ]
Hi,
✅ All tests passed successfully. No issues detected. No action required from the submitter.
The upstream commit SHA1 provided is correct: c6cd2e8d2d9aa7ee35b1fa6a668e32a22a9753da
WARNING: Author mismatch between patch and upstream commit: Backport author: bin.lan.cn@windriver.com Commit author: Namjae Jeonlinkinjeon@kernel.org
Status in newer kernel trees: 6.13.y | Present (exact SHA1) 6.12.y | Present (exact SHA1) 6.6.y | Present (different SHA1: 39bdc4197acf) 6.1.y | Present (different SHA1: ad6480c9a5d8)
Note: The patch differs from the upstream commit: --- 1: c6cd2e8d2d9aa ! 1: 0903a126928c6 ksmbd: fix potencial out-of-bounds when buffer offset is invalid @@ Metadata ## Commit message ## ksmbd: fix potencial out-of-bounds when buffer offset is invalid
+ [ Upstream commit c6cd2e8d2d9aa7ee35b1fa6a668e32a22a9753da ] + I found potencial out-of-bounds when buffer offset fields of a few requests is invalid. This patch set the minimum value of buffer offset field to ->Buffer offset to validate buffer length. @@ Commit message Cc: stable@vger.kernel.org Signed-off-by: Namjae Jeon linkinjeon@kernel.org Signed-off-by: Steve French stfrench@microsoft.com + Signed-off-by: Bin Lan bin.lan.cn@windriver.com + Signed-off-by: He Zhe zhe.he@windriver.com
- ## fs/smb/server/smb2misc.c ## -@@ fs/smb/server/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, unsigned int *len, + ## fs/ksmbd/smb2misc.c ## +@@ fs/ksmbd/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, unsigned int *len, *len = le16_to_cpu(((struct smb2_sess_setup_req *)hdr)->SecurityBufferLength); break; case SMB2_TREE_CONNECT: @@ fs/smb/server/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, u *len = le16_to_cpu(((struct smb2_tree_connect_req *)hdr)->PathLength); break; case SMB2_CREATE: -@@ fs/smb/server/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, unsigned int *len, - max_t(unsigned short int, - le16_to_cpu(((struct smb2_create_req *)hdr)->NameOffset), - offsetof(struct smb2_create_req, Buffer)); -- - unsigned short int name_len = - le16_to_cpu(((struct smb2_create_req *)hdr)->NameLength); - -@@ fs/smb/server/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, unsigned int *len, +@@ fs/ksmbd/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, unsigned int *len, break; } case SMB2_QUERY_INFO: @@ fs/smb/server/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, u *len = le32_to_cpu(((struct smb2_set_info_req *)hdr)->BufferLength); break; case SMB2_READ: -@@ fs/smb/server/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, unsigned int *len, +@@ fs/ksmbd/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, unsigned int *len, case SMB2_WRITE: if (((struct smb2_write_req *)hdr)->DataOffset || ((struct smb2_write_req *)hdr)->Length) { - *off = max_t(unsigned int, + *off = max_t(unsigned short int, le16_to_cpu(((struct smb2_write_req *)hdr)->DataOffset), - offsetof(struct smb2_write_req, Buffer)); + offsetof(struct smb2_write_req, Buffer) - 4); *len = le32_to_cpu(((struct smb2_write_req *)hdr)->Length); -@@ fs/smb/server/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, unsigned int *len, +@@ fs/ksmbd/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, unsigned int *len, *len = le16_to_cpu(((struct smb2_write_req *)hdr)->WriteChannelInfoLength); break; case SMB2_QUERY_DIRECTORY: @@ fs/smb/server/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, u *len = le16_to_cpu(((struct smb2_query_directory_req *)hdr)->FileNameLength); break; case SMB2_LOCK: -@@ fs/smb/server/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, unsigned int *len, +@@ fs/ksmbd/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, unsigned int *len, break; } case SMB2_IOCTL: @@ fs/smb/server/smb2misc.c: static int smb2_get_data_area_len(unsigned int *off, u break; default:
- ## fs/smb/server/smb2pdu.c ## -@@ fs/smb/server/smb2pdu.c: int smb2_tree_connect(struct ksmbd_work *work) + ## fs/ksmbd/smb2pdu.c ## +@@ fs/ksmbd/smb2pdu.c: int smb2_tree_connect(struct ksmbd_work *work)
WORK_BUFFERS(work, req, rsp);
@@ fs/smb/server/smb2pdu.c: int smb2_tree_connect(struct ksmbd_work *work) le16_to_cpu(req->PathLength), true, conn->local_nls); if (IS_ERR(treename)) { -@@ fs/smb/server/smb2pdu.c: int smb2_open(struct ksmbd_work *work) +@@ fs/ksmbd/smb2pdu.c: int smb2_open(struct ksmbd_work *work) goto err_out2; }
@@ fs/smb/server/smb2pdu.c: int smb2_open(struct ksmbd_work *work) le16_to_cpu(req->NameLength), work->conn->local_nls); if (IS_ERR(name)) { -@@ fs/smb/server/smb2pdu.c: int smb2_query_dir(struct ksmbd_work *work) +@@ fs/ksmbd/smb2pdu.c: int smb2_query_dir(struct ksmbd_work *work) }
srch_flag = req->Flags; @@ fs/smb/server/smb2pdu.c: int smb2_query_dir(struct ksmbd_work *work) le16_to_cpu(req->FileNameLength), 1, conn->local_nls); if (IS_ERR(srch_ptr)) { -@@ fs/smb/server/smb2pdu.c: static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp, +@@ fs/ksmbd/smb2pdu.c: static int smb2_get_ea(struct ksmbd_work *work, struct ksmbd_file *fp, sizeof(struct smb2_ea_info_req)) return -EINVAL;
@@ fs/smb/server/smb2pdu.c: static int smb2_get_ea(struct ksmbd_work *work, struct } else { /* need to send all EAs, if no specific EA is requested*/ if (le32_to_cpu(req->Flags) & SL_RETURN_SINGLE_ENTRY) -@@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, +@@ fs/ksmbd/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, struct ksmbd_share_config *share) { unsigned int buf_len = le32_to_cpu(req->BufferLength); @@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work,
switch (req->FileInfoClass) { case FILE_BASIC_INFORMATION: -@@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, +@@ fs/ksmbd/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, if (buf_len < sizeof(struct smb2_file_basic_info)) return -EINVAL;
@@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, } case FILE_ALLOCATION_INFORMATION: { -@@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, +@@ fs/ksmbd/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, return -EINVAL;
return set_file_allocation_info(work, fp, @@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, } case FILE_END_OF_FILE_INFORMATION: { -@@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, +@@ fs/ksmbd/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, return -EINVAL;
return set_end_of_file_info(work, fp, @@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, } case FILE_RENAME_INFORMATION: { -@@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, +@@ fs/ksmbd/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, return -EINVAL;
return set_rename_info(work, fp, @@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, buf_len); } case FILE_LINK_INFORMATION: -@@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, +@@ fs/ksmbd/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, return -EINVAL;
return smb2_create_link(work, work->tcon->share_conf, @@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, buf_len, fp->filp, work->conn->local_nls); } -@@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, +@@ fs/ksmbd/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, return -EINVAL;
return set_file_disposition_info(fp, @@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, } case FILE_FULL_EA_INFORMATION: { -@@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, +@@ fs/ksmbd/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, if (buf_len < sizeof(struct smb2_ea_info)) return -EINVAL;
@@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, buf_len, &fp->filp->f_path, true); } case FILE_POSITION_INFORMATION: -@@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, +@@ fs/ksmbd/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, if (buf_len < sizeof(struct smb2_file_pos_info)) return -EINVAL;
@@ fs/smb/server/smb2pdu.c: static int smb2_set_info_file(struct ksmbd_work *work, } }
-@@ fs/smb/server/smb2pdu.c: int smb2_set_info(struct ksmbd_work *work) +@@ fs/ksmbd/smb2pdu.c: int smb2_set_info(struct ksmbd_work *work) } rc = smb2_set_info_sec(fp, le32_to_cpu(req->AdditionalInformation), @@ fs/smb/server/smb2pdu.c: int smb2_set_info(struct ksmbd_work *work) le32_to_cpu(req->BufferLength)); ksmbd_revert_fsids(work); break; -@@ fs/smb/server/smb2pdu.c: static int fsctl_pipe_transceive(struct ksmbd_work *work, u64 id, +@@ fs/ksmbd/smb2pdu.c: static int fsctl_pipe_transceive(struct ksmbd_work *work, u64 id, struct smb2_ioctl_rsp *rsp) { struct ksmbd_rpc_command *rpc_resp; @@ fs/smb/server/smb2pdu.c: static int fsctl_pipe_transceive(struct ksmbd_work *wor int nbytes = 0;
rpc_resp = ksmbd_rpc_ioctl(work->sess, id, data_buf, -@@ fs/smb/server/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) +@@ fs/ksmbd/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) u64 id = KSMBD_NO_FID; struct ksmbd_conn *conn = work->conn; int ret = 0; @@ fs/smb/server/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work)
if (work->next_smb2_rcv_hdr_off) { req = ksmbd_req_buf_next(work); -@@ fs/smb/server/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) +@@ fs/ksmbd/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) goto out; }
+ buffer = (char *)req + le32_to_cpu(req->InputOffset); -+ - cnt_code = le32_to_cpu(req->CtlCode); + cnt_code = le32_to_cpu(req->CntCode); ret = smb2_calc_max_out_buf_len(work, 48, le32_to_cpu(req->MaxOutputResponse)); -@@ fs/smb/server/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) +@@ fs/ksmbd/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) }
ret = fsctl_validate_negotiate_info(conn, @@ fs/smb/server/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) (struct validate_negotiate_info_rsp *)&rsp->Buffer[0], in_buf_len); if (ret < 0) -@@ fs/smb/server/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) +@@ fs/ksmbd/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) rsp->VolatileFileId = req->VolatileFileId; rsp->PersistentFileId = req->PersistentFileId; fsctl_copychunk(work, - (struct copychunk_ioctl_req *)&req->Buffer[0], + (struct copychunk_ioctl_req *)buffer, - le32_to_cpu(req->CtlCode), + le32_to_cpu(req->CntCode), le32_to_cpu(req->InputCount), req->VolatileFileId, -@@ fs/smb/server/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) +@@ fs/ksmbd/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) goto out; }
@@ fs/smb/server/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) if (ret < 0) goto out; break; -@@ fs/smb/server/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) +@@ fs/ksmbd/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) }
zero_data = @@ fs/smb/server/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work)
off = le64_to_cpu(zero_data->FileOffset); bfz = le64_to_cpu(zero_data->BeyondFinalZero); -@@ fs/smb/server/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) +@@ fs/ksmbd/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) }
ret = fsctl_query_allocated_ranges(work, id, @@ fs/smb/server/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) (struct file_allocated_range_buffer *)&rsp->Buffer[0], out_buf_len / sizeof(struct file_allocated_range_buffer), &nbytes); -@@ fs/smb/server/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) +@@ fs/ksmbd/smb2pdu.c: int smb2_ioctl(struct ksmbd_work *work) goto out; }
---
Results of testing on various branches:
| Branch | Patch Apply | Build Test | |---------------------------|-------------|------------| | stable/linux-5.15.y | Success | Success |