summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSunil Paidimarri <hisunil@codeaurora.org>2021-07-14 13:06:22 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2021-07-26 10:38:47 -0700
commitf37fb52c9e76252eda60be4c132c9b4500d412e7 (patch)
treed0a3ade49a83d97fc0469516a5d14970605fef49
parent1f7904384363ffb8416bdadb6a00436e363a3b7b (diff)
downloaddata-kernel-f37fb52c9e76252eda60be4c132c9b4500d412e7.tar.gz
data-kernel: emac: Fix a security issue
When program avb/dcb algorithm from ioctl request, DWC_ETH_QOS driver does not block invalid queue number from userspace. This vulnerability can be used to modify value of almost arbitrary address. Add checking and block the invalid qinx input to fix the issue. Change-Id: Ic76ff038dab3931ead11fe8fcae989b7e09c8527 Signed-off-by: Sunil Paidimarri <hisunil@codeaurora.org>
-rw-r--r--drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c b/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c
index fda72a8..c467561 100644
--- a/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c
+++ b/drivers/emac-dwc-eqos/DWC_ETH_QOS_drv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2017-2019,2021 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -6802,8 +6802,18 @@ static void DWC_ETH_QOS_program_dcb_algorithm(
DBGPR("-->DWC_ETH_QOS_program_dcb_algorithm\n");
if (copy_from_user(&l_dcb_struct, u_dcb_struct,
- sizeof(struct DWC_ETH_QOS_dcb_algorithm)))
- dev_alert(&pdata->pdev->dev, "Failed to fetch DCB Struct info from user\n");
+ sizeof(struct DWC_ETH_QOS_dcb_algorithm))) {
+ dev_alert(&pdata->pdev->dev,
+ "Failed to fetch DCB Struct info from user\n");
+ return;
+ }
+
+ if (l_dcb_struct.qinx >= DWC_ETH_QOS_TX_QUEUE_CNT) {
+ dev_alert(&pdata->pdev->dev,
+ "Invaild queue number[%u] in DCB Struct from user\n",
+ l_dcb_struct.qinx);
+ return;
+ }
hw_if->set_tx_queue_operating_mode(l_dcb_struct.qinx,
(UINT)l_dcb_struct.op_mode);
@@ -6839,8 +6849,10 @@ static void DWC_ETH_QOS_program_avb_algorithm(
DBGPR("-->DWC_ETH_QOS_program_avb_algorithm\n");
if (copy_from_user(&l_avb_struct, u_avb_struct,
- sizeof(struct DWC_ETH_QOS_avb_algorithm)))
+ sizeof(struct DWC_ETH_QOS_avb_algorithm))) {
dev_alert(&pdata->pdev->dev, "Failed to fetch AVB Struct info from user\n");
+ return;
+ }
if (pdata->speed == SPEED_1000)
avb_params = &l_avb_struct.speed1000params;
@@ -6849,10 +6861,16 @@ static void DWC_ETH_QOS_program_avb_algorithm(
/*Application uses 1 for CLASS A traffic and 2 for CLASS B traffic
Configure right channel accordingly*/
- if (l_avb_struct.qinx == 1)
+ if (l_avb_struct.qinx == 1) {
l_avb_struct.qinx = CLASS_A_TRAFFIC_TX_CHANNEL;
- else if (l_avb_struct.qinx == 2)
+ } else if (l_avb_struct.qinx == 2) {
l_avb_struct.qinx = CLASS_B_TRAFFIC_TX_CHANNEL;
+ } else {
+ dev_alert(&pdata->pdev->dev,
+ "Invalid queue number[%u] in AVB struct from user\n",
+ l_avb_struct.qinx);
+ return;
+ }
hw_if->set_tx_queue_operating_mode(l_avb_struct.qinx,
(UINT)l_avb_struct.op_mode);