Fix the direct assignment of offset and length attributes included in nft_exthdr structure from u32 data to u8.
Unified · Split
| @@ -59,6 +59,7 @@ static int nft_exthdr_init(const struct nft_ctx *ctx, · 58 unmodified lines | ||
| 59 | 59 | const struct nlattr * const tb[]) |
| 60 | 60 | { |
| 61 | 61 | struct nft_exthdr *priv = nft_expr_priv(expr); |
| 62 | + u32 offset, len; | |
| 62 | 63 | |
| 63 | 64 | if (tb[NFTA_EXTHDR_DREG] == NULL || |
| 64 | 65 | tb[NFTA_EXTHDR_TYPE] == NULL || |
| @@ -66,9 +67,15 @@ static int nft_exthdr_init(const struct nft_ctx *ctx, · 1 unmodified line | ||
| 66 | 67 | tb[NFTA_EXTHDR_LEN] == NULL) |
| 67 | 68 | return -EINVAL; |
| 68 | 69 | |
| 70 | + offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET])); | |
| 71 | + len = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN])); | |
| 72 | + | |
| 73 | + if (offset > U8_MAX || len > U8_MAX) | |
| 74 | + return -ERANGE; | |
| 75 | + | |
| 69 | 76 | priv->type = nla_get_u8(tb[NFTA_EXTHDR_TYPE]); |
| 70 | − priv->offset = ntohl(nla_get_be32(tb[NFTA_EXTHDR_OFFSET])); | |
| 71 | − priv->len = ntohl(nla_get_be32(tb[NFTA_EXTHDR_LEN])); | |
| 77 | + priv->offset = offset; | |
| 78 | + priv->len = len; | |
| 72 | 79 | priv->dreg = nft_parse_register(tb[NFTA_EXTHDR_DREG]); |
| 73 | 80 | |
| 74 | 81 | return nft_validate_register_store(ctx, priv->dreg, NULL, |