Skip to content

Commit 55f0fc7

Browse files
aksecuritygregkh
authored andcommitted
inet: update the IP ID generation algorithm to higher standards.
Commit 355b985 ("netns: provide pure entropy for net_hash_mix()") makes net_hash_mix() return a true 32 bits of entropy. When used in the IP ID generation algorithm, this has the effect of extending the IP ID generation key from 32 bits to 64 bits. However, net_hash_mix() is only used for IP ID generation starting with kernel version 4.1. Therefore, earlier kernels remain with 32-bit key no matter what the net_hash_mix() return value is. This change addresses the issue by explicitly extending the key to 64 bits for kernels older than 4.1. Signed-off-by: Amit Klein <aksecurity@gmail.com> Cc: Ben Hutchings <ben@decadent.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 8620392 commit 55f0fc7

File tree

2 files changed

+6
-1
lines changed

2 files changed

+6
-1
lines changed

Diff for: net/ipv4/route.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -488,13 +488,15 @@ EXPORT_SYMBOL(ip_idents_reserve);
488488
void __ip_select_ident(struct iphdr *iph, int segs)
489489
{
490490
static u32 ip_idents_hashrnd __read_mostly;
491+
static u32 ip_idents_hashrnd_extra __read_mostly;
491492
u32 hash, id;
492493

493494
net_get_random_once(&ip_idents_hashrnd, sizeof(ip_idents_hashrnd));
495+
net_get_random_once(&ip_idents_hashrnd_extra, sizeof(ip_idents_hashrnd_extra));
494496

495497
hash = jhash_3words((__force u32)iph->daddr,
496498
(__force u32)iph->saddr,
497-
iph->protocol,
499+
iph->protocol ^ ip_idents_hashrnd_extra,
498500
ip_idents_hashrnd);
499501
id = ip_idents_reserve(hash, segs);
500502
iph->id = htons(id);

Diff for: net/ipv6/ip6_output.c

+3
Original file line numberDiff line numberDiff line change
@@ -546,12 +546,15 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
546546
static void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
547547
{
548548
static u32 ip6_idents_hashrnd __read_mostly;
549+
static u32 ip6_idents_hashrnd_extra __read_mostly;
549550
u32 hash, id;
550551

551552
net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd));
553+
net_get_random_once(&ip6_idents_hashrnd_extra, sizeof(ip6_idents_hashrnd_extra));
552554

553555
hash = __ipv6_addr_jhash(&rt->rt6i_dst.addr, ip6_idents_hashrnd);
554556
hash = __ipv6_addr_jhash(&rt->rt6i_src.addr, hash);
557+
hash = jhash_1word(hash, ip6_idents_hashrnd_extra);
555558

556559
id = ip_idents_reserve(hash, 1);
557560
fhdr->identification = htonl(id);

0 commit comments

Comments
 (0)