crashappsec / libcon4m

Base Compiler and Runtime Support for con4m
Apache License 2.0
0 stars 0 forks source link

UB: call to function through pointer to incorrect function type #56

Closed ee7 closed 4 months ago

ee7 commented 4 months ago

With:

Since Clang 17, the -fsanitize=function check is no longer only for C++, and the check is enabled by default by -fsanitize=undefined. See the list of available UBSan checks and the discussion of the relevant LLVM patch, which contains:

The rationale for reporting errors is C11 6.5.2.2p9:

If the function is defined with a type that is not compatible with the type (of the expression) pointed to by the expression that denotes the called function, the behavior is undefined.

The errors of this kind that are produced when running the tests, sorted by file name:

../src/con4m/box.c:46:12: runtime error: call to function i64_fmt through pointer to incorrect function type 'struct c4m_str_t *(*)(void *, struct c4m_fmt_spec_t *)'
libcon4m/debug/../src/con4m/numbers.c:698: note: i64_fmt defined here
    #0 0x59a156028cf3 in box_format libcon4m/debug/../src/con4m/box.c:46:12
    #1 0x59a156008212 in lookup_arg_strings libcon4m/debug/../src/con4m/format.c:387:29
    #2 0x59a156007072 in c4m_str_vformat libcon4m/debug/../src/con4m/format.c:563:32
    #3 0x59a156009b5d in c4m_base_format libcon4m/debug/../src/con4m/format.c:581:12
    #4 0x59a15600a112 in _c4m_cstr_format libcon4m/debug/../src/con4m/format.c:606:15
    #5 0x59a156064840 in format_location libcon4m/debug/../src/con4m/compiler/errors.c:1224:12
    #6 0x59a156061348 in c4m_format_module_errors libcon4m/debug/../src/con4m/compiler/errors.c:1253:31
    #7 0x59a156060ee4 in c4m_format_errors libcon4m/debug/../src/con4m/compiler/errors.c:1283:13
    #8 0x59a155ece5bb in test_compiler libcon4m/debug/../src/tests/test.c:429:30
    #9 0x59a155ed1231 in main libcon4m/debug/../src/tests/test.c:515:18

../src/con4m/format.c:387:29: runtime error: call to function c4m_string_format through pointer to incorrect function type 'struct c4m_str_t *(*)(void *, struct c4m_fmt_spec_t *)'
libcon4m/debug/../src/con4m/string.c:1360: note: c4m_string_format defined here
    #0 0x59a1560081b9 in lookup_arg_strings libcon4m/debug/../src/con4m/format.c:387:29
    #1 0x59a156007072 in c4m_str_vformat libcon4m/debug/../src/con4m/format.c:563:32
    #2 0x59a156009b5d in c4m_base_format libcon4m/debug/../src/con4m/format.c:581:12
    #3 0x59a15600a112 in _c4m_cstr_format libcon4m/debug/../src/con4m/format.c:606:15
    #4 0x59a1560184ba in internal_normalize_and_join libcon4m/debug/../src/con4m/path.c:108:22
    #5 0x59a156018d4e in c4m_resolve_path libcon4m/debug/../src/con4m/path.c:175:16
    #6 0x59a155ecd635 in build_file_list libcon4m/debug/../src/tests/test.c:223:16
    #7 0x59a155ed0ed7 in main libcon4m/debug/../src/tests/test.c:501:40

../src/con4m/marshal.c:267:5: runtime error: call to function c4m_string_marshal through pointer to incorrect function type 'void (*)(void *, c4m_stream_t *, struct hatrack_dict_t *, long *)'
libcon4m/debug/../src/con4m/string.c:1171: note: c4m_string_marshal defined here
    #0 0x59a155f5bf1b in c4m_sub_marshal libcon4m/debug/../src/con4m/marshal.c:267:5
    #1 0x59a1560d55e7 in c4m_layout_string_const libcon4m/debug/../src/con4m/compiler/memory_layout.c:48:9
    #2 0x59a1560e0cfd in gen_label libcon4m/debug/../src/con4m/compiler/codegen.c:453:22
    #3 0x59a1560e3c18 in gen_module libcon4m/debug/../src/con4m/compiler/codegen.c:782:5
    #4 0x59a1560df710 in gen_one_node libcon4m/debug/../src/con4m/compiler/codegen.c:1805:9
    #5 0x59a1560ddf59 in gen_module_code libcon4m/debug/../src/con4m/compiler/codegen.c:2110:5
    #6 0x59a1560db383 in c4m_internal_codegen libcon4m/debug/../src/con4m/compiler/codegen.c:2188:9
    #7 0x59a156034cb6 in c4m_generate_code libcon4m/debug/../src/con4m/compiler/compile.c:1079:5
    #8 0x59a155ece63f in test_compiler libcon4m/debug/../src/tests/test.c:441:20
    #9 0x59a155ed1231 in main libcon4m/debug/../src/tests/test.c:515:18

../src/con4m/marshal.c:349:5: runtime error: call to function c4m_string_unmarshal through pointer to incorrect function type 'void (*)(void *, c4m_stream_t *, struct hatrack_dict_t *)'
libcon4m/debug/../src/con4m/string.c:1193: note: c4m_string_unmarshal defined here
    #0 0x59a155f5cd49 in c4m_sub_unmarshal libcon4m/debug/../src/con4m/marshal.c:349:5
    #1 0x59a155fb5ac7 in c4m_vm_load_const_data libcon4m/debug/../src/con4m/vm.c:1525:24
    #2 0x59a155fb543c in c4m_vm_setup_runtime libcon4m/debug/../src/con4m/vm.c:1583:5
    #3 0x59a156034cbf in c4m_generate_code libcon4m/debug/../src/con4m/compiler/compile.c:1080:5
    #4 0x59a155ece63f in test_compiler libcon4m/debug/../src/tests/test.c:441:20
    #5 0x59a155ed1231 in main libcon4m/debug/../src/tests/test.c:515:18

../src/con4m/object.c:502:13: runtime error: call to function c4m_sha_init through pointer to incorrect function type 'void (*)(void **, struct __va_list_tag *)'
libcon4m/debug/../src/con4m/crypto/sha.c:30: note: c4m_sha_init defined here
    #0 0x59a155f0b0ca in _c4m_new libcon4m/debug/../src/con4m/object.c:502:13
    #1 0x59a155f60994 in type_hash_and_dedupe libcon4m/debug/../src/con4m/types.c:392:24
    #2 0x59a155f5f218 in c4m_calculate_type_hash libcon4m/debug/../src/con4m/types.c:433:12
    #3 0x59a155f6fe34 in c4m_initialize_global_types libcon4m/debug/../src/con4m/types.c:1672:9
    #4 0x59a155fb48e1 in c4m_init libcon4m/debug/../src/con4m/init.c:40:5

../src/con4m/object.c:538:12: runtime error: call to function signed_repr through pointer to incorrect function type 'struct c4m_str_t *(*)(void *)'
libcon4m/debug/../src/con4m/numbers.c:22: note: signed_repr defined here
    #0 0x59a155f0ba27 in c4m_repr libcon4m/debug/../src/con4m/object.c:538:12
    #1 0x59a156028afd in box_repr libcon4m/debug/../src/con4m/box.c:14:12
    #2 0x59a155f0d221 in c4m_to_str libcon4m/debug/../src/con4m/object.c:589:12
    #3 0x59a155f97561 in _c4m_stream_write_object libcon4m/debug/../src/con4m/streams.c:497:20
    #4 0x59a155f99e6e in _c4m_print libcon4m/debug/../src/con4m/streams.c:711:9
    #5 0x59a155fd81c3 in c4m_vm_runloop libcon4m/debug/../src/con4m/vm.c:1388:17
    #6 0x59a155fb94f9 in c4m_vmthread_run libcon4m/debug/../src/con4m/vm.c:1664:18
    #7 0x59a155ece919 in test_compiler libcon4m/debug/../src/tests/test.c:453:5
    #8 0x59a155ed1231 in main libcon4m/debug/../src/tests/test.c:515:18

