Merge "diag: Copy length and buffer locally to send to userspace client"

This commit is contained in:
qctecmdr
2021-05-06 01:01:10 -07:00
committed by Gerrit - the friendly Code Review server

View File

@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
*/
#include <linux/slab.h>
@@ -330,13 +330,19 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size,
struct diag_md_info *ch = NULL;
struct diag_buf_tbl_t *entry = NULL;
uint8_t drain_again = 0;
int peripheral = 0;
int peripheral = 0, tmp_len = 0;
struct diag_md_session_t *session_info = NULL;
struct pid *pid_struct = NULL;
struct task_struct *task_s = NULL;
unsigned char *tmp_buf = NULL;
if (!info)
return -EINVAL;
tmp_buf = vzalloc(MAX_PERIPHERAL_HDLC_BUF_SZ);
if (!tmp_buf)
return -ENOMEM;
for (i = 0; i < NUM_DIAG_MD_DEV && !err; i++) {
ch = &diag_md[i];
if (!ch->md_info_inited)
@@ -348,6 +354,8 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size,
spin_unlock_irqrestore(&ch->lock, flags);
continue;
}
tmp_len = entry->len;
memcpy(tmp_buf, entry->buf, entry->len);
peripheral = diag_md_get_peripheral(entry->ctx);
if (peripheral < 0) {
spin_unlock_irqrestore(&ch->lock, flags);
@@ -383,14 +391,6 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size,
drain_again = 1;
break;
}
} else {
if ((ret + (2 * sizeof(int)) + entry->len) >=
buf_size) {
drain_again = 1;
break;
}
}
if (i > 0) {
remote_token = diag_get_remote(i);
task_s = get_pid_task(pid_struct, PIDTYPE_PID);
if (task_s) {
@@ -404,23 +404,20 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size,
ret += sizeof(int);
put_task_struct(task_s);
}
} else {
if ((ret + (2 * sizeof(int)) + entry->len) >=
buf_size) {
drain_again = 1;
break;
}
}
task_s = get_pid_task(pid_struct, PIDTYPE_PID);
if (task_s) {
spin_lock_irqsave(&ch->lock, flags);
entry = &ch->tbl[j];
if (entry->len <= 0 || entry->buf == NULL) {
spin_unlock_irqrestore(&ch->lock,
flags);
continue;
}
spin_unlock_irqrestore(&ch->lock,
flags);
/* Copy the length of data being passed */
if (entry->len) {
if (tmp_len) {
err = copy_to_user(buf + ret,
(void *)&(entry->len),
(void *)&(tmp_len),
sizeof(int));
if (err) {
put_task_struct(task_s);
@@ -430,10 +427,10 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size,
}
/* Copy the actual data being passed */
if (entry->buf) {
if (tmp_buf) {
err = copy_to_user(buf + ret,
(void *)entry->buf,
entry->len);
(void *)tmp_buf,
tmp_len);
if (err) {
put_task_struct(task_s);
goto drop_data;
@@ -467,6 +464,8 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size,
spin_unlock_irqrestore(&ch->lock, flags);
put_pid(pid_struct);
memset(tmp_buf, 0, MAX_PERIPHERAL_HDLC_BUF_SZ);
tmp_len = 0;
}
}
@@ -482,6 +481,8 @@ int diag_md_copy_to_user(char __user *buf, int *pret, size_t buf_size,
}
put_pid(pid_struct);
}
vfree(tmp_buf);
tmp_buf = NULL;
diag_ws_on_copy_complete(DIAG_WS_MUX);
if (drain_again)
chk_logging_wakeup();