mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
netfilter: nf_tables: fix mismatch in big-endian system
Currently, there are two different methods to store an u16 integer to the u32 data register. For example: u32 *dest = ®s->data[priv->dreg]; 1. *dest = 0; *(u16 *) dest = val_u16; 2. *dest = val_u16; For method 1, the u16 value will be stored like this, either in big-endian or little-endian system: 0 15 31 +-+-+-+-+-+-+-+-+-+-+-+-+ | Value | 0 | +-+-+-+-+-+-+-+-+-+-+-+-+ For method 2, in little-endian system, the u16 value will be the same as listed above. But in big-endian system, the u16 value will be stored like this: 0 15 31 +-+-+-+-+-+-+-+-+-+-+-+-+ | 0 | Value | +-+-+-+-+-+-+-+-+-+-+-+-+ So later we use "memcmp(®s->data[priv->sreg], data, 2);" to do compare in nft_cmp, nft_lookup expr ..., method 2 will get the wrong result in big-endian system, as 0~15 bits will always be zero. For the similar reason, when loading an u16 value from the u32 data register, we should use "*(u16 *) sreg;" instead of "(u16)*sreg;", the 2nd method will get the wrong value in the big-endian system. So introduce some wrapper functions to store/load an u8 or u16 integer to/from the u32 data register, and use them in the right place. Signed-off-by: Liping Zhang <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
This commit is contained in:
parent
fd89b23a46
commit
10596608c4
8 changed files with 80 additions and 47 deletions
|
|
@ -27,10 +27,10 @@ static void nft_masq_ipv6_eval(const struct nft_expr *expr,
|
|||
memset(&range, 0, sizeof(range));
|
||||
range.flags = priv->flags;
|
||||
if (priv->sreg_proto_min) {
|
||||
range.min_proto.all =
|
||||
*(__be16 *)®s->data[priv->sreg_proto_min];
|
||||
range.max_proto.all =
|
||||
*(__be16 *)®s->data[priv->sreg_proto_max];
|
||||
range.min_proto.all = (__force __be16)nft_reg_load16(
|
||||
®s->data[priv->sreg_proto_min]);
|
||||
range.max_proto.all = (__force __be16)nft_reg_load16(
|
||||
®s->data[priv->sreg_proto_max]);
|
||||
}
|
||||
regs->verdict.code = nf_nat_masquerade_ipv6(pkt->skb, &range,
|
||||
nft_out(pkt));
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@ static void nft_redir_ipv6_eval(const struct nft_expr *expr,
|
|||
|
||||
memset(&range, 0, sizeof(range));
|
||||
if (priv->sreg_proto_min) {
|
||||
range.min_proto.all =
|
||||
*(__be16 *)®s->data[priv->sreg_proto_min],
|
||||
range.max_proto.all =
|
||||
*(__be16 *)®s->data[priv->sreg_proto_max],
|
||||
range.min_proto.all = (__force __be16)nft_reg_load16(
|
||||
®s->data[priv->sreg_proto_min]);
|
||||
range.max_proto.all = (__force __be16)nft_reg_load16(
|
||||
®s->data[priv->sreg_proto_max]);
|
||||
range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue