Penang: resolve kasan panic

Penang:
KASAN: slab-out-of-bounds in qrtr_endpoint_register

Change-Id: I7542a0f2af0ceb0fdd04291b86795ba942ffe8d7
Signed-off-by: YangYi <yangyi31@motorola.com>
Reviewed-on: https://gerrit.mot.com/2413704
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Yuchang Guo <guoyc1@lenovo.com>
Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
YangYi 2022-10-26 11:27:31 +08:00 • committed by Xiaojun Ji
commit a65aa65ad1
3 changed files with 38 additions and 12 deletions

View file

@ -193,6 +193,7 @@ struct qrtr_node {
void *ilc;
u32 nonwake_svc[MAX_NON_WAKE_SVC_LEN];
struct qrtr_array no_wake_svc;
};
struct qrtr_tx_flow_waiter {
@ -421,6 +422,7 @@ static void __qrtr_node_release(struct kref *kref)
kthread_stop(node->task);
skb_queue_purge(&node->rx_queue);
kfree(node->no_wake_svc.arr);
kfree(node);
}
@ -944,8 +946,12 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
if (svc_id > 0) {
for (i = 0; i < MAX_NON_WAKE_SVC_LEN; i++) {
if (svc_id == node->nonwake_svc[i]) {
wake = false;
break;
for (i = 0; i < node->no_wake_svc.size; i++) {
if (svc_id == node->no_wake_svc.arr[i]) {
wake = false;
break;
}
}
}
}
}
@ -964,7 +970,6 @@ int qrtr_endpoint_post(struct qrtr_endpoint *ep, const void *data, size_t len)
qrtr_port_put(ipc);
}
return 0;
err:
@ -1170,7 +1175,7 @@ static void qrtr_hello_work(struct kthread_work *work)
* The specified endpoint must have the xmit function pointer set on call.
*/
int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int net_id,
bool rt, u32 *svc_arr)
bool rt, struct qrtr_array *svc_arr)
{
struct qrtr_node *node;
struct sched_param param = {.sched_priority = 1};
@ -1203,7 +1208,12 @@ int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int net_id,
if (svc_arr)
memcpy(node->nonwake_svc, svc_arr, MAX_NON_WAKE_SVC_LEN * sizeof(int));
if(svc_arr && svc_arr->size) {
node->no_wake_svc.arr = kmalloc_array(svc_arr->size, sizeof(u32), GFP_KERNEL);
memcpy((void *)node->no_wake_svc.arr, (void *)svc_arr->arr,
svc_arr->size * sizeof(u32));
node->no_wake_svc.size = svc_arr->size;
}
mutex_init(&node->qrtr_tx_lock);
INIT_RADIX_TREE(&node->qrtr_tx_flow, GFP_KERNEL);
init_waitqueue_head(&node->resume_tx);

View file

@ -28,8 +28,20 @@ struct qrtr_endpoint {
struct qrtr_node *node;
};
/**
* struct qrtr_array - array with size
* @arr: elements in the array
* @size: number of elements
*
* An array with its size provided.
*/
struct qrtr_array {
u32 *arr;
size_t size;
};
int qrtr_endpoint_register(struct qrtr_endpoint *ep, unsigned int net_id,
bool rt, u32 *svc_arr);
bool rt, struct qrtr_array *svc_arr);
void qrtr_endpoint_unregister(struct qrtr_endpoint *ep);

View file

@ -64,8 +64,9 @@ static int qcom_smd_qrtr_probe(struct rpmsg_device *rpdev)
struct qrtr_smd_dev *qdev;
u32 net_id;
bool rt;
int rc, size;
u32 *svc_arr = NULL;
int rc;
size_t size;
struct qrtr_array svc_arr = {NULL, 0};
pr_info("%s:Entered\n", __func__);
qdev = devm_kzalloc(&rpdev->dev, sizeof(*qdev), GFP_KERNEL);
@ -87,13 +88,16 @@ static int qcom_smd_qrtr_probe(struct rpmsg_device *rpdev)
if (size > 0) {
if (size > MAX_NON_WAKE_SVC_LEN)
size = MAX_NON_WAKE_SVC_LEN;
svc_arr = kmalloc_array(size, sizeof(u32), GFP_KERNEL);
svc_arr.size = size;
svc_arr.arr = kmalloc_array(size, sizeof(u32), GFP_KERNEL);
if (!svc_arr.arr)
return -ENOMEM;
of_property_read_u32_array(rpdev->dev.of_node, "qcom,non-wake-svc",
svc_arr, size);
svc_arr.arr, size);
}
rc = qrtr_endpoint_register(&qdev->ep, net_id, rt, svc_arr);
kfree(svc_arr);
rc = qrtr_endpoint_register(&qdev->ep, net_id, rt, &svc_arr);
kfree(svc_arr.arr);
if (rc)
return rc;