lkml.org 
[lkml]   [2021]   [Feb]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.11 21/67] net: ipa: avoid field overflow
    Date
    From: Alex Elder <elder@linaro.org>

    [ Upstream commit cd1150098f2cc7bd05740c105488c293f6761f5a ]

    It's possible that the length passed to ipa_header_size_encoded()
    is larger than what can be represented by the HDR_LEN field alone
    (starting with IPA v4.5). If we attempted that, u32_encode_bits()
    would trigger a build-time error.

    Avoid this problem by masking off high-order bits of the value
    encoded as the lower portion of the header length.

    The same sort of problem exists in ipa_metadata_offset_encoded(),
    so implement the same fix there.

    Signed-off-by: Alex Elder <elder@linaro.org>
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/net/ipa/ipa_reg.h | 22 ++++++++++++++--------
    1 file changed, 14 insertions(+), 8 deletions(-)

    diff --git a/drivers/net/ipa/ipa_reg.h b/drivers/net/ipa/ipa_reg.h
    index e6b0827a244ec..732e691e9aa62 100644
    --- a/drivers/net/ipa/ipa_reg.h
    +++ b/drivers/net/ipa/ipa_reg.h
    @@ -408,15 +408,18 @@ enum ipa_cs_offload_en {
    static inline u32 ipa_header_size_encoded(enum ipa_version version,
    u32 header_size)
    {
    + u32 size = header_size & field_mask(HDR_LEN_FMASK);
    u32 val;

    - val = u32_encode_bits(header_size, HDR_LEN_FMASK);
    - if (version < IPA_VERSION_4_5)
    + val = u32_encode_bits(size, HDR_LEN_FMASK);
    + if (version < IPA_VERSION_4_5) {
    + /* ipa_assert(header_size == size); */
    return val;
    + }

    /* IPA v4.5 adds a few more most-significant bits */
    - header_size >>= hweight32(HDR_LEN_FMASK);
    - val |= u32_encode_bits(header_size, HDR_LEN_MSB_FMASK);
    + size = header_size >> hweight32(HDR_LEN_FMASK);
    + val |= u32_encode_bits(size, HDR_LEN_MSB_FMASK);

    return val;
    }
    @@ -425,15 +428,18 @@ static inline u32 ipa_header_size_encoded(enum ipa_version version,
    static inline u32 ipa_metadata_offset_encoded(enum ipa_version version,
    u32 offset)
    {
    + u32 off = offset & field_mask(HDR_OFST_METADATA_FMASK);
    u32 val;

    - val = u32_encode_bits(offset, HDR_OFST_METADATA_FMASK);
    - if (version < IPA_VERSION_4_5)
    + val = u32_encode_bits(off, HDR_OFST_METADATA_FMASK);
    + if (version < IPA_VERSION_4_5) {
    + /* ipa_assert(offset == off); */
    return val;
    + }

    /* IPA v4.5 adds a few more most-significant bits */
    - offset >>= hweight32(HDR_OFST_METADATA_FMASK);
    - val |= u32_encode_bits(offset, HDR_OFST_METADATA_MSB_FMASK);
    + off = offset >> hweight32(HDR_OFST_METADATA_FMASK);
    + val |= u32_encode_bits(off, HDR_OFST_METADATA_MSB_FMASK);

    return val;
    }
    --
    2.27.0
    \
     
     \ /
      Last update: 2021-02-24 14:46    [W:6.080 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site