saltwater icon indicating copy to clipboard operation
saltwater copied to clipboard

[ICE] calculating size of struct causes subtract overflow

Open Byter09 opened this issue 4 years ago • 8 comments

Expected behavior

At least an error? (not sure to be honest, just reporting :P)

Actual Behavior

The application panicked (crashed).
Message:  attempt to subtract with overflow
Location: src/arch/mod.rs:81

Code

struct K *E, ED = E - 5;
Backtrace
The application panicked (crashed).
Message:  attempt to subtract with overflow
Location: src/arch/mod.rs:81

Run with RUST_BACKTRACE=full to include source snippets.
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                          (5 post panic frames hidden)                          
 5: core::panicking::panic::hf3b2e3f8bf85ebd1
    at src/libcore/panicking.rs:51
 6: rcc::arch::<impl rcc::data::types::struct_ref::StructType>::struct_size::{{closure}}::h05af7a0c9ba87115
    at src/arch/mod.rs:81
 7: core::result::Result<T,E>::and_then::hdddbf2676abc1373
    at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/result.rs:714
 8: rcc::arch::<impl rcc::data::types::struct_ref::StructType>::struct_size::h20d6a54dfedfb4b9
    at src/arch/mod.rs:75
 9: rcc::arch::<impl rcc::data::types::Type>::sizeof::hcb9d2f0479d42bdd
    at src/arch/mod.rs:144
10: rcc::parse::expr::<impl rcc::data::Expr>::pointer_arithmetic::h1e0cf17b719beb6d
    at src/parse/expr.rs:1360
11: rcc::parse::expr::<impl rcc::parse::Parser<I>>::additive_expr::{{closure}}::hd3904444afa895ac
    at src/parse/expr.rs:349
12: rcc::parse::expr::<impl rcc::parse::Parser<I>>::left_associative_binary_op::h4e1b594902cca88e
    at src/parse/expr.rs:1089
13: rcc::parse::expr::<impl rcc::parse::Parser<I>>::additive_expr::hf387b2d6ebdb087c
    at src/parse/expr.rs:340
14: core::ops::function::Fn::call::h5039e8b7a8c3403b
    at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/ops/function.rs:72
15: rcc::parse::expr::<impl rcc::parse::Parser<I>>::left_associative_binary_op::ha2437f45b220aa11
    at src/parse/expr.rs:1086
16: rcc::parse::expr::<impl rcc::parse::Parser<I>>::integral_left_associative_binary_op::hb47b557cb13546b4
    at src/parse/expr.rs:1037
17: rcc::parse::expr::<impl rcc::parse::Parser<I>>::shift_expr::ha936662fe294f173
    at src/parse/expr.rs:315
18: core::ops::function::Fn::call::hb50baf59066bcd64
    at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/ops/function.rs:72
19: rcc::parse::expr::<impl rcc::parse::Parser<I>>::left_associative_binary_op::he71a991730e27bbd
    at src/parse/expr.rs:1086
20: rcc::parse::expr::<impl rcc::parse::Parser<I>>::relational_expr::h6787d9ae44120836
    at src/parse/expr.rs:297
21: core::ops::function::Fn::call::h6441b8869001fadd
    at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/ops/function.rs:72
22: rcc::parse::expr::<impl rcc::parse::Parser<I>>::left_associative_binary_op::hb195433e1f579d73
    at src/parse/expr.rs:1086
23: rcc::parse::expr::<impl rcc::parse::Parser<I>>::equality_expr::hffc76a7fb3158351
    at src/parse/expr.rs:279
24: core::ops::function::Fn::call::h0749a2a17f8a4a95
    at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/ops/function.rs:72
25: rcc::parse::expr::<impl rcc::parse::Parser<I>>::left_associative_binary_op::h78b1f2f488b027c7
    at src/parse/expr.rs:1086
26: rcc::parse::expr::<impl rcc::parse::Parser<I>>::integral_left_associative_binary_op::h45d119036a7c6e57
    at src/parse/expr.rs:1037
27: rcc::parse::expr::<impl rcc::parse::Parser<I>>::and_expr::h8fd1c7bc67bdb04a
    at src/parse/expr.rs:266
28: core::ops::function::Fn::call::hb2c6fd6969242b6b
    at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/ops/function.rs:72
29: rcc::parse::expr::<impl rcc::parse::Parser<I>>::left_associative_binary_op::he6ac34b5425bea44
    at src/parse/expr.rs:1086
30: rcc::parse::expr::<impl rcc::parse::Parser<I>>::integral_left_associative_binary_op::hd180c6bd3d7e66a2
    at src/parse/expr.rs:1037
31: rcc::parse::expr::<impl rcc::parse::Parser<I>>::exclusive_or_expr::h4f8330242bfcd992
    at src/parse/expr.rs:254
32: core::ops::function::Fn::call::hac9ad511865fdd57
    at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/ops/function.rs:72
33: rcc::parse::expr::<impl rcc::parse::Parser<I>>::left_associative_binary_op::haa680f0da358defb
    at src/parse/expr.rs:1086
34: rcc::parse::expr::<impl rcc::parse::Parser<I>>::integral_left_associative_binary_op::h8d427144d6157c41
    at src/parse/expr.rs:1037
35: rcc::parse::expr::<impl rcc::parse::Parser<I>>::inclusive_or_expr::hafbe7f863049ccd2
    at src/parse/expr.rs:242
36: core::ops::function::Fn::call::hac89d7b203c5c605
    at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/ops/function.rs:72
37: rcc::parse::expr::<impl rcc::parse::Parser<I>>::left_associative_binary_op::h735fe7000bd9a07e
    at src/parse/expr.rs:1086
