diff -uNr linux-2.4.31-orig/drivers/char/random.c linux-2.4.31-randpid/drivers/char/random.c --- linux-2.4.31-orig/drivers/char/random.c 2004-02-18 14:36:31.000000000 +0100 +++ linux-2.4.31-randpid/drivers/char/random.c 2004-08-10 15:48:08.000000000 +0200 @@ -394,6 +394,11 @@ static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); +char get_random_buffer_states(void) +{ + return (random_state != NULL) || (sec_random_state != NULL); +} + /* * Forward procedure declarations */ diff -uNr linux-2.4.31-orig/include/linux/net.h linux-2.4.31-randpid/include/linux/net.h --- linux-2.4.31-orig/include/linux/net.h 2003-11-28 19:26:21.000000000 +0100 +++ linux-2.4.31-randpid/include/linux/net.h 2004-08-10 15:48:08.000000000 +0200 @@ -146,6 +146,8 @@ extern unsigned long net_random(void); extern void net_srandom(unsigned long); +extern int create_tcp_port_number(void); /* FvH: create a random port-number */ + #ifndef CONFIG_SMP #define SOCKOPS_WRAPPED(name) name #define SOCKOPS_WRAP(name, fam) diff -uNr linux-2.4.31-orig/include/linux/random.h linux-2.4.31-randpid/include/linux/random.h --- linux-2.4.31-orig/include/linux/random.h 2000-01-25 23:13:46.000000000 +0100 +++ linux-2.4.31-randpid/include/linux/random.h 2004-08-10 15:48:08.000000000 +0200 @@ -7,6 +7,8 @@ #ifndef _LINUX_RANDOM_H #define _LINUX_RANDOM_H +char get_random_buffer_states(void); + #include /* ioctl()'s for the random number generator */ diff -uNr linux-2.4.31-orig/include/linux/sched.h linux-2.4.31-randpid/include/linux/sched.h --- linux-2.4.31-orig/include/linux/sched.h 2004-08-08 01:26:06.000000000 +0200 +++ linux-2.4.31-randpid/include/linux/sched.h 2004-08-10 15:48:08.000000000 +0200 @@ -417,6 +417,10 @@ void *journal_info; }; +#define NREMEMBER_PIDS 128 /* number of pids to remember to prevent to-soon-re-use */ +extern pid_t last_pids[NREMEMBER_PIDS]; +extern int cur_nremember_pids; /* number of pids in above array */ + /* * Per process flags */ diff -uNr linux-2.4.31-orig/kernel/exit.c linux-2.4.31-randpid/kernel/exit.c --- linux-2.4.31-orig/kernel/exit.c 2002-11-29 00:53:15.000000000 +0100 +++ linux-2.4.31-randpid/kernel/exit.c 2004-08-10 15:48:08.000000000 +0200 @@ -12,6 +12,7 @@ #include #include #include +#include #include #ifdef CONFIG_BSD_PROCESS_ACCT #include @@ -442,6 +443,11 @@ __exit_mm(tsk); lock_kernel(); + + /* add this pid to the list of recently used pids */ + last_pids[cur_nremember_pids++] = tsk -> pid; + cur_nremember_pids %= NREMEMBER_PIDS; + sem_exit(); __exit_files(tsk); __exit_fs(tsk); diff -uNr linux-2.4.31-orig/kernel/fork.c linux-2.4.31-randpid/kernel/fork.c --- linux-2.4.31-orig/kernel/fork.c 2004-04-14 15:05:40.000000000 +0200 +++ linux-2.4.31-randpid/kernel/fork.c 2004-08-10 15:48:08.000000000 +0200 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -84,63 +85,84 @@ /* Protects next_safe and last_pid. */ spinlock_t lastpid_lock = SPIN_LOCK_UNLOCKED; -static int get_pid(unsigned long flags) -{ - static int next_safe = PID_MAX; +/* array of pids to remember to prevent to-soon-re-use */ +pid_t last_pids[NREMEMBER_PIDS]; /* no need to initialize; in bss section which is 0x00'ed anyway */ +int cur_nremember_pids; /* number of pids in above array */ + + static int get_pid(unsigned long flags) + { struct task_struct *p; - int pid, beginpid; - + static int pid = 1, loop; + /* get_random_bytes() is performed through the following + * short-variable: that is because we want to use as less + * as possible bits and this be able to do the + * get_random_bytes(..., sizeof(...)): (..., 2) would + * work on little-endian, not on big-endian + */ + short temp_pid; + static char first_pid = 1, last_pid; + if (flags & CLONE_PID) return current->pid; spin_lock(&lastpid_lock); - beginpid = last_pid; - if((++last_pid) & 0xffff8000) { - last_pid = 300; /* Skip daemons etc. */ - goto inside; - } - if(last_pid >= next_safe) { -inside: - next_safe = PID_MAX; - read_lock(&tasklist_lock); - repeat: - for_each_task(p) { - if(p->pid == last_pid || - p->pgrp == last_pid || - p->tgid == last_pid || - p->session == last_pid) { - if(++last_pid >= next_safe) { - if(last_pid & 0xffff8000) - last_pid = 300; - next_safe = PID_MAX; - } - if(unlikely(last_pid == beginpid)) { - next_safe = 0; - goto nomorepids; - } - goto repeat; + + /* generate a PID number */ + loop: + if (first_pid) { /* first pid; must be '1' -> init=1 */ + first_pid = 0; + pid = 1; + } + else + { + temp_pid = pid; + + do { + if (get_random_buffer_states() == 0) { + temp_pid++; + } else { + get_random_bytes(&temp_pid, sizeof(temp_pid) +); } - if(p->pid > last_pid && next_safe > p->pid) - next_safe = p->pid; - if(p->pgrp > last_pid && next_safe > p->pgrp) - next_safe = p->pgrp; - if(p->tgid > last_pid && next_safe > p->tgid) - next_safe = p->tgid; - if(p->session > last_pid && next_safe > p->session) - next_safe = p->session; - } - read_unlock(&tasklist_lock); - } - pid = last_pid; - spin_unlock(&lastpid_lock); - return pid; + temp_pid &= 32767; + } while (temp_pid<2); + + pid = temp_pid; + } + + /* see if this pid was used recently */ + for(loop=0; loop abort and try again */ + if (p -> pid == pid || + p -> pgrp == pid || + p -> tgid == pid || + p -> session == pid) { + read_unlock(&tasklist_lock); + /* I've always learned: "thy shall not use goto" + * but, well, this one makes all code so much + * shorter + */ + goto loop; + } + } + + read_unlock(&tasklist_lock); + + spin_unlock(&lastpid_lock); -nomorepids: - read_unlock(&tasklist_lock); - spin_unlock(&lastpid_lock); - return 0; -} + return pid; + } static inline int dup_mmap(struct mm_struct * mm) { diff -uNr linux-2.4.31-orig/net/core/Makefile linux-2.4.31-randpid/net/core/Makefile --- linux-2.4.31-orig/net/core/Makefile 2004-08-08 01:26:06.000000000 +0200 +++ linux-2.4.31-randpid/net/core/Makefile 2004-08-10 15:49:37.000000000 +0200 @@ -9,7 +9,7 @@ O_TARGET := core.o -export-objs := netfilter.o profile.o ethtool.o neighbour.o +export-objs := netfilter.o profile.o ethtool.o neighbour.o utils.o obj-y := sock.o skbuff.o iovec.o datagram.o scm.o diff -uNr linux-2.4.31-orig/net/core/utils.c linux-2.4.31-randpid/net/core/utils.c --- linux-2.4.31-orig/net/core/utils.c 1999-08-23 19:01:02.000000000 +0200 +++ linux-2.4.31-randpid/net/core/utils.c 2004-08-10 15:48:09.000000000 +0200 @@ -25,14 +25,31 @@ unsigned long net_random(void) { - net_rand_seed=net_rand_seed*69069L+1; - return net_rand_seed^jiffies; + /* patch by FvH */ + get_random_bytes(&net_rand_seed, sizeof(net_rand_seed)); + + return net_rand_seed; } void net_srandom(unsigned long entropy) { + /* patch by FvH */ net_rand_seed ^= entropy; - net_random(); +} + +int create_tcp_port_number(void) +{ + int loop, rover; + + for(loop=0; loop<16; loop++) /* try at most 16 times, we do not want too much delay */ + { + rover = net_random(); + rover ^= (rover >> 16); + rover &= 65535; + if (rover > 1024) break; + } + + return rover; } int net_msg_cost = 5*HZ; diff -uNr linux-2.4.31-orig/net/ipv4/fib_semantics.c linux-2.4.31-randpid/net/ipv4/fib_semantics.c --- linux-2.4.31-orig/net/ipv4/fib_semantics.c 2003-08-25 13:44:44.000000000 +0200 +++ linux-2.4.31-randpid/net/ipv4/fib_semantics.c 2004-08-10 15:48:09.000000000 +0200 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -977,7 +978,8 @@ it is pretty bad approximation. */ - w = jiffies % fi->fib_power; + get_random_bytes(&w, sizeof(w)); + w %= fi->fib_power; change_nexthops(fi) { if (!(nh->nh_flags&RTNH_F_DEAD) && nh->nh_power) { diff -uNr linux-2.4.31-orig/net/ipv4/netfilter/ip_nat_core.c linux-2.4.31-randpid/net/ipv4/netfilter/ip_nat_core.c --- linux-2.4.31-orig/net/ipv4/netfilter/ip_nat_core.c 2004-08-08 01:26:06.000000000 +0200 +++ linux-2.4.31-randpid/net/ipv4/netfilter/ip_nat_core.c 2004-08-10 15:48:09.000000000 +0200 @@ -288,6 +288,9 @@ explicit socket bindings, for example) */ orig_dstip = tuple->dst.ip; + /* patch by FvH */ + get_random_bytes(&randomness, sizeof(randomness)); + IP_NF_ASSERT(mr->rangesize >= 1); for (i = 0; i < mr->rangesize; i++) { /* Host order */ diff -uNr linux-2.4.31-orig/net/ipv4/tcp_ipv4.c linux-2.4.31-randpid/net/ipv4/tcp_ipv4.c --- linux-2.4.31-orig/net/ipv4/tcp_ipv4.c 2004-04-14 15:05:41.000000000 +0200 +++ linux-2.4.31-randpid/net/ipv4/tcp_ipv4.c 2004-08-10 15:48:09.000000000 +0200 @@ -219,10 +219,13 @@ int low = sysctl_local_port_range[0]; int high = sysctl_local_port_range[1]; int remaining = (high - low) + 1; - int rover; + int rover, loop; spin_lock(&tcp_portalloc_lock); - rover = tcp_port_rover; + +/* rover = tcp_port_rover; FvH patch starts here */ + rover = create_tcp_port_number(); /* ends here */ + do { rover++; if ((rover < low) || (rover > high)) rover = low; @@ -680,7 +683,8 @@ * memory pingpong. Any ideas how to do this in a nice way? */ spin_lock(&tcp_portalloc_lock); - rover = tcp_port_rover; +/* rover = tcp_port_rover; FvH patch starts here */ + rover = create_tcp_port_number(); /* ends here */ do { rover++; diff -uNr linux-2.4.31-orig/net/ipv6/tcp_ipv6.c linux-2.4.31-randpid/net/ipv6/tcp_ipv6.c --- linux-2.4.31-orig/net/ipv6/tcp_ipv6.c 2004-08-08 01:26:07.000000000 +0200 +++ linux-2.4.31-randpid/net/ipv6/tcp_ipv6.c 2004-08-10 15:48:09.000000000 +0200 @@ -104,7 +104,10 @@ int rover; spin_lock(&tcp_portalloc_lock); - rover = tcp_port_rover; + +/* rover = tcp_port_rover; FvH patch starts here */ + rover = create_tcp_port_number(); /* patch ends here */ + do { rover++; if ((rover < low) || (rover > high)) rover = low; diff -uNr linux-2.4.31-orig/net/ipx/af_spx.c linux-2.4.31-randpid/net/ipx/af_spx.c --- linux-2.4.31-orig/net/ipx/af_spx.c 2001-09-14 02:16:23.000000000 +0200 +++ linux-2.4.31-randpid/net/ipx/af_spx.c 2004-08-10 15:48:09.000000000 +0200 @@ -40,6 +40,7 @@ #include #include #include +#include static struct proto_ops *ipx_operations; static struct proto_ops spx_ops; @@ -916,7 +917,10 @@ { int error; +#if 0 connids = (__u16)jiffies; /* initalize random */ +#endif + get_random_bytes(&connids, sizeof(connids)); error = ipx_register_spx(&ipx_operations, &spx_family_ops); if (error) diff -uNr linux-2.4.31-orig/net/netsyms.c linux-2.4.31-randpid/net/netsyms.c --- linux-2.4.31-orig/net/netsyms.c 2004-08-08 01:26:07.000000000 +0200 +++ linux-2.4.31-randpid/net/netsyms.c 2004-08-10 15:48:09.000000000 +0200 @@ -628,3 +628,6 @@ #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */ #endif /* CONFIG_NET */ + +/* added by FvH */ +EXPORT_SYMBOL(create_tcp_port_number);