../src/con4m/object.c:589:12: runtime error: call to function c4m_str_to_str through pointer to incorrect function type 'struct c4m_str_t *(*)(void *)'
libcon4m/debug/../src/con4m/string.c:1247: note: c4m_str_to_str defined here
    #0 0x59a155f0d20f in c4m_to_str libcon4m/debug/../src/con4m/object.c:589:12
    #1 0x59a155f97561 in _c4m_stream_write_object libcon4m/debug/../src/con4m/streams.c:497:20
    #2 0x59a155f99e6e in _c4m_print libcon4m/debug/../src/con4m/streams.c:711:9
    #3 0x59a155ece59c in test_compiler libcon4m/debug/../src/tests/test.c:423:5
    #4 0x59a155ed1231 in main libcon4m/debug/../src/tests/test.c:515:18

../src/con4m/object.c:601:12: runtime error: call to function list_copy through pointer to incorrect function type 'void *(*)(void *)'
libcon4m/debug/../src/con4m/lists.c:171: note: list_copy defined here
    #0 0x59a155f0d3bf in c4m_copy_object libcon4m/debug/../src/con4m/object.c:601:12
    #1 0x59a155fe0ea3 in c4m_vm_tcall libcon4m/debug/../src/con4m/vm.c:347:15
    #2 0x59a155fd4a19 in c4m_vm_runloop libcon4m/debug/../src/con4m/vm.c:1274:17
    #3 0x59a155fb94f9 in c4m_vmthread_run libcon4m/debug/../src/con4m/vm.c:1664:18
    #4 0x59a155ece919 in test_compiler libcon4m/debug/../src/tests/test.c:453:5
    #5 0x59a155ed1231 in main libcon4m/debug/../src/tests/test.c:515:18

../src/con4m/object.c:617:12: runtime error: call to function c4m_str_copy through pointer to incorrect function type 'void *(*)(void *)'
libcon4m/debug/../src/con4m/string.c:273: note: c4m_str_copy defined here
    #0 0x59a155f0d6c6 in c4m_copy_object_of_type libcon4m/debug/../src/con4m/object.c:617:12
    #1 0x59a155f172e8 in list_copy libcon4m/debug/../src/con4m/lists.c:183:31
    #2 0x59a155f0d3ce in c4m_copy_object libcon4m/debug/../src/con4m/object.c:601:12
    #3 0x59a155fe0ea3 in c4m_vm_tcall libcon4m/debug/../src/con4m/vm.c:347:15
    #4 0x59a155fd4a19 in c4m_vm_runloop libcon4m/debug/../src/con4m/vm.c:1274:17
    #5 0x59a155fb94f9 in c4m_vmthread_run libcon4m/debug/../src/con4m/vm.c:1664:18
    #6 0x59a155ece919 in test_compiler libcon4m/debug/../src/tests/test.c:453:5
    #7 0x59a155ed1231 in main libcon4m/debug/../src/tests/test.c:515:18

../src/con4m/object.c:689:12: runtime error: call to function c4m_xlist_len through pointer to incorrect function type 'long (*)(void *)'
libcon4m/debug/../src/con4m/xlist.c:185: note: c4m_xlist_len defined here
    #0 0x59a155f0e152 in c4m_len libcon4m/debug/../src/con4m/object.c:689:12
    #1 0x59a155f598e8 in c4m_marshal_compact_type libcon4m/debug/../src/con4m/marshal.c:148:33
    #2 0x59a155f5bee2 in c4m_sub_marshal libcon4m/debug/../src/con4m/marshal.c:265:5
    #3 0x59a1560d68ac in _c4m_layout_const_obj libcon4m/debug/../src/con4m/compiler/memory_layout.c:127:5
    #4 0x59a1560f1da4 in gen_load_const_obj libcon4m/debug/../src/con4m/compiler/codegen.c:251:23
    #5 0x59a1560ea78c in gen_literal libcon4m/debug/../src/con4m/compiler/codegen.c:1543:13
    #6 0x59a1560dfb34 in gen_one_node libcon4m/debug/../src/con4m/compiler/codegen.c:1877:9
    #7 0x59a1560e41aa in gen_kids libcon4m/debug/../src/con4m/compiler/codegen.c:466:9
    #8 0x59a1560dfbc0 in gen_one_node libcon4m/debug/../src/con4m/compiler/codegen.c:1912:9
    #9 0x59a1560f4d37 in gen_one_kid libcon4m/debug/../src/con4m/compiler/codegen.c:484:5
    #10 0x59a1560ebb75 in gen_assign libcon4m/debug/../src/con4m/compiler/codegen.c:1605:5
    #11 0x59a1560dfb42 in gen_one_node libcon4m/debug/../src/con4m/compiler/codegen.c:1880:9
    #12 0x59a1560e41aa in gen_kids libcon4m/debug/../src/con4m/compiler/codegen.c:466:9
    #13 0x59a1560e3c66 in gen_module libcon4m/debug/../src/con4m/compiler/codegen.c:787:5
    #14 0x59a1560df710 in gen_one_node libcon4m/debug/../src/con4m/compiler/codegen.c:1805:9
    #15 0x59a1560ddf59 in gen_module_code libcon4m/debug/../src/con4m/compiler/codegen.c:2110:5
    #16 0x59a1560db383 in c4m_internal_codegen libcon4m/debug/../src/con4m/compiler/codegen.c:2188:9
    #17 0x59a156034cb6 in c4m_generate_code libcon4m/debug/../src/con4m/compiler/compile.c:1079:5
    #18 0x59a155ece63f in test_compiler libcon4m/debug/../src/tests/test.c:441:20
    #19 0x59a155ed1231 in main libcon4m/debug/../src/tests/test.c:515:18

../src/con4m/object.c:703:12: runtime error: call to function list_get through pointer to incorrect function type 'void *(*)(void *, void *)'
libcon4m/debug/../src/con4m/lists.c:191: note: list_get defined here
    #0 0x59a155f0e2f6 in c4m_index_get libcon4m/debug/../src/con4m/object.c:703:12
    #1 0x59a155ff1a23 in c4m_vm_tcall libcon4m/debug/../src/con4m/vm.c:502:15
    #2 0x59a155fd4a19 in c4m_vm_runloop libcon4m/debug/../src/con4m/vm.c:1274:17
    #3 0x59a155fb94f9 in c4m_vmthread_run libcon4m/debug/../src/con4m/vm.c:1664:18
    #4 0x59a155ece919 in test_compiler libcon4m/debug/../src/tests/test.c:453:5
    #5 0x59a155ed1231 in main libcon4m/debug/../src/tests/test.c:515:18

../src/con4m/object.c:717:5: runtime error: call to function list_set through pointer to incorrect function type 'void (*)(void *, void *, void *)'
libcon4m/debug/../src/con4m/lists.c:226: note: list_set defined here
    #0 0x59a155f0e49a in c4m_index_set libcon4m/debug/../src/con4m/object.c:717:5
    #1 0x59a155ff2420 in c4m_vm_tcall libcon4m/debug/../src/con4m/vm.c:515:9
    #2 0x59a155fd4a19 in c4m_vm_runloop libcon4m/debug/../src/con4m/vm.c:1274:17
    #3 0x59a155fb94f9 in c4m_vmthread_run libcon4m/debug/../src/con4m/vm.c:1664:18
    #4 0x59a155ece919 in test_compiler libcon4m/debug/../src/tests/test.c:453:5
    #5 0x59a155ed1231 in main libcon4m/debug/../src/tests/test.c:515:18

