From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from cstnet.cn (smtp21.cstnet.cn [159.226.251.21]) (using TLSv1.2 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A5F29434E41; Mon, 6 Jul 2026 09:35:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.226.251.21 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783330527; cv=none; b=A1ZsrC9tauVBrZ7nPsWNj9ROzHszJXjLM3fXXlE8UphxE3irRPo/H+LxiX0z8M2Z1k9e+CGumJhX7dvJK+U7Pnya7Nu7+lP4Zjdq2PONK8C3RzUC5EV95xqY7JIkeZjYLQ5L2RYrZfeuCpSvU4ivCcoyOlO8fWiBHiEkaRP2Sdg= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783330527; c=relaxed/simple; bh=n0B3B0tyhdS5oTazdgAMUW+gNHDIKtv7VjTt/R0pbVI=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=qK1jZalg/91adK0YqOzHaiX7PclLxGK+kCsJ6RLNa8H8mFGI81rFL46pdfyjjYM6mmnBRM1H7HSwl9hk5DD+o+g7VvArWbKcNZUUvHMzqn2FmIAqPK6j0P0mZKbLCnkImeG7qydhBWqIRJhxePMGbhvzJwD3KhzKt9yU0zf3gbA= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn; spf=pass smtp.mailfrom=iscas.ac.cn; arc=none smtp.client-ip=159.226.251.21 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=iscas.ac.cn Received: from localhost.localdomain (unknown [111.196.245.140]) by APP-01 (Coremail) with SMTP id qwCowAAnwMi_dktq+pDxBA--.1304S2; Mon, 06 Jul 2026 17:34:55 +0800 (CST) From: Pengpeng Hou To: Cai Huoqing Cc: Pengpeng Hou , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , netdev@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] net: hinic: validate firmware image section bounds Date: Mon, 6 Jul 2026 17:34:55 +0800 Message-ID: <20260706093455.81168-1-pengpeng@iscas.ac.cn> X-Mailer: git-send-email 2.50.1 Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID:qwCowAAnwMi_dktq+pDxBA--.1304S2 X-Coremail-Antispam: 1UD129KBjvJXoWxCr4xAr4fZw4UZrW8Jr4kCrg_yoW5KrW8pa 95CFW3Kr9rGr4UJwn3ta1UuF93WrWUGa4DJF9xG3WFy3W3XrWkt3ZYyryjvr45Gr95ZFZ7 Wa1jvr4kC3W5CF7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUvj14x267AKxVW8JVW5JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26ryj6F1UM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4U JVWxJr1l84ACjcxK6I8E87Iv67AKxVW0oVCq3wA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_Gc CE3s1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2WlYx0E 2Ix0cI8IcVAFwI0_Jw0_WrylYx0Ex4A2jsIE14v26r4j6F4UMcvjeVCFs4IE7xkEbVWUJV W8JwACjcxG0xvY0x0EwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lc7CjxVAaw2AFwI0_ Jw0_GFyl42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67 AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r1q6r43MIIY rxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Gr0_Xr1lIxAIcVC0I7IYx2IY6xkF7I0E14 v26r4UJVWxJr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r4j 6F4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr1j6F4UJbIYCTnIWIevJa73UjIFyTuYvjfU5b yZUUUUU X-CM-SenderInfo: pshqw1xhqjqxpvfd2hldfou0/ The firmware update path copies each section from the image with an offset and length supplied by the firmware header. The image validator only checked the sum of section lengths and used fw_len + header_size to check the file size, but it did not prove that each section offset and length fits in the firmware payload. Reject images with a truncated header, avoid the fw_len plus header-size addition, validate each section type before it is used as a bit index, and prove every section range with offset <= fw_len and len <= fw_len - offset. Signed-off-by: Pengpeng Hou --- .../net/ethernet/huawei/hinic/hinic_devlink.c | 57 ++++++++++++++++--- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/huawei/hinic/hinic_devlink.c b/drivers/net/ethernet/huawei/hinic/hinic_devlink.c index c977c43e5d5a..0c06fbdadad3 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_devlink.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_devlink.c @@ -20,14 +20,25 @@ #include "hinic_devlink.h" #include "hinic_hw_dev.h" +static bool hinic_fw_section_valid(u32 fw_len, u32 offset, u32 len) +{ + return offset <= fw_len && len <= fw_len - offset; +} + static bool check_image_valid(struct hinic_devlink_priv *priv, const u8 *buf, - u32 image_size, struct host_image_st *host_image) + size_t image_size, struct host_image_st *host_image) { - struct fw_image_st *fw_image = NULL; + const struct fw_image_st *fw_image; u32 len = 0; u32 i; - fw_image = (struct fw_image_st *)buf; + if (image_size < UPDATEFW_IMAGE_HEAD_SIZE) { + dev_err(&priv->hwdev->hwif->pdev->dev, + "Wrong image size read from file\n"); + return false; + } + + fw_image = (const struct fw_image_st *)buf; if (fw_image->fw_magic != HINIC_MAGIC_NUM) { dev_err(&priv->hwdev->hwif->pdev->dev, "Wrong fw_magic read from file, fw_magic: 0x%x\n", @@ -41,14 +52,44 @@ static bool check_image_valid(struct hinic_devlink_priv *priv, const u8 *buf, return false; } + if (fw_image->fw_len != image_size - UPDATEFW_IMAGE_HEAD_SIZE) { + dev_err(&priv->hwdev->hwif->pdev->dev, + "Wrong data size read from file\n"); + return false; + } + for (i = 0; i < fw_image->fw_info.fw_section_cnt; i++) { - len += fw_image->fw_section_info[i].fw_section_len; - host_image->image_section_info[i] = fw_image->fw_section_info[i]; + const struct fw_section_info_st *section = + &fw_image->fw_section_info[i]; + + if (section->fw_section_type >= FILE_TYPE_TOTAL_NUM) { + dev_err(&priv->hwdev->hwif->pdev->dev, + "Wrong section type read from file: %u\n", + section->fw_section_type); + return false; + } + + if (!hinic_fw_section_valid(fw_image->fw_len, + section->fw_section_offset, + section->fw_section_len)) { + dev_err(&priv->hwdev->hwif->pdev->dev, + "Wrong section size read from file\n"); + return false; + } + + if (section->fw_section_len > fw_image->fw_len - len) { + dev_err(&priv->hwdev->hwif->pdev->dev, + "Wrong data size read from file\n"); + return false; + } + + len += section->fw_section_len; + host_image->image_section_info[i] = *section; } - if (len != fw_image->fw_len || - (fw_image->fw_len + UPDATEFW_IMAGE_HEAD_SIZE) != image_size) { - dev_err(&priv->hwdev->hwif->pdev->dev, "Wrong data size read from file\n"); + if (len != fw_image->fw_len) { + dev_err(&priv->hwdev->hwif->pdev->dev, + "Wrong data size read from file\n"); return false; } -- 2.43.0