Received: by 2002:a05:6a10:f3d0:0:0:0:0 with SMTP id a16csp617255pxv; Thu, 8 Jul 2021 10:00:16 -0700 (PDT) X-Google-Smtp-Source: ABdhPJylVFpNVCSBwBGXHgxxmWd5sPxyLeHWP35SICVFQ1NzwcLuqSwtYRi4Fru2V0dqUcyXfQQT X-Received: by 2002:a17:907:da3:: with SMTP id go35mr30053129ejc.243.1625763615891; Thu, 08 Jul 2021 10:00:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1625763615; cv=none; d=google.com; s=arc-20160816; b=jIxOxU2QnMwD2yM8QNyWWanSWPfkGplrTI1AbFmV4dUMlqgUf69kNGIbmaoLGopCUM jaKdLR7LTt9LrBdwTSVHn5wQjIZOBBxgsJ3grdvrJBmfT/bPNZrGo7/u0YDg3Go1e2E3 wzoIfXsxY3XEznthZ2MTgtL5uBe9TW+TqZ7zSGcKKOEGYT4/JEUKGKeGUvJhhV4+59CV nSMY3crE2F7KY3wfqxaHJzlbC9BK9g7V0xbY18TXcoLJlL9SDqpqNSaZ/RThwyxEjxad bZG019lpN0w1ArA1g178extpSReTHqBXSL7cowBSOWYpdWLBqPnIk2VVaoGCo3ERGaLA UCqA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:references:in-reply-to:message-id:date:subject :cc:to:from:dmarc-filter:sender:dkim-signature; bh=O4wkWN2rnP4eo3wD22+kpFg3/5NLciNL6N09wy5efvE=; b=q3H4LIn0WCsIltT/okDMGy0TUPzai2AngWnHbHQM96y4xIYKcyhV7fre3Ylyb5tyrW 5kxQQHcCKkwKqOvJpjrV3G7OIxR3mtbKKPBz+ZX/yeX/zZmtH1qbo4EdyCHjEeroewqX Dkb5CXPYkAnjPezM8NEYCQ1bRLANSpUXqzen84AHipNgMgB7pVi7KMoPP+1PzLuY7uf3 NlTKHJp7sX6KR8dANlxHXE411wRNhSIKoa+/gg4OIqqSEgvrCOrT2U3hZjVhHEcxsskc 1p8CltHk+n6rZdYT6743KT9m+AhGiKcltPCdq900tQJMeO0L+uJMZ5gpUb+xI1hXAbVb S7ew== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@mg.codeaurora.org header.s=smtp header.b=a3dJuiCD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w11si4565186ede.8.2021.07.08.09.59.53; Thu, 08 Jul 2021 10:00:15 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@mg.codeaurora.org header.s=smtp header.b=a3dJuiCD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229986AbhGHRBc (ORCPT + 99 others); Thu, 8 Jul 2021 13:01:32 -0400 Received: from so254-9.mailgun.net ([198.61.254.9]:60218 "EHLO so254-9.mailgun.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229863AbhGHRB3 (ORCPT ); Thu, 8 Jul 2021 13:01:29 -0400 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1625763527; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=O4wkWN2rnP4eo3wD22+kpFg3/5NLciNL6N09wy5efvE=; b=a3dJuiCDx7v4xIzm71apnVs2czFkpU/0xeDSnsW0/U6Nxe+Ep6wU5M47DRRnWj2+YSE8c5LK q3AzdHbB77xCXcpVHEg5rUCiH3HvqThKJRIEMs3SQsNkf4jnkoN6GIqqPGAGdW9N/Zb1pg5R 5+FT89PiPbKVm+ujeNsIPgGboGs= X-Mailgun-Sending-Ip: 198.61.254.9 X-Mailgun-Sid: WyI0MWYwYSIsICJsaW51eC1rZXJuZWxAdmdlci5rZXJuZWwub3JnIiwgImJlOWU0YSJd Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by smtp-out-n04.prod.us-east-1.postgun.com with SMTP id 60e72ec51938941955b32755 (version=TLS1.2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256); Thu, 08 Jul 2021 16:58:45 GMT Sender: deesin=codeaurora.org@mg.codeaurora.org Received: by smtp.codeaurora.org (Postfix, from userid 1001) id 22C72C4338A; Thu, 8 Jul 2021 16:58:45 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-caf-mail-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=ALL_TRUSTED,BAYES_00,SPF_FAIL, URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.0 Received: from deesin-linux.qualcomm.com (unknown [202.46.22.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: deesin) by smtp.codeaurora.org (Postfix) with ESMTPSA id 599B5C433F1; Thu, 8 Jul 2021 16:58:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 599B5C433F1 Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=fail smtp.mailfrom=deesin@codeaurora.org From: Deepak Kumar Singh To: bjorn.andersson@linaro.org, clew@codeaurora.org Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-remoteproc@vger.kernel.org, Deepak Kumar Singh , Andy Gross Subject: [PATCH V2 2/2] soc: qcom: smem: validate fields of shared structures Date: Thu, 8 Jul 2021 22:28:22 +0530 Message-Id: <1625763502-22806-3-git-send-email-deesin@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1625763502-22806-1-git-send-email-deesin@codeaurora.org> References: <1625763502-22806-1-git-send-email-deesin@codeaurora.org> Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Structures in shared memory that can be modified by remote processors may have untrusted values, they should be validated before use. Adding proper validation before using fields of shared structures. Signed-off-by: Deepak Kumar Singh --- drivers/soc/qcom/smem.c | 82 +++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 10 deletions(-) diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 9404eec..e4f62d9 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -366,13 +366,18 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem, struct smem_partition_header *phdr; size_t alloc_size; void *cached; + void *p_end; phdr = part->virt_base; + p_end = (void *)phdr + part->size; hdr = phdr_to_first_uncached_entry(phdr); end = phdr_to_last_uncached_entry(phdr); cached = phdr_to_last_cached_entry(phdr); + if (WARN_ON((void *)end > p_end || (void *)cached > p_end)) + return -EINVAL; + while (hdr < end) { if (hdr->canary != SMEM_PRIVATE_CANARY) goto bad_canary; @@ -382,6 +387,9 @@ static int qcom_smem_alloc_private(struct qcom_smem *smem, hdr = uncached_entry_next(hdr); } + if (WARN_ON((void *)hdr > p_end)) + return -EINVAL; + /* Check that we don't grow into the cached region */ alloc_size = sizeof(*hdr) + ALIGN(size, 8); if ((void *)hdr + alloc_size > cached) { @@ -500,6 +508,8 @@ static void *qcom_smem_get_global(struct qcom_smem *smem, struct smem_header *header; struct smem_region *region; struct smem_global_entry *entry; + u64 entry_offset; + u32 e_size; u32 aux_base; unsigned i; @@ -514,9 +524,16 @@ static void *qcom_smem_get_global(struct qcom_smem *smem, region = &smem->regions[i]; if (region->aux_base == aux_base || !aux_base) { + e_size = le32_to_cpu(entry->size); + entry_offset = le32_to_cpu(entry->offset); + + if (WARN_ON(e_size + entry_offset > region->size)) + return ERR_PTR(-EINVAL); + if (size != NULL) - *size = le32_to_cpu(entry->size); - return region->virt_base + le32_to_cpu(entry->offset); + *size = e_size; + + return region->virt_base + entry_offset; } } @@ -530,47 +547,83 @@ static void *qcom_smem_get_private(struct qcom_smem *smem, { struct smem_private_entry *e, *end; struct smem_partition_header *phdr; + void *item_ptr, *p_end; + u32 padding_data; + u32 e_size; phdr = part->virt_base; + p_end = (void *)phdr + part->size; e = phdr_to_first_uncached_entry(phdr); end = phdr_to_last_uncached_entry(phdr); + if (WARN_ON((void *)end > p_end)) + return ERR_PTR(-EINVAL); + while (e < end) { if (e->canary != SMEM_PRIVATE_CANARY) goto invalid_canary; if (le16_to_cpu(e->item) == item) { - if (size != NULL) - *size = le32_to_cpu(e->size) - - le16_to_cpu(e->padding_data); + if (size != NULL) { + e_size = le32_to_cpu(e->size); + padding_data = le16_to_cpu(e->padding_data); + + if (WARN_ON(e_size > part->size || padding_data > e_size)) + return ERR_PTR(-EINVAL); + + *size = e_size - padding_data; + } - return uncached_entry_to_item(e); + item_ptr = uncached_entry_to_item(e); + if (WARN_ON(item_ptr > p_end)) + return ERR_PTR(-EINVAL); + + return item_ptr; } e = uncached_entry_next(e); } + if (WARN_ON((void *)e > p_end)) + return ERR_PTR(-EINVAL); + /* Item was not found in the uncached list, search the cached list */ e = phdr_to_first_cached_entry(phdr, part->cacheline); end = phdr_to_last_cached_entry(phdr); + if (WARN_ON((void *)e < (void *)phdr || (void *)end > p_end)) + return ERR_PTR(-EINVAL); + while (e > end) { if (e->canary != SMEM_PRIVATE_CANARY) goto invalid_canary; if (le16_to_cpu(e->item) == item) { - if (size != NULL) - *size = le32_to_cpu(e->size) - - le16_to_cpu(e->padding_data); + if (size != NULL) { + e_size = le32_to_cpu(e->size); + padding_data = le16_to_cpu(e->padding_data); + + if (WARN_ON(e_size > part->size || padding_data > e_size)) + return ERR_PTR(-EINVAL); - return cached_entry_to_item(e); + *size = e_size - padding_data; + } + + item_ptr = cached_entry_to_item(e); + if (WARN_ON(item_ptr < (void *)phdr)) + return ERR_PTR(-EINVAL); + + return item_ptr; } e = cached_entry_next(e, part->cacheline); } + if (WARN_ON((void *)e < (void *)phdr)) + return ERR_PTR(-EINVAL); + return ERR_PTR(-ENOENT); invalid_canary: @@ -647,14 +700,23 @@ int qcom_smem_get_free_space(unsigned host) phdr = part->virt_base; ret = le32_to_cpu(phdr->offset_free_cached) - le32_to_cpu(phdr->offset_free_uncached); + + if (ret > le32_to_cpu(part->size)) + return -EINVAL; } else if (__smem->global_partition.virt_base) { part = &__smem->global_partition; phdr = part->virt_base; ret = le32_to_cpu(phdr->offset_free_cached) - le32_to_cpu(phdr->offset_free_uncached); + + if (ret > le32_to_cpu(part->size)) + return -EINVAL; } else { header = __smem->regions[0].virt_base; ret = le32_to_cpu(header->available); + + if (ret > __smem->regions[0].size) + return -EINVAL; } return ret; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project