Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ksmbd: implement error handling for STATUS_INFO_LENGTH_MISMATCH in smb server

Add STATUS_INFO_LENGTH_MISMATCH mapping to EMSGSIZE.
Currently, STATUS_INFO_LENGTH_MISMATCH has no mapping to any error code,
making it difficult to distinguish between invalid parameters and length
mismatch.

Map STATUS_INFO_LENGTH_MISMATCH to EMSGSIZE while keeping the EINVAL for
invalid parameters. Although the buf_len check only checks for buf_size
being less than required, there was no error code for lower buf_size.
Hence, EMSGSIZE is used.

Signed-off-by: Aaditya Kansal <aadityakansal390@gmail.com>
Acked-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>

authored by

Aaditya Kansal and committed by
Steve French
e4442b2e b39a1833

+11 -10
+11 -10
fs/smb/server/smb2pdu.c
··· 6383 6383 * @share: ksmbd_share_config pointer 6384 6384 * 6385 6385 * Return: 0 on success, otherwise error 6386 - * TODO: need to implement an error handling for STATUS_INFO_LENGTH_MISMATCH 6387 6386 */ 6388 6387 static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp, 6389 6388 struct smb2_set_info_req *req, ··· 6395 6396 case FILE_BASIC_INFORMATION: 6396 6397 { 6397 6398 if (buf_len < sizeof(struct smb2_file_basic_info)) 6398 - return -EINVAL; 6399 + return -EMSGSIZE; 6399 6400 6400 6401 return set_file_basic_info(fp, (struct smb2_file_basic_info *)buffer, share); 6401 6402 } 6402 6403 case FILE_ALLOCATION_INFORMATION: 6403 6404 { 6404 6405 if (buf_len < sizeof(struct smb2_file_alloc_info)) 6405 - return -EINVAL; 6406 + return -EMSGSIZE; 6406 6407 6407 6408 return set_file_allocation_info(work, fp, 6408 6409 (struct smb2_file_alloc_info *)buffer); ··· 6410 6411 case FILE_END_OF_FILE_INFORMATION: 6411 6412 { 6412 6413 if (buf_len < sizeof(struct smb2_file_eof_info)) 6413 - return -EINVAL; 6414 + return -EMSGSIZE; 6414 6415 6415 6416 return set_end_of_file_info(work, fp, 6416 6417 (struct smb2_file_eof_info *)buffer); ··· 6418 6419 case FILE_RENAME_INFORMATION: 6419 6420 { 6420 6421 if (buf_len < sizeof(struct smb2_file_rename_info)) 6421 - return -EINVAL; 6422 + return -EMSGSIZE; 6422 6423 6423 6424 return set_rename_info(work, fp, 6424 6425 (struct smb2_file_rename_info *)buffer, ··· 6427 6428 case FILE_LINK_INFORMATION: 6428 6429 { 6429 6430 if (buf_len < sizeof(struct smb2_file_link_info)) 6430 - return -EINVAL; 6431 + return -EMSGSIZE; 6431 6432 6432 6433 return smb2_create_link(work, work->tcon->share_conf, 6433 6434 (struct smb2_file_link_info *)buffer, ··· 6437 6438 case FILE_DISPOSITION_INFORMATION: 6438 6439 { 6439 6440 if (buf_len < sizeof(struct smb2_file_disposition_info)) 6440 - return -EINVAL; 6441 + return -EMSGSIZE; 6441 6442 6442 6443 return set_file_disposition_info(fp, 6443 6444 (struct smb2_file_disposition_info *)buffer); ··· 6451 6452 } 6452 6453 6453 6454 if (buf_len < sizeof(struct smb2_ea_info)) 6454 - return -EINVAL; 6455 + return -EMSGSIZE; 6455 6456 6456 6457 return smb2_set_ea((struct smb2_ea_info *)buffer, 6457 6458 buf_len, &fp->filp->f_path, true); ··· 6459 6460 case FILE_POSITION_INFORMATION: 6460 6461 { 6461 6462 if (buf_len < sizeof(struct smb2_file_pos_info)) 6462 - return -EINVAL; 6463 + return -EMSGSIZE; 6463 6464 6464 6465 return set_file_position_info(fp, (struct smb2_file_pos_info *)buffer); 6465 6466 } 6466 6467 case FILE_MODE_INFORMATION: 6467 6468 { 6468 6469 if (buf_len < sizeof(struct smb2_file_mode_info)) 6469 - return -EINVAL; 6470 + return -EMSGSIZE; 6470 6471 6471 6472 return set_file_mode_info(fp, (struct smb2_file_mode_info *)buffer); 6472 6473 } ··· 6573 6574 rsp->hdr.Status = STATUS_ACCESS_DENIED; 6574 6575 else if (rc == -EINVAL) 6575 6576 rsp->hdr.Status = STATUS_INVALID_PARAMETER; 6577 + else if (rc == -EMSGSIZE) 6578 + rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH; 6576 6579 else if (rc == -ESHARE) 6577 6580 rsp->hdr.Status = STATUS_SHARING_VIOLATION; 6578 6581 else if (rc == -ENOENT)