net: ipa: avoid field overflow
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>
This commit is contained in:
parent
4873537430
commit
cd1150098f
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue