Ruby C-APIでモジュールのメソッドを適切に呼び出すにはどうすればよいですか?

概要

このオープンソース正規表現ライブラリのファジングハーネスを作成しようとしていますが、Ruby C-API でモジュールを適切に呼び出す方法がわからないという問題に遭遇しています。

現在のハーネスコードは次のようになります。


int main(int argc, char** argv) {
    // Initialize ruby
    ruby_init();

    // Define example regex string
    VALUE x;
    x = rb_str_new_cstr("a"); // Very simple regex which maches an "a" character

    
    // Initialize the Onigmo module
    printf("Initializing the Onigmo module...\n");

    VALUE rb_cOnigmo = rb_define_module("Onigmo");

    rb_define_singleton_method(rb_cOnigmo, "parse", parse, 1);
    rb_define_singleton_method(rb_cOnigmo, "compile", compile, 1);

    rb_cOnigmoNode = rb_define_class_under(rb_cOnigmo, "Node", rb_cObject);
    rb_cOnigmoAlternationNode = rb_define_class_under(rb_cOnigmo, "AlternationNode", rb_cOnigmoNode);
    rb_cOnigmoAnchorBufferBeginNode = rb_define_class_under(rb_cOnigmo, "AnchorBufferBeginNode", rb_cOnigmoNode);
    rb_cOnigmoAnchorBufferEndNode = rb_define_class_under(rb_cOnigmo, "AnchorBufferEndNode", rb_cOnigmoNode);
    rb_cOnigmoAnchorKeepNode = rb_define_class_under(rb_cOnigmo, "AnchorKeepNode", rb_cOnigmoNode);
    rb_cOnigmoAnchorLineBeginNode = rb_define_class_under(rb_cOnigmo, "AnchorLineBeginNode", rb_cOnigmoNode);
    rb_cOnigmoAnchorLineEndNode = rb_define_class_under(rb_cOnigmo, "AnchorLineEndNode", rb_cOnigmoNode);
    rb_cOnigmoAnchorPositionBeginNode = rb_define_class_under(rb_cOnigmo, "AnchorPositionBeginNode", rb_cOnigmoNode);
    rb_cOnigmoAnchorSemiEndNode = rb_define_class_under(rb_cOnigmo, "AnchorSemiEndNode", rb_cOnigmoNode);
    rb_cOnigmoAnchorWordBoundaryNode = rb_define_class_under(rb_cOnigmo, "AnchorWordBoundaryNode", rb_cOnigmoNode);
    rb_cOnigmoAnchorWordBoundaryInvertNode = rb_define_class_under(rb_cOnigmo, "AnchorWordBoundaryInvertNode", rb_cOnigmoNode);
    rb_cOnigmoAnyNode = rb_define_class_under(rb_cOnigmo, "AnyNode", rb_cOnigmoNode);
    rb_cOnigmoBackrefNode = rb_define_class_under(rb_cOnigmo, "BackrefNode", rb_cOnigmoNode);
    rb_cOnigmoCallNode = rb_define_class_under(rb_cOnigmo, "CallNode", rb_cOnigmoNode);
    rb_cOnigmoCClassNode = rb_define_class_under(rb_cOnigmo, "CClassNode", rb_cOnigmoNode);
    rb_cOnigmoCClassInvertNode = rb_define_class_under(rb_cOnigmo, "CClassInvertNode", rb_cOnigmoNode);
    rb_cOnigmoEncloseAbsentNode = rb_define_class_under(rb_cOnigmo, "EncloseAbsentNode", rb_cOnigmoNode);
    rb_cOnigmoEncloseConditionNode = rb_define_class_under(rb_cOnigmo, "EncloseConditionNode", rb_cOnigmoNode);
    rb_cOnigmoEncloseMemoryNode = rb_define_class_under(rb_cOnigmo, "EncloseMemoryNode", rb_cOnigmoNode);
    rb_cOnigmoEncloseOptionsNode = rb_define_class_under(rb_cOnigmo, "EncloseOptionsNode", rb_cOnigmoNode);
    rb_cOnigmoEncloseStopBacktrackNode = rb_define_class_under(rb_cOnigmo, "EncloseStopBacktrackNode", rb_cOnigmoNode);
    rb_cOnigmoListNode = rb_define_class_under(rb_cOnigmo, "ListNode", rb_cOnigmoNode);
    rb_cOnigmoLookAheadNode = rb_define_class_under(rb_cOnigmo, "LookAheadNode", rb_cOnigmoNode);
    rb_cOnigmoLookAheadInvertNode = rb_define_class_under(rb_cOnigmo, "LookAheadInvertNode", rb_cOnigmoNode);
    rb_cOnigmoLookBehindNode = rb_define_class_under(rb_cOnigmo, "LookBehindNode", rb_cOnigmoNode);
    rb_cOnigmoLookBehindInvertNode = rb_define_class_under(rb_cOnigmo, "LookBehindInvertNode", rb_cOnigmoNode);
    rb_cOnigmoQuantifierNode = rb_define_class_under(rb_cOnigmo, "QuantifierNode", rb_cOnigmoNode);
    rb_cOnigmoStringNode = rb_define_class_under(rb_cOnigmo, "StringNode", rb_cOnigmoNode);
    rb_cOnigmoWordNode = rb_define_class_under(rb_cOnigmo, "WordNode", rb_cOnigmoNode);
    rb_cOnigmoWordInvertNode = rb_define_class_under(rb_cOnigmo, "WordInvertNode", rb_cOnigmoNode);



    printf("Creating instance of rb_cOnigmo...\n");
    VALUE module_object = rb_class_new_instance(0, NULL, rb_cOnigmo);
    printf("Trying to call \"parse\" on the module...\n");
    rb_funcall(module_object, rb_intern("parse"), 1, x);
    printf("Done!\n");

    // Cleanup
    return ruby_cleanup(0);
}

