如何设置输入的约束?
假设我有以下结构,
type Hdr struct{
Src uint16
Dst uint16
Priotity byte
Pktcnt byte
Opcode byte
Ver byte
}
我有两个函数 Marshal
和 Unmarshal
,它们将 Hdr
编码为以下二进制格式:
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Src |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Dst |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Prio | Cnt | Opcode| Ver |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
我想使用 Go Fuzz 生成随机、有效的 Hdr
实例,Marshal
然后转换为二进制文件,Unmarshal
二进制文件并确保输出与原始输入匹配。
我遇到的主要问题是,我不知道如何告诉 Go Fuzz 像 Priority
这样的字段不能大于 15,否则它们在编组时会被截断(只有 4 位)。我如何设置这个约束?
更新
这只是一个玩具盒。很多时候,像上面这样的协议中,诸如操作码之类的东西会触发二次更复杂的解析/审查。模糊测试仍然可以在约束内发现非常有用的问题(即:如果 Prio 0x00
和 Cnt 0x2F
辅助解析器将出错,因为分隔符是 \
)。
Assume I have the following structure
type Hdr struct{
Src uint16
Dst uint16
Priotity byte
Pktcnt byte
Opcode byte
Ver byte
}
I have two functions Marshal
and Unmarshal
that encode Hdr
to and from a binary format of:
0 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Src |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Dst |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Prio | Cnt | Opcode| Ver |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
I'd like to use Go Fuzz to make random, valid Hdr
instances, Marshal
then to binary, Unmarshal
the binary and make sure the output matches the original input.
The main issue I am having is that I cannot figure out how to tell Go Fuzz that fields like Priotity
cannot be greater than 15 otherwise they will get truncated when they are marshalled (only 4 bits). How do I set this constraint?
Update
This is just a toy case. There are many times with protocols like the above where something like the opcode
would trigger secondary more complex parsing/vetting. Fuzzing could still find very useful issues within a constraint (IE: if Prio 0x00
and Cnt 0x2F
secondary parser will error because delimiter is \
).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
edit
我不确定在这里模糊是否合适。模糊旨在查找意外输入:多字节UTF8输入(有效和非valid);负值;巨大的价值,长度等。这些将试图捕获“边缘”案例。
在您的情况下,您知道:
unmarshal
输入有效载荷必须是6个字节(否则应发生错误),因此vanilla
testing.t
测试可能在这里更适合。保持简单。
如果您不想“浪费”模糊输入&您知道代码的输入约束,可以尝试类似的内容:
在您的测试中 - 可以测试强制值 - 或跳过(如@JCH所示):
EDIT
I'm not sure Fuzzing is a good fit here. Fuzzing is designed to find unexpected inputs: multi-byte UTF8 inputs (valid and non-valid); negative values; huge values, long lengths etc. These will try to catch "edge" cases.
In your case here, you know the:
Unmarshal
input payload must be 6 bytes (should error otherwise)so vanilla
testing.T
tests may be a better fit here.Keep it simple.
If you don't want to "waste" a Fuzz input & you know the input constraints of your code, you can try something like this:
and in your test - the coerced value can be tested - or skipped (as @jch showed):
为了跳过无趣的结果,请在模糊功能中调用
t.skip
。这样的事情:In order to skip uninteresting results, call
t.Skip
in your fuzzing function. Something like this: