ruzzy 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/cruzzy/cruzzy.c +6 -6
- data/ext/cruzzy/extconf.rb +3 -0
- data/ext/dummy/dummy.c +11 -10
- data/lib/ruzzy.rb +21 -6
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 64fa385ff3dca5a231ebc02511f7240143838b4cf4314a8ced35a57127ac2dc2
|
4
|
+
data.tar.gz: 1cd94db1a0b30debdc03caddf39394b3759b11f85d0b2ef78037e5769b0761ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed77800fbbe359a7b2be3e215b00d052b2bf8f1038da0e2ad88c6a8ea9d66bcf2d875ed5658592262ef35a18a23c4b1f5fcc9d44e7f669fc81817310dda96122
|
7
|
+
data.tar.gz: 80ef311558dd4c4aa88697014e08a6b06a164d182a16d5c4718ce9355bc6b2f82c52bce11d3eaa1d1071df2a900eef9ef46148013ad7099ed1fbf07df173b6c3
|
data/ext/cruzzy/cruzzy.c
CHANGED
@@ -194,11 +194,11 @@ static void event_hook_branch(VALUE counter_hash, rb_trace_arg_t *tracearg) {
|
|
194
194
|
|
195
195
|
static void enable_branch_coverage_hooks()
|
196
196
|
{
|
197
|
-
// Call Coverage.
|
197
|
+
// Call Coverage.start(branches: true) to activate branch coverage hooks.
|
198
198
|
// Branch coverage hooks will not be activated without this call despite
|
199
199
|
// adding the event hooks. I suspect rb_set_coverages must be called
|
200
200
|
// first, which initializes some global state that we do not have direct
|
201
|
-
// access to. Calling
|
201
|
+
// access to. Calling start initializes coverage state here:
|
202
202
|
// https://github.com/ruby/ruby/blob/v3_3_0/ext/coverage/coverage.c#L112-L120
|
203
203
|
// If rb_set_coverages is not called, then rb_get_coverages returns a NULL
|
204
204
|
// pointer, which appears to effectively disable coverage collection here:
|
@@ -207,10 +207,10 @@ static void enable_branch_coverage_hooks()
|
|
207
207
|
VALUE coverage_mod = rb_const_get(rb_cObject, rb_intern("Coverage"));
|
208
208
|
VALUE hash_arg = rb_hash_new();
|
209
209
|
rb_hash_aset(hash_arg, ID2SYM(rb_intern("branches")), Qtrue);
|
210
|
-
rb_funcall(coverage_mod, rb_intern("
|
210
|
+
rb_funcall(coverage_mod, rb_intern("start"), 1, hash_arg);
|
211
211
|
}
|
212
212
|
|
213
|
-
static VALUE
|
213
|
+
static VALUE c_trace(VALUE self, VALUE harness_path)
|
214
214
|
{
|
215
215
|
VALUE counter_hash = rb_hash_new();
|
216
216
|
|
@@ -230,7 +230,7 @@ static VALUE c_trace_branch(VALUE self)
|
|
230
230
|
|
231
231
|
enable_branch_coverage_hooks();
|
232
232
|
|
233
|
-
return
|
233
|
+
return rb_require(StringValueCStr(harness_path));
|
234
234
|
}
|
235
235
|
|
236
236
|
void Init_cruzzy()
|
@@ -245,5 +245,5 @@ void Init_cruzzy()
|
|
245
245
|
rb_define_module_function(ruzzy, "c_libfuzzer_is_loaded", &c_libfuzzer_is_loaded, 0);
|
246
246
|
rb_define_module_function(ruzzy, "c_trace_cmp8", &c_trace_cmp8, 2);
|
247
247
|
rb_define_module_function(ruzzy, "c_trace_div8", &c_trace_div8, 1);
|
248
|
-
rb_define_module_function(ruzzy, "
|
248
|
+
rb_define_module_function(ruzzy, "c_trace", &c_trace, 1);
|
249
249
|
}
|
data/ext/cruzzy/extconf.rb
CHANGED
@@ -64,6 +64,7 @@ def merge_sanitizer_libfuzzer_lib(sanitizer_lib, fuzzer_no_main_lib, merged_outp
|
|
64
64
|
'-Wl,--no-whole-archive',
|
65
65
|
'-lpthread',
|
66
66
|
'-ldl',
|
67
|
+
'-lstdc++',
|
67
68
|
'-shared',
|
68
69
|
'-o',
|
69
70
|
merged_output
|
@@ -137,4 +138,6 @@ merge_sanitizer_libfuzzer_lib(
|
|
137
138
|
# For more information, see https://github.com/ruby/ruby/blob/master/lib/mkmf.rb.
|
138
139
|
$LOCAL_LIBS = fuzzer_no_main_lib
|
139
140
|
|
141
|
+
$LIBS << ' -lstdc++'
|
142
|
+
|
140
143
|
create_makefile('cruzzy/cruzzy')
|
data/ext/dummy/dummy.c
CHANGED
@@ -6,17 +6,18 @@
|
|
6
6
|
// https://llvm.org/docs/LibFuzzer.html#toy-example
|
7
7
|
static int _c_dummy_test_one_input(const uint8_t *data, size_t size)
|
8
8
|
{
|
9
|
-
char
|
9
|
+
volatile char boom = 'x';
|
10
10
|
|
11
|
-
if (size
|
12
|
-
if (
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
if (size == 2) {
|
12
|
+
if (data[0] == 'H') {
|
13
|
+
if (data[1] == 'I') {
|
14
|
+
// Intentional heap-use-after-free for testing purposes
|
15
|
+
char * volatile ptr = malloc(128);
|
16
|
+
ptr[0] = 'x';
|
17
|
+
free(ptr);
|
18
|
+
boom = ptr[0];
|
19
|
+
(void) boom;
|
20
|
+
}
|
20
21
|
}
|
21
22
|
}
|
22
23
|
|
data/lib/ruzzy.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'pathname'
|
4
4
|
|
5
|
-
# A Ruby C
|
5
|
+
# A coverage-guided fuzzer for pure Ruby code and Ruby C extensions
|
6
6
|
module Ruzzy
|
7
7
|
require 'cruzzy/cruzzy'
|
8
8
|
|
@@ -15,10 +15,6 @@ module Ruzzy
|
|
15
15
|
c_fuzz(test_one_input, args)
|
16
16
|
end
|
17
17
|
|
18
|
-
def dummy
|
19
|
-
fuzz(->(data) { Ruzzy.dummy_test_one_input(data) })
|
20
|
-
end
|
21
|
-
|
22
18
|
def dummy_test_one_input(data)
|
23
19
|
# This 'require' depends on LD_PRELOAD, so it's placed inside the function
|
24
20
|
# scope. This allows us to access EXT_PATH for LD_PRELOAD and not have a
|
@@ -28,9 +24,28 @@ module Ruzzy
|
|
28
24
|
c_dummy_test_one_input(data)
|
29
25
|
end
|
30
26
|
|
27
|
+
def dummy
|
28
|
+
fuzz(->(data) { dummy_test_one_input(data) })
|
29
|
+
end
|
30
|
+
|
31
|
+
def trace(harness_script)
|
32
|
+
harness_path = Pathname.new(harness_script)
|
33
|
+
|
34
|
+
# Mimic require_relative. If harness script is provided as an absolute path,
|
35
|
+
# then use that. If not, then assume the script is in the same directory as
|
36
|
+
# as the tracer script, i.e. the caller.
|
37
|
+
if !harness_path.absolute?
|
38
|
+
caller_path = Pathname.new(caller_locations.first.path)
|
39
|
+
harness_path = (caller_path.parent / harness_path).realpath
|
40
|
+
end
|
41
|
+
|
42
|
+
c_trace(harness_path.to_s)
|
43
|
+
end
|
44
|
+
|
31
45
|
module_function :fuzz
|
32
|
-
module_function :dummy
|
33
46
|
module_function :dummy_test_one_input
|
47
|
+
module_function :dummy
|
48
|
+
module_function :trace
|
34
49
|
end
|
35
50
|
|
36
51
|
# Hook Integer operations for tracing in SantizerCoverage
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruzzy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Trail of Bits
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-03-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -101,5 +101,5 @@ requirements: []
|
|
101
101
|
rubygems_version: 3.5.3
|
102
102
|
signing_key:
|
103
103
|
specification_version: 4
|
104
|
-
summary: A Ruby C
|
104
|
+
summary: A coverage-guided fuzzer for pure Ruby code and Ruby C extensions
|
105
105
|
test_files: []
|