]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ksmbd: implement error handling for STATUS_INFO_LENGTH_MISMATCH in smb server
authorAaditya Kansal <aadityakansal390@gmail.com>
Mon, 17 Nov 2025 18:50:31 +0000 (00:20 +0530)
committerSteve French <stfrench@microsoft.com>
Mon, 1 Dec 2025 03:11:45 +0000 (21:11 -0600)
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>
fs/smb/server/smb2pdu.c

index c3eedc70e6430afa56e79b50745fec130f435e8b..11d3fab9bde3806fc3c3c056ef8277c96e0eeda9 100644 (file)
@@ -6383,7 +6383,6 @@ static int set_file_mode_info(struct ksmbd_file *fp,
  * @share:     ksmbd_share_config pointer
  *
  * Return:     0 on success, otherwise error
- * TODO: need to implement an error handling for STATUS_INFO_LENGTH_MISMATCH
  */
 static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
                              struct smb2_set_info_req *req,
@@ -6396,14 +6395,14 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
        case FILE_BASIC_INFORMATION:
        {
                if (buf_len < sizeof(struct smb2_file_basic_info))
-                       return -EINVAL;
+                       return -EMSGSIZE;
 
                return set_file_basic_info(fp, (struct smb2_file_basic_info *)buffer, share);
        }
        case FILE_ALLOCATION_INFORMATION:
        {
                if (buf_len < sizeof(struct smb2_file_alloc_info))
-                       return -EINVAL;
+                       return -EMSGSIZE;
 
                return set_file_allocation_info(work, fp,
                                                (struct smb2_file_alloc_info *)buffer);
@@ -6411,7 +6410,7 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
        case FILE_END_OF_FILE_INFORMATION:
        {
                if (buf_len < sizeof(struct smb2_file_eof_info))
-                       return -EINVAL;
+                       return -EMSGSIZE;
 
                return set_end_of_file_info(work, fp,
                                            (struct smb2_file_eof_info *)buffer);
@@ -6419,7 +6418,7 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
        case FILE_RENAME_INFORMATION:
        {
                if (buf_len < sizeof(struct smb2_file_rename_info))
-                       return -EINVAL;
+                       return -EMSGSIZE;
 
                return set_rename_info(work, fp,
                                       (struct smb2_file_rename_info *)buffer,
@@ -6428,7 +6427,7 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
        case FILE_LINK_INFORMATION:
        {
                if (buf_len < sizeof(struct smb2_file_link_info))
-                       return -EINVAL;
+                       return -EMSGSIZE;
 
                return smb2_create_link(work, work->tcon->share_conf,
                                        (struct smb2_file_link_info *)buffer,
@@ -6438,7 +6437,7 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
        case FILE_DISPOSITION_INFORMATION:
        {
                if (buf_len < sizeof(struct smb2_file_disposition_info))
-                       return -EINVAL;
+                       return -EMSGSIZE;
 
                return set_file_disposition_info(fp,
                                                 (struct smb2_file_disposition_info *)buffer);
@@ -6452,7 +6451,7 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
                }
 
                if (buf_len < sizeof(struct smb2_ea_info))
-                       return -EINVAL;
+                       return -EMSGSIZE;
 
                return smb2_set_ea((struct smb2_ea_info *)buffer,
                                   buf_len, &fp->filp->f_path, true);
@@ -6460,14 +6459,14 @@ static int smb2_set_info_file(struct ksmbd_work *work, struct ksmbd_file *fp,
        case FILE_POSITION_INFORMATION:
        {
                if (buf_len < sizeof(struct smb2_file_pos_info))
-                       return -EINVAL;
+                       return -EMSGSIZE;
 
                return set_file_position_info(fp, (struct smb2_file_pos_info *)buffer);
        }
        case FILE_MODE_INFORMATION:
        {
                if (buf_len < sizeof(struct smb2_file_mode_info))
-                       return -EINVAL;
+                       return -EMSGSIZE;
 
                return set_file_mode_info(fp, (struct smb2_file_mode_info *)buffer);
        }
@@ -6574,6 +6573,8 @@ err_out:
                rsp->hdr.Status = STATUS_ACCESS_DENIED;
        else if (rc == -EINVAL)
                rsp->hdr.Status = STATUS_INVALID_PARAMETER;
+       else if (rc == -EMSGSIZE)
+               rsp->hdr.Status = STATUS_INFO_LENGTH_MISMATCH;
        else if (rc == -ESHARE)
                rsp->hdr.Status = STATUS_SHARING_VIOLATION;
        else if (rc == -ENOENT)