From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 70E7A280A29 for ; Fri, 22 Aug 2025 17:20:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755883210; cv=none; b=DESrdBN+g9o8JMgtxmeAlhiK8833P31hw/X9Svy1wemTz/tMBjYwCQgbe1ShoXSAnQrNsjHjnq7acFnnTWZH4BR7bVI4t3CKuBQPEJ74OMVU94rtluq4FPKyJMEPSilbwMYjhxWA/g5YcLjbRQ/K7OrGxj5zAcv1EC4uQ6eLOFI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755883210; c=relaxed/simple; bh=Wq/dTD1hNE3dRnI6P2CAjKxc3aeLlkHBikD9ZKabKlY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LNGmwu0UJ1zff3oMEf9+eeaE2/t47Y6YAiakrKnT/d2VIF46SO1v2w3wIgjxUq3o2xjToypCRw34gG/JIxdqAlen64OhfhTkDlHV2y/RyfvDdbX/e7SOtNDgTtw/PlKge58vr01eCmzzdEEMO8BuOjy8pip5cLyMncVc0hZFrfU= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=pqyOOFRm; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="pqyOOFRm" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3ED1BC113CF; Fri, 22 Aug 2025 17:20:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1755883209; bh=Wq/dTD1hNE3dRnI6P2CAjKxc3aeLlkHBikD9ZKabKlY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pqyOOFRmmaHNve1RVyG1DV+W54AL+zmNu4M7F3x8B8x++NPjGrHGUaEPVmSs8suDe ygDwBiWGkYGOTbEe6dUXITaH1JCXu4Vrwo+kXMaUciPpoMf3+2qWYDJM/kmvieQ6De vYabOwUYnpyykHTnFG6pI4czb9TxV1BHZGxWjuJw8zbh7qxIPWZ6CxVZ0zpJO/dZNk L806myGTwdQ6bsWyb8vSkFsJlmlGOFwm1GXFs27MuF3CKJkExm5KoxLh2RMvwD+gyb hPMAl9V9ah+nY9AHwTPIao2ZEOegXMjXrJKpstjddwy3vK+zab4tWx3FpDViNbLIm3 te9zIdzHutOaQ== From: Sasha Levin To: stable@vger.kernel.org Cc: Bjorn Andersson , Doug Anderson , Dmitry Baryshkov , Bjorn Andersson , Sasha Levin Subject: [PATCH 6.1.y 2/2] soc: qcom: mdt_loader: Ensure we don't read past the ELF header Date: Fri, 22 Aug 2025 13:20:05 -0400 Message-ID: <20250822172005.1328408-2-sashal@kernel.org> X-Mailer: git-send-email 2.50.1 In-Reply-To: <20250822172005.1328408-1-sashal@kernel.org> References: <2025082135-dividable-grandma-3c11@gregkh> <20250822172005.1328408-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Bjorn Andersson [ Upstream commit 9f9967fed9d066ed3dae9372b45ffa4f6fccfeef ] When the MDT loader is used in remoteproc, the ELF header is sanitized beforehand, but that's not necessary the case for other clients. Validate the size of the firmware buffer to ensure that we don't read past the end as we iterate over the header. e_phentsize and e_shentsize are validated as well, to ensure that the assumptions about step size in the traversal are valid. Fixes: 2aad40d911ee ("remoteproc: Move qcom_mdt_loader into drivers/soc/qcom") Cc: stable@vger.kernel.org Reported-by: Doug Anderson Signed-off-by: Bjorn Andersson Reviewed-by: Dmitry Baryshkov Link: https://lore.kernel.org/r/20250610-mdt-loader-validation-and-fixes-v2-1-f7073e9ab899@oss.qualcomm.com Signed-off-by: Bjorn Andersson Signed-off-by: Sasha Levin --- drivers/soc/qcom/mdt_loader.c | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/drivers/soc/qcom/mdt_loader.c b/drivers/soc/qcom/mdt_loader.c index c075d38f38fe..fc6fdcd0a5d4 100644 --- a/drivers/soc/qcom/mdt_loader.c +++ b/drivers/soc/qcom/mdt_loader.c @@ -17,6 +17,37 @@ #include #include +static bool mdt_header_valid(const struct firmware *fw) +{ + const struct elf32_hdr *ehdr; + size_t phend; + size_t shend; + + if (fw->size < sizeof(*ehdr)) + return false; + + ehdr = (struct elf32_hdr *)fw->data; + + if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG)) + return false; + + if (ehdr->e_phentsize != sizeof(struct elf32_phdr)) + return -EINVAL; + + phend = size_add(size_mul(sizeof(struct elf32_phdr), ehdr->e_phnum), ehdr->e_phoff); + if (phend > fw->size) + return false; + + if (ehdr->e_shentsize != sizeof(struct elf32_shdr)) + return -EINVAL; + + shend = size_add(size_mul(sizeof(struct elf32_shdr), ehdr->e_shnum), ehdr->e_shoff); + if (shend > fw->size) + return false; + + return true; +} + static bool mdt_phdr_valid(const struct elf32_phdr *phdr) { if (phdr->p_type != PT_LOAD) @@ -84,6 +115,9 @@ ssize_t qcom_mdt_get_size(const struct firmware *fw) phys_addr_t max_addr = 0; int i; + if (!mdt_header_valid(fw)) + return -EINVAL; + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr + 1); @@ -136,6 +170,9 @@ void *qcom_mdt_read_metadata(const struct firmware *fw, size_t *data_len, ssize_t ret; void *data; + if (!mdt_header_valid(fw)) + return ERR_PTR(-EINVAL); + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr + 1); @@ -216,6 +253,9 @@ int qcom_mdt_pas_init(struct device *dev, const struct firmware *fw, int ret; int i; + if (!mdt_header_valid(fw)) + return -EINVAL; + ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr + 1); @@ -304,6 +344,9 @@ static int __qcom_mdt_load(struct device *dev, const struct firmware *fw, if (!fw || !mem_region || !mem_phys || !mem_size) return -EINVAL; + if (!mdt_header_valid(fw)) + return -EINVAL; + is_split = qcom_mdt_bins_are_split(fw, fw_name); ehdr = (struct elf32_hdr *)fw->data; phdrs = (struct elf32_phdr *)(ehdr + 1); -- 2.50.1