Skip to content

Commit c301f09

Browse files
Dan Carpenterummakynes
authored andcommitted
netfilter: nf_tables: fix pointer math issue in nft_byteorder_eval()
The problem is in nft_byteorder_eval() where we are iterating through a loop and writing to dst[0], dst[1], dst[2] and so on... On each iteration we are writing 8 bytes. But dst[] is an array of u32 so each element only has space for 4 bytes. That means that every iteration overwrites part of the previous element. I spotted this bug while reviewing commit caf3ef7 ("netfilter: nf_tables: prevent OOB access in nft_byteorder_eval") which is a related issue. I think that the reason we have not detected this bug in testing is that most of time we only write one element. Fixes: ce1e798 ("netfilter: nft_byteorder: provide 64bit le/be conversion") Signed-off-by: Dan Carpenter <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent a44af08 commit c301f09

File tree

3 files changed

+6
-5
lines changed

3 files changed

+6
-5
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -178,9 +178,9 @@ static inline __be32 nft_reg_load_be32(const u32 *sreg)
178178
return *(__force __be32 *)sreg;
179179
}
180180

181-
static inline void nft_reg_store64(u32 *dreg, u64 val)
181+
static inline void nft_reg_store64(u64 *dreg, u64 val)
182182
{
183-
put_unaligned(val, (u64 *)dreg);
183+
put_unaligned(val, dreg);
184184
}
185185

186186
static inline u64 nft_reg_load64(const u32 *sreg)

net/netfilter/nft_byteorder.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,22 @@ void nft_byteorder_eval(const struct nft_expr *expr,
3838

3939
switch (priv->size) {
4040
case 8: {
41+
u64 *dst64 = (void *)dst;
4142
u64 src64;
4243

4344
switch (priv->op) {
4445
case NFT_BYTEORDER_NTOH:
4546
for (i = 0; i < priv->len / 8; i++) {
4647
src64 = nft_reg_load64(&src[i]);
47-
nft_reg_store64(&dst[i],
48+
nft_reg_store64(&dst64[i],
4849
be64_to_cpu((__force __be64)src64));
4950
}
5051
break;
5152
case NFT_BYTEORDER_HTON:
5253
for (i = 0; i < priv->len / 8; i++) {
5354
src64 = (__force __u64)
5455
cpu_to_be64(nft_reg_load64(&src[i]));
55-
nft_reg_store64(&dst[i], src64);
56+
nft_reg_store64(&dst64[i], src64);
5657
}
5758
break;
5859
}

net/netfilter/nft_meta.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ nft_meta_get_eval_time(enum nft_meta_keys key,
6363
{
6464
switch (key) {
6565
case NFT_META_TIME_NS:
66-
nft_reg_store64(dest, ktime_get_real_ns());
66+
nft_reg_store64((u64 *)dest, ktime_get_real_ns());
6767
break;
6868
case NFT_META_TIME_DAY:
6969
nft_reg_store8(dest, nft_meta_weekday());

0 commit comments

Comments
 (0)