../src/con4m/object.c:745:5: runtime error: call to function list_set_slice through pointer to incorrect function type 'void (*)(void *, long, long, void *)'
libcon4m/debug/../src/con4m/lists.c:275: note: list_set_slice defined here
    #0 0x59a155f0e7fe in c4m_slice_set libcon4m/debug/../src/con4m/object.c:745:5
    #1 0x59a155ff3975 in c4m_vm_tcall libcon4m/debug/../src/con4m/vm.c:539:9
    #2 0x59a155fd4a19 in c4m_vm_runloop libcon4m/debug/../src/con4m/vm.c:1274:17
    #3 0x59a155fb94f9 in c4m_vmthread_run libcon4m/debug/../src/con4m/vm.c:1664:18
    #4 0x59a155ece919 in test_compiler libcon4m/debug/../src/tests/test.c:453:5
    #5 0x59a155ed1231 in main libcon4m/debug/../src/tests/test.c:515:18

../src/con4m/object.c:780:12: runtime error: call to function any_int_coerce_to through pointer to incorrect function type 'void *(*)(void *, struct c4m_type_t *)'
libcon4m/debug/../src/con4m/numbers.c:393: note: any_int_coerce_to defined here
    #0 0x59a155f0ed31 in c4m_coerce libcon4m/debug/../src/con4m/object.c:780:12
    #1 0x59a155f9157a in tuple_coerce libcon4m/debug/../src/con4m/tuple.c:123:25
    #2 0x59a155f91780 in tuple_copy libcon4m/debug/../src/con4m/tuple.c:132:12
    #3 0x59a155f0d3ce in c4m_copy_object libcon4m/debug/../src/con4m/object.c:601:12
    #4 0x59a155fe0ea3 in c4m_vm_tcall libcon4m/debug/../src/con4m/vm.c:347:15
    #5 0x59a155fd4a19 in c4m_vm_runloop libcon4m/debug/../src/con4m/vm.c:1274:17
    #6 0x59a155fb94f9 in c4m_vmthread_run libcon4m/debug/../src/con4m/vm.c:1664:18
    #7 0x59a155ece919 in test_compiler libcon4m/debug/../src/tests/test.c:453:5
    #8 0x59a155ed1231 in main libcon4m/debug/../src/tests/test.c:515:18

../src/con4m/object.c:929:12: runtime error: call to function to_list_lit through pointer to incorrect function type 'void *(*)(struct c4m_type_t *, c4m_xlist_t *, struct c4m_str_t *)'
libcon4m/debug/../src/con4m/lists.c:360: note: to_list_lit defined here
    #0 0x59a155f10364 in c4m_container_literal libcon4m/debug/../src/con4m/object.c:929:12
    #1 0x59a1560975fb in c4m_fold_container libcon4m/debug/../src/con4m/compiler/check_pass.c:268:17
    #2 0x59a1560c21f4 in calculate_container_type libcon4m/debug/../src/con4m/compiler/check_pass.c:375:5
    #3 0x59a1560a5c8f in check_literal libcon4m/debug/../src/con4m/compiler/check_pass.c:1969:9
    #4 0x59a1560a10f3 in base_check_pass_dispatch libcon4m/debug/../src/con4m/compiler/check_pass.c:2137:9
    #5 0x59a1560bbda0 in process_children libcon4m/debug/../src/con4m/compiler/check_pass.c:566:9
    #6 0x59a1560a11f6 in base_check_pass_dispatch libcon4m/debug/../src/con4m/compiler/check_pass.c:2210:9
    #7 0x59a1560c9b9c in base_handle_assign libcon4m/debug/../src/con4m/compiler/check_pass.c:1853:5
    #8 0x59a1560b96db in handle_assign libcon4m/debug/../src/con4m/compiler/check_pass.c:1881:9
    #9 0x59a1560a1194 in base_check_pass_dispatch libcon4m/debug/../src/con4m/compiler/check_pass.c:2181:9
    #10 0x59a15609fe1f in check_pass_toplevel_dispatch libcon4m/debug/../src/con4m/compiler/check_pass.c:2254:9
    #11 0x59a1560a04eb in process_toplevel_children libcon4m/debug/../src/con4m/compiler/check_pass.c:2225:9
    #12 0x59a15609fcae in check_pass_toplevel_dispatch libcon4m/debug/../src/con4m/compiler/check_pass.c:2238:9
    #13 0x59a15609cbce in check_module_toplevel libcon4m/debug/../src/con4m/compiler/check_pass.c:2539:5
    #14 0x59a156099798 in module_check_pass libcon4m/debug/../src/con4m/compiler/check_pass.c:2791:5
    #15 0x59a15609884f in c4m_check_pass libcon4m/debug/../src/con4m/compiler/check_pass.c:3001:24
    #16 0x59a156034724 in c4m_compile_from_entry_point libcon4m/debug/../src/con4m/compiler/compile.c:1065:5
    #17 0x59a155ece5a5 in test_compiler libcon4m/debug/../src/tests/test.c:425:11
    #18 0x59a155ed1231 in main libcon4m/debug/../src/tests/test.c:515:18

../src/con4m/tree_pattern.c:292:12: runtime error: call to function tcmp through pointer to incorrect function type 'bool (*)(void *, void *)'
libcon4m/debug/../src/con4m/compiler/ast_utils.c:6: note: tcmp defined here
    #0 0x59a15617149a in content_matches libcon4m/debug/../src/con4m/tree_pattern.c:292:12
    #1 0x59a156170607 in full_match libcon4m/debug/../src/con4m/tree_pattern.c:554:20
    #2 0x59a15616fd1f in c4m_tree_match libcon4m/debug/../src/con4m/tree_pattern.c:274:19
    #3 0x59a15607aa71 in apply_pattern_on_node libcon4m/debug/../src/con4m/compiler/ast_utils.c:376:24
    #4 0x59a15607b1b4 in get_match_on_node libcon4m/debug/../src/con4m/compiler/ast_utils.c:394:24
    #5 0x59a1560fa99f in is_tuple_assignment libcon4m/debug/../src/con4m/compiler/codegen.c:1588:26
    #6 0x59a1560ebc7c in gen_assign libcon4m/debug/../src/con4m/compiler/codegen.c:1610:13
    #7 0x59a1560dfb42 in gen_one_node libcon4m/debug/../src/con4m/compiler/codegen.c:1880:9
    #8 0x59a1560e41aa in gen_kids libcon4m/debug/../src/con4m/compiler/codegen.c:466:9
    #9 0x59a1560e3c66 in gen_module libcon4m/debug/../src/con4m/compiler/codegen.c:787:5
    #10 0x59a1560df710 in gen_one_node libcon4m/debug/../src/con4m/compiler/codegen.c:1805:9
    #11 0x59a1560ddf59 in gen_module_code libcon4m/debug/../src/con4m/compiler/codegen.c:2110:5
    #12 0x59a1560db383 in c4m_internal_codegen libcon4m/debug/../src/con4m/compiler/codegen.c:2188:9
    #13 0x59a156034cb6 in c4m_generate_code libcon4m/debug/../src/con4m/compiler/compile.c:1079:5
    #14 0x59a155ece63f in test_compiler libcon4m/debug/../src/tests/test.c:441:20
    #15 0x59a155ed1231 in main libcon4m/debug/../src/tests/test.c:515:18
viega commented 4 months ago

No, won't fix. A pointer is a pointer, and in every ABI in the world a void * in a parameter can be substituted with any other pointer type.

It's much more clear at the function definition site to declare the ACTUAL types. Nor am I ever going to take the pain to do all the refactoring and gory casting to make the code less clear.

Please do not spend time on UB that is not actually going to lead to issues on any target platforms.

ee7 commented 4 months ago

No, won't fix.

That's all fine by me. My main motivation for this ticket was to track the removal of this UBSan output, by whatever means, so that the rest of the output is more visible.

In the meantime, we've gained the use_ubsan option, so I'll suggest that we add a line in meson.build to suppress these errors. Otherwise I have to maintain a local branch to do that.

I'll take the liberty of re-opening this ticket, and creating https://github.com/crashappsec/libcon4m/pull/86 to close it. Please yell at me if you object.