mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
CIFS: Fix null pointer deref during read resp processing
Currently during receiving a read response mid->resp_buf can be NULL when it is being passed to cifs_discard_remaining_data() from cifs_readv_discard(). Fix it by always passing server->smallbuf instead and initializing mid->resp_buf at the end of read response processing. Signed-off-by: Pavel Shilovsky <pshilov@microsoft.com> CC: Stable <stable@vger.kernel.org> Acked-by: Sachin Prabhu <sprabhu@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
This commit is contained in:
parent
c08e611b7d
commit
350be257ea
@ -79,8 +79,7 @@ extern void cifs_delete_mid(struct mid_q_entry *mid);
|
|||||||
extern void cifs_wake_up_task(struct mid_q_entry *mid);
|
extern void cifs_wake_up_task(struct mid_q_entry *mid);
|
||||||
extern int cifs_handle_standard(struct TCP_Server_Info *server,
|
extern int cifs_handle_standard(struct TCP_Server_Info *server,
|
||||||
struct mid_q_entry *mid);
|
struct mid_q_entry *mid);
|
||||||
extern int cifs_discard_remaining_data(struct TCP_Server_Info *server,
|
extern int cifs_discard_remaining_data(struct TCP_Server_Info *server);
|
||||||
char *buf);
|
|
||||||
extern int cifs_call_async(struct TCP_Server_Info *server,
|
extern int cifs_call_async(struct TCP_Server_Info *server,
|
||||||
struct smb_rqst *rqst,
|
struct smb_rqst *rqst,
|
||||||
mid_receive_t *receive, mid_callback_t *callback,
|
mid_receive_t *receive, mid_callback_t *callback,
|
||||||
|
@ -1400,9 +1400,9 @@ openRetry:
|
|||||||
* current bigbuf.
|
* current bigbuf.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
cifs_discard_remaining_data(struct TCP_Server_Info *server, char *buf)
|
cifs_discard_remaining_data(struct TCP_Server_Info *server)
|
||||||
{
|
{
|
||||||
unsigned int rfclen = get_rfc1002_length(buf);
|
unsigned int rfclen = get_rfc1002_length(server->smallbuf);
|
||||||
int remaining = rfclen + 4 - server->total_read;
|
int remaining = rfclen + 4 - server->total_read;
|
||||||
|
|
||||||
while (remaining > 0) {
|
while (remaining > 0) {
|
||||||
@ -1426,8 +1426,10 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
|||||||
int length;
|
int length;
|
||||||
struct cifs_readdata *rdata = mid->callback_data;
|
struct cifs_readdata *rdata = mid->callback_data;
|
||||||
|
|
||||||
length = cifs_discard_remaining_data(server, mid->resp_buf);
|
length = cifs_discard_remaining_data(server);
|
||||||
dequeue_mid(mid, rdata->result);
|
dequeue_mid(mid, rdata->result);
|
||||||
|
mid->resp_buf = server->smallbuf;
|
||||||
|
server->smallbuf = NULL;
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1459,7 +1461,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
|||||||
|
|
||||||
if (server->ops->is_status_pending &&
|
if (server->ops->is_status_pending &&
|
||||||
server->ops->is_status_pending(buf, server, 0)) {
|
server->ops->is_status_pending(buf, server, 0)) {
|
||||||
cifs_discard_remaining_data(server, buf);
|
cifs_discard_remaining_data(server);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1519,9 +1521,6 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
|||||||
cifs_dbg(FYI, "0: iov_base=%p iov_len=%u\n",
|
cifs_dbg(FYI, "0: iov_base=%p iov_len=%u\n",
|
||||||
rdata->iov[0].iov_base, server->total_read);
|
rdata->iov[0].iov_base, server->total_read);
|
||||||
|
|
||||||
mid->resp_buf = server->smallbuf;
|
|
||||||
server->smallbuf = NULL;
|
|
||||||
|
|
||||||
/* how much data is in the response? */
|
/* how much data is in the response? */
|
||||||
data_len = server->ops->read_data_length(buf);
|
data_len = server->ops->read_data_length(buf);
|
||||||
if (data_offset + data_len > buflen) {
|
if (data_offset + data_len > buflen) {
|
||||||
@ -1544,6 +1543,8 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
|||||||
return cifs_readv_discard(server, mid);
|
return cifs_readv_discard(server, mid);
|
||||||
|
|
||||||
dequeue_mid(mid, false);
|
dequeue_mid(mid, false);
|
||||||
|
mid->resp_buf = server->smallbuf;
|
||||||
|
server->smallbuf = NULL;
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2195,7 +2195,7 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid)
|
|||||||
if (rc)
|
if (rc)
|
||||||
goto free_pages;
|
goto free_pages;
|
||||||
|
|
||||||
rc = cifs_discard_remaining_data(server, buf);
|
rc = cifs_discard_remaining_data(server);
|
||||||
if (rc)
|
if (rc)
|
||||||
goto free_pages;
|
goto free_pages;
|
||||||
|
|
||||||
@ -2221,7 +2221,7 @@ free_pages:
|
|||||||
kfree(pages);
|
kfree(pages);
|
||||||
return rc;
|
return rc;
|
||||||
discard_data:
|
discard_data:
|
||||||
cifs_discard_remaining_data(server, buf);
|
cifs_discard_remaining_data(server);
|
||||||
goto free_pages;
|
goto free_pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user