Re: 2.2.0 wishlist

Theodore Y. Ts'o (tytso@mit.edu)
Fri, 14 Jun 1996 14:06:02 -0400


From: Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>
Date: Thu, 13 Jun 1996 18:17:16 +0200 (MET DST)

* Secure TCP sequence numbers (the random driver has some code
for that which doesn't seem to be used anywhere at the moment)

It was too late to put such a change into 2.0. Here's the patch for
those people who want to play with it....

- Ted

--- include/net/tcp.h 1996/06/07 00:25:18 1.1
+++ include/net/tcp.h 1996/06/07 01:33:02
@@ -174,22 +174,6 @@
extern void tcp_delack_timer(unsigned long);
extern void tcp_retransmit_timer(unsigned long);

-/*
- * Default sequence number picking algorithm.
- * As close as possible to RFC 793, which
- * suggests using a 250kHz clock.
- * Further reading shows this assumes 2MB/s networks.
- * For 10MB/s ethernet, a 1MHz clock is appropriate.
- * That's funny, Linux has one built in! Use it!
- */
-
-static inline u32 tcp_init_seq(void)
-{
- struct timeval tv;
- do_gettimeofday(&tv);
- return tv.tv_usec+tv.tv_sec*1000000;
-}
-
static __inline__ int tcp_old_window(struct sock * sk)
{
return sk->window - (sk->acked_seq - sk->lastwin_seq);
--- net/ipv4/tcp.c 1996/06/07 00:25:18 1.1
+++ net/ipv4/tcp.c 1996/06/07 00:25:21
@@ -202,6 +202,7 @@
* improvement.
* Stefan Magdalinski : adjusted tcp_readable() to fix FIONREAD
* Willy Konynenberg : Transparent proxying support.
+ * Theodore Ts'o : Do secure TCP sequence numbers.
*
* To Fix:
* Fast path the code. Two things here - fix the window calculation
@@ -427,6 +428,7 @@
#include <linux/config.h>
#include <linux/types.h>
#include <linux/fcntl.h>
+#include <linux/random.h>

#include <net/icmp.h>
#include <net/tcp.h>
@@ -1905,25 +1907,20 @@

lock_sock(sk);
sk->daddr = usin->sin_addr.s_addr;
- sk->write_seq = tcp_init_seq();
- sk->window_seq = sk->write_seq;
- sk->rcv_ack_seq = sk->write_seq -1;
+
sk->rcv_ack_cnt = 1;
sk->err = 0;
sk->dummy_th.dest = usin->sin_port;
- release_sock(sk);

buff = sock_wmalloc(sk,MAX_SYN_SIZE,0, GFP_KERNEL);
if (buff == NULL)
{
return(-ENOMEM);
}
- lock_sock(sk);
buff->sk = sk;
buff->free = 0;
buff->localroute = sk->localroute;

-
/*
* Put in the IP header and routing stuff.
*/
@@ -1939,6 +1936,15 @@
if ((rt = sk->ip_route_cache) != NULL && !sk->saddr)
sk->saddr = rt->rt_src;
sk->rcv_saddr = sk->saddr;
+
+ /*
+ * Set up our outgoing TCP sequence number
+ */
+ sk->write_seq = secure_tcp_sequence_number(sk->saddr, sk->daddr,
+ sk->dummy_th.source,
+ usin->sin_port);
+ sk->window_seq = sk->write_seq;
+ sk->rcv_ack_seq = sk->write_seq -1;

t1 = (struct tcphdr *) skb_put(buff,sizeof(struct tcphdr));

--- net/ipv4/tcp_input.c 1996/06/07 00:25:18 1.1
+++ net/ipv4/tcp_input.c 1996/06/07 00:25:21
@@ -28,9 +28,12 @@
* Eric Schenk : Skip fast retransmit on small windows.
* Eric schenk : Fixes to retransmission code to
* : avoid extra retransmission.
+ * Theodore Ts'o : Do secure TCP sequence numbers.
*/

#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/random.h>
#include <net/tcp.h>

/*
@@ -1687,6 +1690,7 @@
struct tcphdr *th;
struct sock *sk;
int syn_ok=0;
+ __u32 seq;
#ifdef CONFIG_IP_TRANSPARENT_PROXY
int r;
#endif
@@ -1824,10 +1828,12 @@
}

/*
- * Guess we need to make a new socket up
+ * Guess we need to make a new socket up
*/
-
- tcp_conn_request(sk, skb, daddr, saddr, opt, dev, tcp_init_seq());
+ seq = secure_tcp_sequence_number(saddr, daddr,
+ skb->h.th->dest,
+ skb->h.th->source);
+ tcp_conn_request(sk, skb, daddr, saddr, opt, dev, seq);

/*
* Now we have several options: In theory there is nothing else