#rng #fuzzing #generates-random #structure-aware

bufrng

一个生成 '随机' 数字并从给定缓冲区复制的 RNG。仅用于测试和模糊测试!!

3 个稳定版本

1.0.2 2019年10月17日
1.0.1 2019年8月30日

#16#generates-random

Download history 23/week @ 2024-03-28 13/week @ 2024-04-04 11/week @ 2024-06-20 79/week @ 2024-06-27

每月90 次下载

MIT/Apache

13KB

Build Status

bufrng

BufRng 是一个简单的“随机”数字生成器,从缓冲区中输出预先确定的值,并在缓冲区耗尽后输出 0

⚠⚠⚠

此 RNG 仅适用于测试和模糊测试!它不适用于密码学!它不适用于生成伪随机数!

⚠⚠⚠

为什么?

BufRng 对于将 libFuzzerAFL 的原始输入字节重新解释为结构感知测试用例生成器(例如,quickcheck::Arbitrary)的 RNG 很有用。这结合了覆盖率引导模糊测试与结构感知模糊测试的力量。

示例

假设我们正在开发一个可以将 RGB 和 HSL 颜色表示相互转换的 crate。

首先,我们可以为我们的颜色类型实现 quickcheck::Arbitrary 以获取结构感知测试用例生成器。然后,我们可以使用这些生成器与 quickcheck 自身的测试运行器基础设施一起使用,以断言代码的各种属性(例如,它永远不会崩溃,或者 RGB -> HSL -> RGB 是恒等函数),并且 quickcheck 将生成 RgbHsl 的随机实例以检查此属性。

/// A color represented with RGB.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Rgb {
    pub r: u8,
    pub g: u8,
    pub b: u8,
}

impl Rgb {
    pub fn to_hsl(&self) -> Hsl {
        // ...
    }
}

/// A color represented with HSL.
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Hsl {
    pub h: f64,
    pub s: f64,
    pub l: f64,
}

impl Hsl {
    pub fn to_rgb(&self) -> Rgb {
        // ...
    }
}

// Implementations of `quickcheck::Arbitrary` to create structure-aware test
// case generators for `Rgb` and `Hsl`.

use rand::prelude::*;
use quickcheck::{Arbitrary, Gen};

impl Arbitrary for Rgb {
    fn arbitrary<G: Gen>(g: &mut G) -> Self {
        Rgb {
            r: g.gen(),
            g: g.gen(),
            b: g.gen(),
        }
    }
}

impl Arbitrary for Hsl {
    fn arbitrary<G: Gen>(g: &mut G) -> Self {
        Hsl {
            h: g.gen_range(0.0, 360.0),
            s: g.gen_range(0.0, 1.0),
            l: g.gen_range(0.0, 1.0),
        }
    }
}

// Properties that we can have `quickcheck` assert for us.

pub fn rgb_to_hsl_doesnt_panic(rgb: Rgb) {
    let _ = rgb.to_hsl();
}

pub fn rgb_to_hsl_to_rgb_is_identity(rgb: Rgb) {
    assert_eq!(rgb, rgb.to_hsl().to_rgb());
}

#[cfg(test)]
mod tests {
    quickcheck::quickcheck! {
        fn rgb_to_hsl_doesnt_panic(rgb: Rgb) -> bool {
            super::rgb_to_hsl_doesnt_panic(rgb);
            true
        }
    }

    quickcheck::quickcheck! {
        fn rgb_to_hsl_to_rgb_is_identity(rgb: Rgb) -> bool {
            super::rgb_to_hsl_to_rgb_is_identity(rgb);
            true
        }
    }
}

最后,我们可以 重用 现有的结构感知测试用例生成器(Arbitrary 实现)与 BufRng 一起使用 libFuzzer 或 AFL 输入。因此,我们可以利用覆盖率引导模糊测试——模糊测试器在测试运行时观察代码覆盖率,并尝试最大化输入覆盖的路径——以及我们现有的结构感知生成器。

以下片段使用 cargo fuzz 和 libFuzzer,但概念同样适用于 AFL 等。

// my-rgb-to-hsl-crate/fuzz/fuzz_targets/rgb.rs

#![no_main]

#[macro_use]
extern crate libfuzzer_sys;

use bufrng::BufRng;
use my_rgb_to_hsl_crate::{rgb_to_hsl_doesnt_panic, rgb_to_hsl_to_rgb_is_identity, Rgb};
use quickcheck::Arbitrary;

fuzz_target!(|data: &[u8]| {
    // Create a `BufRng` from the raw data given to us by the fuzzer.
    let mut rng = BufRng::new(data);

    // Generate an `Rgb` instance with it.
    let rgb = Rgb::arbitrary(&mut rng);

    // Assert our properties!
    rgb_to_hsl_doesnt_panic(rgb);
    rgb_to_hsl_to_rgb_is_identity(rgb);
});

依赖项

~61KB