コンパイルして実行しようとすると、次の出力が得られます。

Initializing the Onigmo module...
Creating instance of rb_cOnigmo...
ruby: [BUG] Segmentation fault at 0x0000000000000040
ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux-gnu]

-- Control frame information -----------------------------------------------
c:0001 p:0000 s:0003 E:0008c0 (none) [FINISH]


-- Machine register context ------------------------------------------------
 RIP: 0x00007fc7cd3d2ca9 RBP: 0x00005614b0a0b850 RSP: 0x00007ffca19ce140
 RAX: 0x0000000000000000 RBX: 0x00005614b0a64d28 RCX: 0x0000000000000003
 RDX: 0x0000000000000010 RDI: 0x00005614b0a0b850 RSI: 0x0000000000000006
  R8: 0x0000000000000000  R9: 0x00005614b0b32ab0 R10: 0x00005614b0b32900
 R11: 0x00007fc7cd239ce0 R12: 0x0000000000000006 R13: 0x00007fc7cd69c560
 R14: 0x0000000000000008 R15: 0x00005614b00db7a8 EFL: 0x0000000000010206

-- C level backtrace information -------------------------------------------
/lib/x86_64-linux-gnu/libruby-3.0.so.3.0(0x7fc7cd57a0d0) [0x7fc7cd57a0d0]
/lib/x86_64-linux-gnu/libruby-3.0.so.3.0(0x7fc7cd3ce4f4) [0x7fc7cd3ce4f4]
/lib/x86_64-linux-gnu/libruby-3.0.so.3.0(0x7fc7cd4ee4ed) [0x7fc7cd4ee4ed]
/lib/x86_64-linux-gnu/libc.so.6(__restore_rt+0x0) [0x7fc7cd061520]
/lib/x86_64-linux-gnu/libruby-3.0.so.3.0(0x7fc7cd3d2ca9) [0x7fc7cd3d2ca9]
/lib/x86_64-linux-gnu/libruby-3.0.so.3.0(0x7fc7cd3d8502) [0x7fc7cd3d8502]
/lib/x86_64-linux-gnu/libruby-3.0.so.3.0(0xa9662) [0x7fc7cd3d8662]
/lib/x86_64-linux-gnu/libruby-3.0.so.3.0(0x7fc7cd3cea0b) [0x7fc7cd3cea0b]
/lib/x86_64-linux-gnu/libruby-3.0.so.3.0(rb_check_type+0x3c) [0x7fc7cd359ccb]
/lib/x86_64-linux-gnu/libruby-3.0.so.3.0(0x7fc7cd35ac7b) [0x7fc7cd35ac7b]
./fuzzer(main+0x406) [0x5614b00d1686]

