$ echo "TnNcAALv////Ua2t" | base64 --decode > script.crash
$ FUZZ=script src/test/fuzz/fuzz script.crash
fuzz: test/fuzz/script.cpp:87: void script_fuzz_target(FuzzBufferType): Assertion `!extract_destination_ret' failed.
fuzz: `script`: Assertion `!extract_destination_ret' failed. #30615
issue dergoegge opened this issue on August 9, 2024-
dergoegge commented at 8:01 AM on August 9, 2024: member
-
dergoegge commented at 8:03 AM on August 9, 2024: member
This looks P2A related (#30352).
-
ismaelsadeeq commented at 9:28 AM on August 9, 2024: member
Yes I think it is, I've bisected and it starts crashing on 455fca86cfada1823aa28615b5683f9dc73dbb9a
IIUC I dont think we should
assertthatExtractDestinationwill return false after parsing aCScriptofTxoutType::ANCHORtype.It returns true.
So I think we should not
assertfor that?<details> <summary>diff</summary>
diff --git a/src/test/fuzz/script.cpp b/src/test/fuzz/script.cpp index a23543d70ec..07a49e039fb 100644 --- a/src/test/fuzz/script.cpp +++ b/src/test/fuzz/script.cpp @@ -76,13 +76,11 @@ FUZZ_TARGET(script, .init = initialize_script) assert(which_type == TxoutType::PUBKEY || which_type == TxoutType::NONSTANDARD || which_type == TxoutType::NULL_DATA || - which_type == TxoutType::MULTISIG || - which_type == TxoutType::ANCHOR); + which_type == TxoutType::MULTISIG); } if (which_type == TxoutType::NONSTANDARD || which_type == TxoutType::NULL_DATA || - which_type == TxoutType::MULTISIG || - which_type == TxoutType::ANCHOR) { + which_type == TxoutType::MULTISIG) { assert(!extract_destination_ret); }</details>
- fanquake added this to the milestone 28.0 on Aug 9, 2024
- maflcko added the label Tests on Aug 9, 2024
-
maflcko commented at 10:37 AM on August 10, 2024: member
About how easy it is for the fuzz engine to find this bug: This is trivial to find in libFuzzer with a small enough max_len and value profile ( for example,
-use_value_profile=1 -max_len=24). However, absent that, it seems harder to find on a quick test.There are no hashes involved here, so in theory symbolic execution should also be able to find this quickly?
Would be fun to use this example for some fuzz benchmarks/evaluation. cc @dergoegge @agroce @murchandamus
-
agroce commented at 4:31 PM on August 10, 2024: contributor
This actually leads to a q I was wondering about for OSS-Fuzz: are there configs for appropriate targets with smaller max-lens?
-
dergoegge commented at 8:13 AM on August 12, 2024: member
fwiw, I found this using afl++ and libfuzzer in parallel in ~16h CPU hours. The original input is much larger, but I minimized it for this issue:
TnNzc3NzknNzc3Nzc3Nzc3NzUXNzc3Nzc3NzcnNzc3Nzc3Nzc3Nzc3Nzc3Nzc3MAAAAAgPlzc3Nzc3NEY1wAAAAAgAEBAYABAfogAAAAc3Nzc3Nzc3Nzc3Nzc3NzbHNzc3Nzc3Jzc3//c3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3N3c3Nzc3NzRAFc/wEBAYABAQGAAQH6AS8vLy8vLy8vLy8vEi9/AC8vLy8vLy8vLy8vc3NWc3Nzc3NzlHNfc3Nzc3Pe3iHe3t7e3t7e3t7ec3NBQQCeW1yfn5+fn5+fn59cXFxcXFxcXV1cQZ+fc3Nzc3hzc3Nzc0QBXP8BAQGAAQEBgAEB+gEvLy8vLy8vLy9CLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vb0FBQUFbdVteW1u3W1tb6Fw1AAAAf/9cXABcXFwAAF1cu1xmW1xcXDk5AxC+AVzBXB0xMTExMTExMTExMTH//wAB/zsh/7D/sFZcc3Nzc3Nzc3Nzc3Nzc3NydHNzc3Nzc1xcXFxvXAAAAAAAAHNzc3Nzc3Nzc3Nzc3Nzc3N3c3Nzc3NzRAFzc3Nzc3Nzc0QBXP8BAQGAAQEBgAEB+gEvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vb0FBQUFbdVteW1vOW1tb6EJCQnNEAVwAAAAAgAEBAYABAfpzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Jzc3//c3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3N3c3Nzc3NzRAFc/wEBAYABAVwuXP8D6Fw1XH1cXFxBQUBhPlxAAHhBAOzu////Ua2tLy8vLy8vLy8vLy9vQUFBQVt1W15bXKdbW1voXDVcAQGAAQH6AS8vLy8vLy8vLy8vEi9/AC8vLy8vLy8vLy8vc3NWc3Nzc3NzlHRfc3Nzc3Pe3t7e3t7e3t7e3t7ec3NBQQCeW1yfn5+fn5+fn59cXFxcXFxcXV1cQZ+fc3Nzc3hzc3Nzc0QBXP8BAQGAAQEBgAEB+gEvLy8vLy8vLy9CLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vb0FBQUFbdVteW1u3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t7e3t1tbW+hcNVx9XCcE/xxcIx4AAAAAIwA6AHkBLy8vL1zBXAFcwVwdMTExMTExMTExMTEx//8AAf87If+w/7BWXHNzc3Nzc3Nzc3Nzc3NzcnNzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3Nzc3NEAVz/AQEBgAEBAVxCQuLj4uLi4uLi4kJCQUFteQAx9QH1eXr1ARAAAVwuXP8D6Fw1XH1cXFxBQUBhPlxAAHhBAOzu////Ua2tLy8vLy8vLy8vLy9vQUFBQVt1W15bXKdbW1voXDVcfVxcXEFBQGE+XEAAaEEAAtH///8BgAEB+gEBEAABXC5c/wPoXDVcfVxcXEFBZGE+XEAAeEEAAu////9Rra0=This actually leads to a q I was wondering about for OSS-Fuzz: are there configs for appropriate targets with smaller max-lens?
Not on oss-fuzz directly. I think we have a few harnesses that exit early if the input size is smaller or larger than expected, e.g.:
- glozow closed this on Aug 12, 2024
- glozow referenced this in commit 257a4fda3c on Aug 12, 2024
-
agroce commented at 11:22 AM on August 12, 2024: contributor
I think we have a few harnesses that exit early if the input size is smaller or larger than expected, e.g.:
Not sure the equivalent in AFL++, but in libFuzzer (and Eclipser) for some targets really limiting the size of input gives the mutator a much better chance at finding lots of things. This is a good example of very different time-to-find depending on max_len. It might be a good idea to either add a (rare) config for targets with some appropriate "very short but long enough to be interesting" lengths or at least run such outside OSS-Fuzz occasionally. I don't remember what libFuzzer does with corpus entries over max_len... Or maybe try len_control runs?
-
agroce commented at 3:44 PM on August 12, 2024: contributor
Actually, looks like the random_max_len (which could be small enough) strategy is enabled 15% of the time in the OSS-Fuzz config anyway.
-
agroce commented at 3:45 PM on August 12, 2024: contributor
-
agroce commented at 3:48 PM on August 12, 2024: contributor
.... though that's a random uniform value between 1 and 10000, so at 15% (which is of runs?) I'm not sure how often you'll ever see any target hit with a particularly small max_len. it'll happen, but perhaps quite infrequently if there are targets that benefit substantially from small string runs
-
agroce commented at 5:31 PM on August 12, 2024: contributor
Each target will spend < 0.15% of the time with a length of 100 or below, so not much low-max_len fuzzing happening I guess.
-
agroce commented at 8:55 PM on August 12, 2024: contributor
This is trivial to find in libFuzzer with a small enough max_len and value profile ( for example, -use_value_profile=1 -max_len=24).
How trivial is trivial? I have a set up that can definitely find it, and that setting is taking quite some time...
-
agroce commented at 4:43 PM on August 13, 2024: contributor
I got about 20 hours to find running libfuzzer with value profile + length 50, starting from every corpus entry that's 50 or less (seeing if throwing out longer corpus entries is better than truncating, for this kind of thing)
-
agroce commented at 4:43 PM on August 13, 2024: contributor
None of my other configs have found it yet...
-
agroce commented at 12:53 AM on August 15, 2024: contributor
@maflcko @dergoegge this is actually a question worth trying muttfuzz on: I think clearly full suite / max len fuzzing kills more mutants. but I can see how big the cost is for max len 50 runs, and how common mutants that are much easier to detect with short inputs only are. that might be worth seeing, since the gap in detection time here does seem to be huge (I have many finds with 50 length corpus/max_len, some in less than 10 minutes, and the original run with full corpus/no limit is still running after days)
- bitcoin locked this on Aug 15, 2025
Milestone
28.0