【问题标题】:ASLR affected by entropy available on Linux?ASLR 受 Linux 上可用熵的影响?
【发布时间】:2013-03-07 12:44:20
【问题描述】:

random.c 的内核源代码中提到,get_random_int 是“类似于 urandom,但目标是最小化熵池耗尽”。但是,get_random_int 在哪里(以及如何)与熵池交互?

现在,urandom 实际上调用了extract_entropy_user,但我在get_random_int 中看不到任何类似的东西。 get_random_int 似乎使用了自己的熵源(与键盘、鼠标和磁盘活动无关):

hash[0] += current->pid + jiffies + get_cycles();

并且通常不关心(也不更新)系统可用的熵状态?

get_random_int 如何耗尽熵池?这是在哪里更新的?我知道我遗漏了一些东西或读取了错误的源代码,因为当我执行一个程序时,我可以通过在 entropy_avail 上执行 cat 来查看它是如何耗尽熵池的。

我查看了http://xorl.wordpress.com/2011/01/16/linux-kernel-aslr-implementation/,但似乎没有提到它是如何工作的。

【问题讨论】:

    标签: linux entropy aslr


    【解决方案1】:

    据我所知,它不会直接耗尽熵池。它只是返回一个低质量的随机数。它取决于 ISN seq 生成使用的秘密哈希(定期刷新)、它自己的 per-cpu 状态以及 pid/time/cycles。

    它与urandom的相似之处主要在于它在熵低时不会阻塞。

    【讨论】:

    • 有趣,那为什么我在重复 cat 文件时观察到 entropy_avail 下降?
    • 如果我不得不猜测,我会说这是因为rekey_seq_generator(),它被定期调用(并设置上述哈希),它使用get_random_bytes(),它确实使用了熵池。
    • 再想一想,这似乎是一个错误的猜测,因为重新生成密钥的间隔是(300 * HZ)。无论如何,我看不到任何直接消耗熵的东西
    • 你能重现我观察到熵被耗尽的行为吗?我杀死了大多数正在运行的进程,进行查找以确保熵很高,然后我 cat /proc/sys/kernel/entropy_avail 并看到每次执行 cat 时这个数字都会减少。
    【解决方案2】:

    hash[0] 还与名为 random_int_secret 的哈希混合在一起,该哈希仅在启动时由函数 random_int_secret_init() 生成一次。它是使用get_random_bytes() 生成的,它确实耗尽了熵估计。

    从 drivers/char/random.c 中定义了一个函数,该函数将生成这个一次性哈希,每次请求随机 int 时都会重复使用该哈希:

    static u32 random_int_secret[MD5_MESSAGE_BYTES / 4];
    int random_int_secret_init(void)
    {
        get_random_bytes(random_int_secret, sizeof(random_int_secret)); /* XXX */
        return 0;
    }
    

    在函数get_random_int() 中,random_int_secrethash 混合在一起,然后hash[0] 作为被请求的随机整数返回。

    static DEFINE_PER_CPU(__u32 [MD5_DIGEST_WORDS], get_random_int_hash);
    unsigned int get_random_int(void)
    {
        __u32 *hash;
        unsigned int ret;
    
        if (arch_get_random_int(&ret))
            return ret;
    
        hash = get_cpu_var(get_random_int_hash);
    
        hash[0] += current->pid + jiffies + random_get_entropy();
        md5_transform(hash, random_int_secret); /* XXX */
        ret = hash[0];
        put_cpu_var(get_random_int_hash);
    
        return ret;
    }
    EXPORT_SYMBOL(get_random_int);
    

    就在启动过程的开始,在 init/main.c 中,生成了这个种子:

    static void __init do_basic_setup(void)
    {
        cpuset_init_smp();
        shmem_init();
        driver_init();
        init_irq_proc();
        do_ctors();
        usermodehelper_enable();
        do_initcalls();
        random_int_secret_init(); /* XXX */
    }
    

    关于猫耗尽游泳池,我曾经记得它为什么这样做,但我现在不记得了。但是我很确定它不是 ASLR,因为在带有 RDRAND 的系统上,get_random_int() 仅提供指令中的整数,而没有其他内容。我的系统有 RDRAND,我还看到生成进程时熵计数下降。

    【讨论】:

      猜你喜欢
      • 2016-06-26
      • 2012-11-29
      • 2012-09-25
      • 1970-01-01
      • 2016-10-29
      • 1970-01-01
      • 2012-04-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多