-- Other runtime information -----------------------------------------------

* Loaded script: ruby

* Loaded features:

    0 enumerator.so
    1 thread.rb
    2 rational.so
    3 complex.so
    4 ruby2_keywords.rb

* Process memory map:

5614b00c9000-5614b00cd000 r--p 00000000 08:06 23653890                   /home/cyberhacker/Asioita/Hakkerointi/Fuzzing/onigmo/ext/onigmo/fuzzer
5614b00cd000-5614b00d7000 r-xp 00004000 08:06 23653890                   /home/cyberhacker/Asioita/Hakkerointi/Fuzzing/onigmo/ext/onigmo/fuzzer
5614b00d7000-5614b00da000 r--p 0000e000 08:06 23653890                   /home/cyberhacker/Asioita/Hakkerointi/Fuzzing/onigmo/ext/onigmo/fuzzer
5614b00da000-5614b00db000 r--p 00010000 08:06 23653890                   /home/cyberhacker/Asioita/Hakkerointi/Fuzzing/onigmo/ext/onigmo/fuzzer
5614b00db000-5614b00dc000 rw-p 00011000 08:06 23653890                   /home/cyberhacker/Asioita/Hakkerointi/Fuzzing/onigmo/ext/onigmo/fuzzer
5614b00dc000-5614b02dc000 rw-p 00000000 00:00 0 
5614b0a08000-5614b0b40000 rw-p 00000000 00:00 0                          [heap]
7fc7c8737000-7fc7c8f8d000 rw-p 00000000 00:00 0 
7fc7c8f8d000-7fc7c93c4000 r--s 00000000 08:06 40248810                   /usr/lib/debug/.build-id/c2/89da5071a3399de893d2af81d6a30c62646e1e.debug
7fc7c93c4000-7fc7c95e3000 r--s 00000000 08:06 40120745                   /usr/lib/x86_64-linux-gnu/libc.so.6
7fc7c95e3000-7fc7c9948000 r--s 00000000 08:06 40117551                   /usr/lib/x86_64-linux-gnu/libruby-3.0.so.3.0.2
7fc7c9948000-7fc7c9977000 r--s 00000000 08:06 23653890                   /home/cyberhacker/Asioita/Hakkerointi/Fuzzing/onigmo/ext/onigmo/fuzzer
7fc7c9977000-7fc7c997a000 r--p 00000000 08:06 40108172                   /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
7fc7c997a000-7fc7c9991000 r-xp 00003000 08:06 40108172                   /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
7fc7c9991000-7fc7c9995000 r--p 0001a000 08:06 40108172                   /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
7fc7c9995000-7fc7c9996000 r--p 0001d000 08:06 40108172                   /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
7fc7c9996000-7fc7c9997000 rw-p 0001e000 08:06 40108172                   /usr/lib/x86_64-linux-gnu/libgcc_s.so.1
7fc7c9997000-7fc7c9998000 ---p 00000000 00:00 0 
7fc7c9998000-7fc7c9a39000 rw-p 00000000 00:00 0 
7fc7c9a39000-7fc7c9a3a000 ---p 00000000 00:00 0 
7fc7c9a3a000-7fc7c9adb000 rw-p 00000000 00:00 0 
7fc7c9adb000-7fc7c9adc000 ---p 00000000 00:00 0 
7fc7c9adc000-7fc7c9b7d000 rw-p 00000000 00:00 0 
7fc7c9b7d000-7fc7c9b7e000 ---p 00000000 00:00 0 
7fc7c9b7e000-7fc7c9c1f000 rw-p 00000000 00:00 0 
7fc7c9c1f000-7fc7c9c20000 ---p 00000000 00:00 0 
7fc7c9c20000-7fc7c9cc1000 rw-p 00000000 00:00 0 
7fc7c9cc1000-7fc7c9cc2000 ---p 00000000 00:00 0 
7fc7c9cc2000-7fc7c9d63000 rw-p 00000000 00:00 0 
7fc7c9d63000-7fc7c9d64000 ---p 00000000 00:00 0 
7fc7c9d64000-7fc7c9e05000 rw-p 00000000 00:00 0 
7fc7c9e05000-7fc7c9e06000 ---p 00000000 00:00 0 
7fc7c9e06000-7fc7c9ea7000 rw-p 00000000 00:00 0 
7fc7c9ea7000-7fc7c9ea8000 ---p 00000000 00:00 0 
7fc7c9ea8000-7fc7c9f49000 rw-p 00000000 00:00 0 
7fc7c9f49000-7fc7c9f4a000 ---p 00000000 00:00 0 
7fc7c9f4a000-7fc7c9feb000 rw-p 00000000 00:00 0 
7fc7c9feb000-7fc7c9fec000 ---p 00000000 00:00 0 
7fc7c9fec000-7fc7ca08d000 rw-p 00000000 00:00 0 
7fc7ca08d000-7fc7ca08e000 ---p 00000000 00:00 0 
7fc7ca08e000-7fc7ca12f000 rw-p 00000000 00:00 0 
7fc7ca12f000-7fc7ca130000 ---p 00000000 00:00 0 
7fc7ca130000-7fc7ca1d1000 rw-p 00000000 00:00 0 
7fc7ca1d1000-7fc7ca1d2000 ---p 00000000 00:00 0 
7fc7ca1d2000-7fc7ca273000 rw-p 00000000 00:00 0 
7fc7ca273000-7fc7ca274000 ---p 00000000 00:00 0 
7fc7ca274000-7fc7ca315000 rw-p 00000000 00:00 0 
7fc7ca315000-7fc7ca316000 ---p 00000000 00:00 0 
7fc7ca316000-7fc7ca3b7000 rw-p 00000000 00:00 0 
7fc7ca3b7000-7fc7ca3b8000 ---p 00000000 00:00 0 
7fc7ca3b8000-7fc7ca459000 rw-p 00000000 00:00 0 
7fc7ca459000-7fc7ca45a000 ---p 00000000 00:00 0 
7fc7ca45a000-7fc7ca4fb000 rw-p 00000000 00:00 0 
7fc7ca4fb000-7fc7ca4fc000 ---p 00000000 00:00 0 
7fc7ca4fc000-7fc7ca59d000 rw-p 00000000 00:00 0 
7fc7ca59d000-7fc7ca59e000 ---p 00000000 00:00 0 
7fc7ca59e000-7fc7ca63f000 rw-p 00000000 00:00 0 
7fc7ca63f000-7fc7ca640000 ---p 00000000 00:00 0 
7fc7ca640000-7fc7ca6e1000 rw-p 00000000 00:00 0 
7fc7ca6e1000-7fc7ca6e2000 ---p 00000000 00:00 0 
7fc7ca6e2000-7fc7ca783000 rw-p 00000000 00:00 0 
7fc7ca783000-7fc7ca784000 ---p 00000000 00:00 0 
7fc7ca784000-7fc7ca825000 rw-p 00000000 00:00 0 
7fc7ca825000-7fc7ca826000 ---p 00000000 00:00 0 
7fc7ca826000-7fc7ca8c7000 rw-p 00000000 00:00 0 
7fc7ca8c7000-7fc7ca8c8000 ---p 00000000 00:00 0 
7fc7ca8c8000-7fc7ca969000 rw-p 00000000 00:00 0 
7fc7ca969000-7fc7ca96a000 ---p 00000000 00:00 0 
7fc7ca96a000-7fc7caa0b000 rw-p 00000000 00:00 0 
7fc7caa0b000-7fc7caa0c000 ---p 00000000 00:00 0 
7fc7caa0c000-7fc7caaad000 rw-p 00000000 00:00 0 
7fc7caaad000-7fc7caaae000 ---p 00000000 00:00 0 
7fc7caaae000-7fc7cab4f000 rw-p 00000000 00:00 0 
7fc7cab4f000-7fc7cab50000 ---p 00000000 00:00 0 
7fc7cab50000-7fc7cabf1000 rw-p 00000000 00:00 0 
7fc7cabf1000-7fc7cabf2000 ---p 00000000 00:00 0 
7fc7cabf2000-7fc7cac93000 rw-p 00000000 00:00 0 
7fc7cac93000-7fc7cac94000 ---p 00000000 00:00 0 
7fc7cac94000-7fc7cad35000 rw-p 00000000 00:00 0 
7fc7cad35000-7fc7cad36000 ---p 00000000 00:00 0 
7fc7cad36000-7fc7ccf47000 rw-p 00000000 00:00 0 
7fc7ccf47000-7fc7ccf49000 r--p 00000000 08:06 40110225                   /usr/lib/x86_64-linux-gnu/libcrypt.so.1.1.0
7fc7ccf49000-7fc7ccf5d000 r-xp 00002000 08:06 40110225                   /usr/lib/x86_64-linux-gnu/libcrypt.so.1.1.0
7fc7ccf5d000-7fc7ccf76000 r--p 00016000 08:06 40110225                   /usr/lib/x86_64-linux-gnu/libcrypt.so.1.1.0
7fc7ccf76000-7fc7ccf77000 ---p 0002f000 08:06 40110225                   /usr/lib/x86_64-linux-gnu/libcrypt.so.1.1.0
7fc7ccf77000-7fc7ccf78000 r--p 0002f000 08:06 40110225                   /usr/lib/x86_64-linux-gnu/libcrypt.so.1.1.0
7fc7ccf78000-7fc7ccf79000 rw-p 00030000 08:06 40110225                   /usr/lib/x86_64-linux-gnu/libcrypt.so.1.1.0
7fc7ccf79000-7fc7ccf81000 rw-p 00000000 00:00 0 
7fc7ccf81000-7fc7ccf8b000 r--p 00000000 08:06 40110568                   /usr/lib/x86_64-linux-gnu/libgmp.so.10.4.1
7fc7ccf8b000-7fc7ccfea000 r-xp 0000a000 08:06 40110568                   /usr/lib/x86_64-linux-gnu/libgmp.so.10.4.1
7fc7ccfea000-7fc7cd001000 r--p 00069000 08:06 40110568                   /usr/lib/x86_64-linux-gnu/libgmp.so.10.4.1
7fc7cd001000-7fc7cd002000 r--p 0007f000 08:06 40110568                   /usr/lib/x86_64-linux-gnu/libgmp.so.10.4.1
7fc7cd002000-7fc7cd003000 rw-p 00080000 08:06 40110568                   /usr/lib/x86_64-linux-gnu/libgmp.so.10.4.1
7fc7cd003000-7fc7cd005000 r--p 00000000 08:06 40110282                   /usr/lib/x86_64-linux-gnu/libz.so.1.2.11
7fc7cd005000-7fc7cd016000 r-xp 00002000 08:06 40110282                   /usr/lib/x86_64-linux-gnu/libz.so.1.2.11
7fc7cd016000-7fc7cd01c000 r--p 00013000 08:06 40110282                   /usr/lib/x86_64-linux-gnu/libz.so.1.2.11
7fc7cd01c000-7fc7cd01d000 ---p 00019000 08:06 40110282                   /usr/lib/x86_64-linux-gnu/libz.so.1.2.11
7fc7cd01d000-7fc7cd01e000 r--p 00019000 08:06 40110282                   /usr/lib/x86_64-linux-gnu/libz.so.1.2.11
7fc7cd01e000-7fc7cd01f000 rw-p 0001a000 08:06 40110282                   /usr/lib/x86_64-linux-gnu/libz.so.1.2.11
7fc7cd01f000-7fc7cd047000 r--p 00000000 08:06 40120745                   /usr/lib/x86_64-linux-gnu/libc.so.6
7fc7cd047000-7fc7cd1dc000 r-xp 00028000 08:06 40120745                   /usr/lib/x86_64-linux-gnu/libc.so.6
7fc7cd1dc000-7fc7cd234000 r--p 001bd000 08:06 40120745                   /usr/lib/x86_64-linux-gnu/libc.so.6
7fc7cd234000-7fc7cd235000 ---p 00215000 08:06 40120745                   /usr/lib/x86_64-linux-gnu/libc.so.6
7fc7cd235000-7fc7cd239000 r--p 00215000 08:06 40120745                   /usr/lib/x86_64-linux-gnu/libc.so.6
7fc7cd239000-7fc7cd23b000 rw-p 00219000 08:06 40120745                   /usr/lib/x86_64-linux-gnu/libc.so.6
7fc7cd23b000-7fc7cd248000 rw-p 00000000 00:00 0 
7fc7cd248000-7fc7cd256000 r--p 00000000 08:06 40120748                   /usr/lib/x86_64-linux-gnu/libm.so.6
7fc7cd256000-7fc7cd2d2000 r-xp 0000e000 08:06 40120748                   /usr/lib/x86_64-linux-gnu/libm.so.6
7fc7cd2d2000-7fc7cd32d000 r--p 0008a000 08:06 40120748                   /usr/lib/x86_64-linux-gnu/libm.so.6
7fc7cd32d000-7fc7cd32e000 r--p 000e4000 08:06 40120748                   /usr/lib/x86_64-linux-gnu/libm.so.6
7fc7cd32e000-7fc7cd32f000 rw-p 000e5000 08:06 40120748                   /usr/lib/x86_64-linux-gnu/libm.so.6
7fc7cd32f000-7fc7cd358000 r--p 00000000 08:06 40117551                   /usr/lib/x86_64-linux-gnu/libruby-3.0.so.3.0.2
7fc7cd358000-7fc7cd586000 r-xp 00029000 08:06 40117551                   /usr/lib/x86_64-linux-gnu/libruby-3.0.so.3.0.2
7fc7cd586000-7fc7cd68c000 r--p 00257000 08:06 40117551                   /usr/lib/x86_64-linux-gnu/libruby-3.0.so.3.0.2
7fc7cd68c000-7fc7cd693000 r--p 0035c000 08:06 40117551                   /usr/lib/x86_64-linux-gnu/libruby-3.0.so.3.0.2
7fc7cd693000-7fc7cd694000 rw-p 00363000 08:06 40117551                   /usr/lib/x86_64-linux-gnu/libruby-3.0.so.3.0.2
7fc7cd694000-7fc7cd6a4000 rw-p 00000000 00:00 0 
7fc7cd6cf000-7fc7cd6d1000 rw-p 00000000 00:00 0 
7fc7cd6d1000-7fc7cd6d3000 r--p 00000000 08:06 40110231                   /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7fc7cd6d3000-7fc7cd6fd000 r-xp 00002000 08:06 40110231                   /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7fc7cd6fd000-7fc7cd708000 r--p 0002c000 08:06 40110231                   /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7fc7cd709000-7fc7cd70b000 r--p 00037000 08:06 40110231                   /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7fc7cd70b000-7fc7cd70d000 rw-p 00039000 08:06 40110231                   /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
7ffca11d1000-7ffca19d0000 rw-p 00000000 00:00 0                          [stack]
7ffca19e0000-7ffca19e4000 r--p 00000000 00:00 0                          [vvar]
7ffca19e4000-7ffca19e6000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]


Aborted (core dumped)

したがって、問題のあるコード行は次のとおりです。 VALUE module_object = rb_class_new_instance(0, NULL, rb_cOnigmo); 。 rb_cOnigmo はモジュールです: VALUE rb_cOnigmo = rb_define_module(“Onigmo”);クラスではないので、 rb_class_new_instance ではなく、代わりに他の関数を使用する必要があると思います。問題は、この他の機能が何であるかがわからないことです。

基本的にこれを実現したいのですが、 Onigmo.parse(“a”) ですが、C コードで実行します。

TLDR: Ruby C API を使用するときにモジュールのメソッドを適切に呼び出すにはどうすればよいですか?

解決策

答えてくれてmitch_さんに感謝します!モジュールオブジェクトに対して rb_funcall(rb_cOnigmo, …) を呼び出す必要がありました。