netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] ip: make IP identifiers less predictable
@ 2014-07-24  8:07 Eric Dumazet
  2014-07-24 18:21 ` Linus Torvalds
  2014-07-25 19:50 ` [PATCH v2 " Eric Dumazet
  0 siblings, 2 replies; 17+ messages in thread
From: Eric Dumazet @ 2014-07-24  8:07 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, Jeffrey Knockel, Jedidiah R. Crandall, Linus Torvalds,
	Willy Tarreau, security

From: Eric Dumazet <edumazet@google.com>

In "Counting Packets Sent Between Arbitrary Internet Hosts", Jeffrey and
Jedidiah describe ways exploiting linux IP identifier generation to
infer whether two machines are exchanging packets.

With commit 73f156a6e8c1 ("inetpeer: get rid of ip_id_count"), we
changed IP id generation, but this does not really prevent this
side-channel technique.

This patch adds a random amount of perturbation so that IP identifiers
for a given destination [1] are no longer monotonically increasing after
an idle period.

Note that prandom_u32_max(1) returns 0, so if generator is used at most
once per jiffy, this patch inserts no hole in the ID suite and do not
increase collision probability.

This is jiffies based, so in the worst case (HZ=1000), the id can
rollover after ~65 seconds of idle time, which should be fine.

If I ping the patched target, we can see ID are now hard to predict.

21:57:11.008086 IP (...)
    A > target: ICMP echo request, seq 1, length 64
21:57:11.010752 IP (... id 2081 ...)
    target > A: ICMP echo reply, seq 1, length 64

21:57:12.013133 IP (...)
    A > target: ICMP echo request, seq 2, length 64
21:57:12.015737 IP (... id 3039 ...)
    target > A: ICMP echo reply, seq 2, length 64

21:57:13.016580 IP (...)
    A > target: ICMP echo request, seq 3, length 64
21:57:13.019251 IP (... id 3437 ...)
    target > A: ICMP echo reply, seq 3, length 64

[1] TCP sessions uses a per flow ID generator not changed by this patch.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: Jeffrey Knockel <jeffk@cs.unm.edu>
Reported-by: Jedidiah R. Crandall <crandall@cs.unm.edu>
Cc: Willy Tarreau <w@1wt.eu>
---
 include/net/ip.h |   11 +----------
 net/ipv4/route.c |   27 +++++++++++++++++++++++++--
 2 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/include/net/ip.h b/include/net/ip.h
index 0e795df05ec9..7596eb22e1ce 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -309,16 +309,7 @@ static inline unsigned int ip_skb_dst_mtu(const struct sk_buff *skb)
 	}
 }
 
-#define IP_IDENTS_SZ 2048u
-extern atomic_t *ip_idents;
-
-static inline u32 ip_idents_reserve(u32 hash, int segs)
-{
-	atomic_t *id_ptr = ip_idents + hash % IP_IDENTS_SZ;
-
-	return atomic_add_return(segs, id_ptr) - segs;
-}
-
+u32 ip_idents_reserve(u32 hash, int segs);
 void __ip_select_ident(struct iphdr *iph, int segs);
 
 static inline void ip_select_ident_segs(struct sk_buff *skb, struct sock *sk, int segs)
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 3162ea923ded..2e9713a8966f 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -457,8 +457,31 @@ static struct neighbour *ipv4_neigh_lookup(const struct dst_entry *dst,
 	return neigh_create(&arp_tbl, pkey, dev);
 }
 
-atomic_t *ip_idents __read_mostly;
-EXPORT_SYMBOL(ip_idents);
+#define IP_IDENTS_SZ 2048u
+struct ip_ident_bucket {
+	atomic_t	id;
+	u32		stamp32;
+};
+
+static struct ip_ident_bucket *ip_idents __read_mostly;
+
+/* In order to protect privacy, we add a perturbation to identifiers
+ * if one generator is seldom used. This makes hard for an attacker
+ * to infer how many packets were sent between two hosts.
+ */
+u32 ip_idents_reserve(u32 hash, int segs)
+{
+	struct ip_ident_bucket *bucket = ip_idents + hash % IP_IDENTS_SZ;
+	u32 old = ACCESS_ONCE(bucket->stamp32);
+	u32 now = (u32)jiffies;
+	u32 delta = 0;
+
+	if (old != now && cmpxchg(&bucket->stamp32, old, now) == old)
+		delta = prandom_u32_max(now - old);
+
+	return atomic_add_return(segs + delta, &bucket->id) - segs;
+}
+EXPORT_SYMBOL(ip_idents_reserve);
 
 void __ip_select_ident(struct iphdr *iph, int segs)
 {

^ permalink raw reply related	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2014-07-29  1:47 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-07-24  8:07 [PATCH net] ip: make IP identifiers less predictable Eric Dumazet
2014-07-24 18:21 ` Linus Torvalds
2014-07-25 15:55   ` Jeffrey Knockel
2014-07-25 18:09     ` Eric Dumazet
2014-07-25 18:35       ` Linus Torvalds
2014-07-25 18:38         ` Eric Dumazet
2014-07-25 19:03           ` Willy Tarreau
2014-07-25 23:05           ` Hannes Frederic Sowa
2014-07-25 20:28       ` Jeffrey Knockel
2014-07-25 19:50 ` [PATCH v2 " Eric Dumazet
2014-07-25 19:54   ` Eric Dumazet
2014-07-25 19:57     ` Eric Dumazet
2014-07-25 22:35   ` Hannes Frederic Sowa
2014-07-26  6:51     ` Eric Dumazet
2014-07-26 12:21       ` Hannes Frederic Sowa
2014-07-26  6:58   ` [PATCH v3 " Eric Dumazet
2014-07-29  1:47     ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).