Merge to Fedora Core 2 kernel-2.6.8-1.521
[linux-2.6.git] / drivers / char / random.c
index f51b541..a261179 100644 (file)
@@ -822,6 +822,11 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
        } else {
                time = jiffies;
        }
+#elif defined (__sparc_v9__)
+       unsigned long tick = tick_ops->get_tick();
+
+       time = (unsigned int) tick;
+       num ^= (tick >> 32UL);
 #else
        time = jiffies;
 #endif
@@ -1894,13 +1899,13 @@ static int change_poolsize(int poolsize)
 }
 
 static int proc_do_poolsize(ctl_table *table, int write, struct file *filp,
-                           void __user *buffer, size_t *lenp)
+                           void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        int     ret;
 
        sysctl_poolsize = random_state->poolinfo.POOLBYTES;
 
-       ret = proc_dointvec(table, write, filp, buffer, lenp);
+       ret = proc_dointvec(table, write, filp, buffer, lenp, ppos);
        if (ret || !write ||
            (sysctl_poolsize == random_state->poolinfo.POOLBYTES))
                return ret;
@@ -1945,7 +1950,7 @@ static int poolsize_strategy(ctl_table *table, int __user *name, int nlen,
  * sysctl system call, it is returned as 16 bytes of binary data.
  */
 static int proc_do_uuid(ctl_table *table, int write, struct file *filp,
-                       void __user *buffer, size_t *lenp)
+                       void __user *buffer, size_t *lenp, loff_t *ppos)
 {
        ctl_table       fake_table;
        unsigned char   buf[64], tmp_uuid[16], *uuid;
@@ -1967,7 +1972,7 @@ static int proc_do_uuid(ctl_table *table, int write, struct file *filp,
        fake_table.data = buf;
        fake_table.maxlen = sizeof(buf);
 
-       return proc_dostring(&fake_table, write, filp, buffer, lenp);
+       return proc_dostring(&fake_table, write, filp, buffer, lenp, ppos);
 }
 
 static int uuid_strategy(ctl_table *table, int __user *name, int nlen,
@@ -2478,3 +2483,36 @@ __u32 check_tcp_syn_cookie(__u32 cookie, __u32 saddr, __u32 daddr, __u16 sport,
        return (cookie - tmp[17]) & COOKIEMASK; /* Leaving the data behind */
 }
 #endif
+
+/*
+ * Get a random word:
+ */
+unsigned int get_random_int(void)
+{
+       unsigned int val = 0;
+
+       if (!exec_shield_randomize)
+               return 0;
+
+#ifdef CONFIG_X86_HAS_TSC
+       rdtscl(val);
+#endif
+       val += current->pid + jiffies + (int)&val;
+
+       /*
+        * Use IP's RNG. It suits our purpose perfectly: it re-keys itself
+        * every second, from the entropy pool (and thus creates a limited
+        * drain on it), and uses halfMD4Transform within the second. We
+        * also spice it with the TSC (if available), jiffies, PID and the
+        * stack address:
+        */
+       return secure_ip_id(val);
+}
+
+unsigned long randomize_range(unsigned long start, unsigned long end, unsigned long len)
+{
+       unsigned long range = end - len - start;
+       if (end <= start + len)
+               return 0;
+       return PAGE_ALIGN(get_random_int() % range + start);
+}