diff options
author | Sunil Paidimarri <hisunil@codeaurora.org> | 2021-07-14 13:06:22 -0700 |
---|---|---|
committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2021-07-26 10:38:47 -0700 |
commit | f37fb52c9e76252eda60be4c132c9b4500d412e7 (patch) | |
tree | d0a3ade49a83d97fc0469516a5d14970605fef49 | |
parent | 1f7904384363ffb8416bdadb6a00436e363a3b7b (diff) | |
download | data-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.c | 30 |
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); |