38: rcc::parse::expr::<impl rcc::parse::Parser<I>>::scalar_left_associative_binary_op::h29accd524256c645
    at src/parse/expr.rs:991
39: rcc::parse::expr::<impl rcc::parse::Parser<I>>::logical_and_expr::hc7d92fdca7cdc1a8
    at src/parse/expr.rs:222
40: core::ops::function::Fn::call::h63638d4a179fad2b
    at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/ops/function.rs:72
41: rcc::parse::expr::<impl rcc::parse::Parser<I>>::left_associative_binary_op::ha280f713ce335e89
    at src/parse/expr.rs:1086
42: rcc::parse::expr::<impl rcc::parse::Parser<I>>::scalar_left_associative_binary_op::h6cefda0d7488a441
    at src/parse/expr.rs:991
43: rcc::parse::expr::<impl rcc::parse::Parser<I>>::logical_or_expr::hbe5a6b85a63fc202
    at src/parse/expr.rs:196
44: rcc::parse::expr::<impl rcc::parse::Parser<I>>::conditional_expr::hd7caf09e525ccde7
    at src/parse/expr.rs:148
45: rcc::parse::expr::<impl rcc::parse::Parser<I>>::assignment_expr::h2d0da538cd925acb
    at src/parse/expr.rs:100
46: rcc::parse::decl::<impl rcc::parse::Parser<I>>::initializer::h97321b7e43566a54
    at src/parse/decl.rs:1284
47: rcc::parse::decl::<impl rcc::parse::Parser<I>>::init_declarator::h2bc43d4ed628745d
    at src/parse/decl.rs:308
48: rcc::parse::decl::<impl rcc::parse::Parser<I>>::declaration::h86b44297cc69fef0
    at src/parse/decl.rs:159
49: <rcc::parse::Parser<I> as core::iter::traits::iterator::Iterator>::next::{{closure}}::hdd18439defadfd6e
    at src/parse/mod.rs:147
50: core::option::Option<T>::or_else::hcb5c319b81d0484f
    at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/option.rs:754
51: <rcc::parse::Parser<I> as core::iter::traits::iterator::Iterator>::next::h6d4a9e42759949ed
    at src/parse/mod.rs:125
52: <&mut I as core::iter::traits::iterator::Iterator>::next::h15766c776a15448d
    at /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/iter/traits/iterator.rs:2991
53: rcc::compile::h34e0130023da28b4
    at src/lib.rs:184
54: rcc::real_main::h09a7310ce4f4bc85
    at src/main.rs:110
55: rcc::main::hee21c23574a97928
    at src/main.rs:176
                        (12 runtime init frames hidden)

Original fuzzer file: SIGABRT.PC.7ffff7dee7bb.STACK.18cc8e2cc7.CODE.-6.ADDR.(nil).INSTR.mov____0x108(%rsp),%rcx.tar.gz

Byter09 avatar Feb 29 '20 19:02 Byter09

Looks like somehow the alignment is returning 0? That shouldn't happen. I think align needs to return an error if the struct has no members.

jyn514 avatar Mar 27 '20 03:03 jyn514

@jyn514 I hate to say it, but I think the proper way to solve this is with complete/incomplete types as in #261. This is the error provided by clang:

test.c:1:22: error: arithmetic on a pointer to an incomplete type 'struct K'
struct K *E, *ED = E - 5;
                   ~ ^
test.c:1:8: note: forward declaration of 'struct K'
struct K *E, *ED = E - 5;
       ^
1 error generated.

hdamron17 avatar Apr 09 '20 17:04 hdamron17

@hdamron17 you can detect an incomplete forward declaration by an empty members list.

jyn514 avatar Apr 09 '20 17:04 jyn514

However, I did try returning an error from align when the members array is empty and it solves this issue but fails test case https://github.com/jyn514/rcc/blob/a388f00/tests/runner-tests/decls/forward_declaration/0.c when a struct is declared extern. I'm not sure how the size of such a struct should be calculated, though, so I'm looking through the C11 standard now.

hdamron17 avatar Apr 09 '20 17:04 hdamron17

Ahh, this is another case of calling sizeof on an incomplete struct. If I change the test decls/forward_declaration/0.c to call sizeof(my_s) in the main function, then it fails with the following:

tests/runner-tests/decls/forward_declaration/0.c:2:40: error: invalid application of 'sizeof' to an incomplete type 'struct s'
extern struct s my_s; int main(){sizeof(my_s);}
                                       ^~~~~~
tests/runner-tests/decls/forward_declaration/0.c:2:15: note: forward declaration of 'struct s'
extern struct s my_s; int main(){sizeof(my_s);}
              ^
1 error generated.

hdamron17 avatar Apr 09 '20 17:04 hdamron17

Can you find what's trying to call sizeof on my_s? I don't think that should be happening for extern declarations, since there's no definition of the struct.

jyn514 avatar Apr 09 '20 17:04 jyn514

Sorry, I misspoke. In this case, it's calling alignof at https://github.com/jyn514/rcc/blob/a388f00/src/ir/static_init.rs#L32. To be honest, I don't fully understand what store_static does though.

hdamron17 avatar Apr 09 '20 17:04 hdamron17

Hmm, looks like I hacked around this in the wrong place: https://github.com/jyn514/rcc/blob/a388f00/src/ir/static_init.rs#L41. Probably this should be caught in the parser instead and not passed to the backend.

store_static emits static objects into the object file (.o). For example, if you have a program with int a = {1, 2, 3};, it would be in charge of writing the bytes [0x1, 0x2, 0x3] into the binary in little-endian order.

jyn514 avatar Apr 09 '20 17:04 jyn514