| From 1843e1ce5c814720761be53c0f038b67a81b2cad Mon Sep 17 00:00:00 2001 |
| From: Yilu Lin <linyilu@huawei.com> |
| Date: Wed, 18 Mar 2020 11:59:19 +0800 |
| Subject: [PATCH] CIFS: Fix bug which the return value by asynchronous read is |
| error |
| |
| commit 97adda8b3ab703de8e4c8d27646ddd54fe22879c upstream. |
| |
| This patch is used to fix the bug in collect_uncached_read_data() |
| that rc is automatically converted from a signed number to an |
| unsigned number when the CIFS asynchronous read fails. |
| It will cause ctx->rc is error. |
| |
| Example: |
| Share a directory and create a file on the Windows OS. |
| Mount the directory to the Linux OS using CIFS. |
| On the CIFS client of the Linux OS, invoke the pread interface to |
| deliver the read request. |
| |
| The size of the read length plus offset of the read request is greater |
| than the maximum file size. |
| |
| In this case, the CIFS server on the Windows OS returns a failure |
| message (for example, the return value of |
| smb2.nt_status is STATUS_INVALID_PARAMETER). |
| |
| After receiving the response message, the CIFS client parses |
| smb2.nt_status to STATUS_INVALID_PARAMETER |
| and converts it to the Linux error code (rdata->result=-22). |
| |
| Then the CIFS client invokes the collect_uncached_read_data function to |
| assign the value of rdata->result to rc, that is, rc=rdata->result=-22. |
| |
| The type of the ctx->total_len variable is unsigned integer, |
| the type of the rc variable is integer, and the type of |
| the ctx->rc variable is ssize_t. |
| |
| Therefore, during the ternary operation, the value of rc is |
| automatically converted to an unsigned number. The final result is |
| ctx->rc=4294967274. However, the expected result is ctx->rc=-22. |
| |
| Signed-off-by: Yilu Lin <linyilu@huawei.com> |
| Signed-off-by: Steve French <stfrench@microsoft.com> |
| CC: Stable <stable@vger.kernel.org> |
| Acked-by: Ronnie Sahlberg <lsahlber@redhat.com> |
| Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> |
| |
| diff --git a/fs/cifs/file.c b/fs/cifs/file.c |
| index 5910494c3f65..91ad9047afe9 100644 |
| --- a/fs/cifs/file.c |
| +++ b/fs/cifs/file.c |
| @@ -3687,7 +3687,7 @@ collect_uncached_read_data(struct cifs_aio_ctx *ctx) |
| if (rc == -ENODATA) |
| rc = 0; |
| |
| - ctx->rc = (rc == 0) ? ctx->total_len : rc; |
| + ctx->rc = (rc == 0) ? (ssize_t)ctx->total_len : rc; |
| |
| mutex_unlock(&ctx->aio_mutex); |
| |
| -- |
| 2.7.4 |
| |