From 8a079632f447be9fd86f92b8e02b1940a26c8a2a Mon Sep 17 00:00:00 2001 From: Skylar Chang Date: Wed, 1 Mar 2017 16:08:27 -0800 Subject: msm: IPA: add the check on intf query The ipa_ioc_query_intf_rx_props structure comes from the ioctl handler, and it is verified that the size of rx buffer does not exceed the IPA_NUM_PROPS_MAX elements. It is also verified that the "entry->rx" buffer does not exceed IPA_NUM_PROPS_MAX when "entry" is allocated. However, the sizes of the buffer "rx->rx" and the buffer "entry->rx" are not guaranteed to be the same and will lead memory corruption issue. The fix is to add the check before memcpy. Change-Id: Idf5c2d32f47c1a1cffeaa5607193855188893ddb Signed-off-by: Skylar Chang --- drivers/platform/msm/ipa/ipa_intf.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/drivers/platform/msm/ipa/ipa_intf.c b/drivers/platform/msm/ipa/ipa_intf.c index 9a74107..18924a7 100644 --- a/drivers/platform/msm/ipa/ipa_intf.c +++ b/drivers/platform/msm/ipa/ipa_intf.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved. +/* Copyright (c) 2013-2017, 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 @@ -275,6 +275,14 @@ int ipa_query_intf_tx_props(struct ipa_ioc_query_intf_tx_props *tx) mutex_lock(&ipa_ctx->lock); list_for_each_entry(entry, &ipa_ctx->intf_list, link) { if (!strncmp(entry->name, tx->name, IPA_RESOURCE_NAME_MAX)) { + /* add the entry check */ + if (entry->num_tx_props != tx->num_tx_props) { + IPAERR("invalid entry number(%u %u)\n", + entry->num_tx_props, + tx->num_tx_props); + mutex_unlock(&ipa_ctx->lock); + return result; + } memcpy(tx->tx, entry->tx, entry->num_tx_props * sizeof(struct ipa_ioc_tx_intf_prop)); result = 0; @@ -308,6 +316,14 @@ int ipa_query_intf_rx_props(struct ipa_ioc_query_intf_rx_props *rx) mutex_lock(&ipa_ctx->lock); list_for_each_entry(entry, &ipa_ctx->intf_list, link) { if (!strncmp(entry->name, rx->name, IPA_RESOURCE_NAME_MAX)) { + /* add the entry check */ + if (entry->num_rx_props != rx->num_rx_props) { + IPAERR("invalid entry number(%u %u)\n", + entry->num_rx_props, + rx->num_rx_props); + mutex_unlock(&ipa_ctx->lock); + return result; + } memcpy(rx->rx, entry->rx, entry->num_rx_props * sizeof(struct ipa_ioc_rx_intf_prop)); result = 0; @@ -341,6 +357,14 @@ int ipa_query_intf_ext_props(struct ipa_ioc_query_intf_ext_props *ext) mutex_lock(&ipa_ctx->lock); list_for_each_entry(entry, &ipa_ctx->intf_list, link) { if (!strcmp(entry->name, ext->name)) { + /* add the entry check */ + if (entry->num_ext_props != ext->num_ext_props) { + IPAERR("invalid entry number(%u %u)\n", + entry->num_ext_props, + ext->num_ext_props); + mutex_unlock(&ipa_ctx->lock); + return result; + } memcpy(ext->ext, entry->ext, entry->num_ext_props * sizeof(struct ipa_ioc_ext_intf_prop)); result = 0; -- cgit v1.1