lkml.org 
[lkml]   [2022]   [Oct]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 6.0 650/862] crypto: marvell/octeontx - prevent integer overflows
    Date
    From: Dan Carpenter <dan.carpenter@oracle.com>

    [ Upstream commit caca37cf6c749ff0303f68418cfe7b757a4e0697 ]

    The "code_length" value comes from the firmware file. If your firmware
    is untrusted realistically there is probably very little you can do to
    protect yourself. Still we try to limit the damage as much as possible.
    Also Smatch marks any data read from the filesystem as untrusted and
    prints warnings if it not capped correctly.

    The "code_length * 2" can overflow. The round_up(ucode_size, 16) +
    sizeof() expression can overflow too. Prevent these overflows.

    Fixes: d9110b0b01ff ("crypto: marvell - add support for OCTEON TX CPT engine")
    Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    .../crypto/marvell/octeontx/otx_cptpf_ucode.c | 18 ++++++++++++++++--
    1 file changed, 16 insertions(+), 2 deletions(-)

    diff --git a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
    index 40b482198ebc..a765eefb18c2 100644
    --- a/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
    +++ b/drivers/crypto/marvell/octeontx/otx_cptpf_ucode.c
    @@ -286,6 +286,7 @@ static int process_tar_file(struct device *dev,
    struct tar_ucode_info_t *tar_info;
    struct otx_cpt_ucode_hdr *ucode_hdr;
    int ucode_type, ucode_size;
    + unsigned int code_length;

    /*
    * If size is less than microcode header size then don't report
    @@ -303,7 +304,13 @@ static int process_tar_file(struct device *dev,
    if (get_ucode_type(ucode_hdr, &ucode_type))
    return 0;

    - ucode_size = ntohl(ucode_hdr->code_length) * 2;
    + code_length = ntohl(ucode_hdr->code_length);
    + if (code_length >= INT_MAX / 2) {
    + dev_err(dev, "Invalid code_length %u\n", code_length);
    + return -EINVAL;
    + }
    +
    + ucode_size = code_length * 2;
    if (!ucode_size || (size < round_up(ucode_size, 16) +
    sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) {
    dev_err(dev, "Ucode %s invalid size\n", filename);
    @@ -886,6 +893,7 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode,
    {
    struct otx_cpt_ucode_hdr *ucode_hdr;
    const struct firmware *fw;
    + unsigned int code_length;
    int ret;

    set_ucode_filename(ucode, ucode_filename);
    @@ -896,7 +904,13 @@ static int ucode_load(struct device *dev, struct otx_cpt_ucode *ucode,
    ucode_hdr = (struct otx_cpt_ucode_hdr *) fw->data;
    memcpy(ucode->ver_str, ucode_hdr->ver_str, OTX_CPT_UCODE_VER_STR_SZ);
    ucode->ver_num = ucode_hdr->ver_num;
    - ucode->size = ntohl(ucode_hdr->code_length) * 2;
    + code_length = ntohl(ucode_hdr->code_length);
    + if (code_length >= INT_MAX / 2) {
    + dev_err(dev, "Ucode invalid code_length %u\n", code_length);
    + ret = -EINVAL;
    + goto release_fw;
    + }
    + ucode->size = code_length * 2;
    if (!ucode->size || (fw->size < round_up(ucode->size, 16)
    + sizeof(struct otx_cpt_ucode_hdr) + OTX_CPT_UCODE_SIGN_LEN)) {
    dev_err(dev, "Ucode %s invalid size\n", ucode_filename);
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-10-19 11:21    [W:3.732 / U:0.212 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site