Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash on bogus input #40

Closed
collosi opened this issue Jun 21, 2018 · 5 comments
Closed

Crash on bogus input #40

collosi opened this issue Jun 21, 2018 · 5 comments
Labels

Comments

@collosi
Copy link
Contributor

collosi commented Jun 21, 2018

Avro-rs has a tendency to crash the process when given invalid input. The typical error message that I've seen (I don't have it right now) mentions an out of memory condition. My guess is it's trying to allocate an array of size -7 or something. I'd like to start using this crate in a project of mine, but the crashes are an issue.

I've actually created a fuzzer project with afl.rs, that I can share if that would be helpful, but at its core it's just:

extern crate afl;
extern crate avro_rs;

use avro_rs::{Schema, from_avro_datum};

    static SCHEMA: &'static str = r#"
            {
                "type": "record",
                "name": "test",
                "fields": [
                    {"name": "a", "type": "long", "default": 42},
                    {"name": "b", "type": "string"}
                ]
            }
        "#;


fn main() {
    afl::read_stdio_bytes(|bs| {
	let schema = Schema::parse_str(SCHEMA).unwrap();
        let _ = from_avro_datum(&schema, &mut &bs[..], None);
    });
}

And here are the stats (4 crashes) after running for a minute or two:

start_time        : 1529615156
last_update       : 1529615246
fuzzer_pid        : 27636
cycles_done       : 32
execs_done        : 178688
execs_per_sec     : 2081.67
paths_total       : 18
paths_favored     : 7
paths_found       : 17
paths_imported    : 0
max_depth         : 2
cur_path          : 0
pending_favs      : 0
pending_total     : 0
variable_paths    : 18
stability         : 98.40%
bitmap_cvg        : 1.62%
unique_crashes    : 4
unique_hangs      : 0
last_path         : 1529615159
last_crash        : 1529615157
last_hang         : 0
execs_since_crash : 178078
exec_timeout      : 20
afl_banner        : avro-fuzz
afl_version       : 2.52b
target_mode       : default

@collosi
Copy link
Contributor Author

collosi commented Jun 22, 2018

So here's some output from a crash:

fatal runtime error: allocator memory exhausted
Process 15891, “env” “cat out/crashes/id:000000,sig:0…” terminated by signal SIGILL (Illegal instruction)

And here's what gdb reports as the backtrace (Edit: updated stack trace below):

#0  alloc_system::platform::_$LT$impl$u20$core..heap..Alloc$u20$for$u20$$RF$$u27$a$u20$alloc_system..System$GT$::oom::hb39f299bff3ff955 () at liballoc_system/lib.rs:207
#1  0x000055555564ddf0 in _$LT$alloc_system..System$u20$as$u20$core..heap..Alloc$GT$::oom::h4964edf0a16d2492 () at liballoc_system/lib.rs:78
#2  0x0000555555619b34 in __rde_oom () at liballoc_jemalloc/lib.rs:124
#3  0x000055555556c984 in _$LT$alloc..heap..Heap$u20$as$u20$core..heap..Alloc$GT$::oom::he2910aaba4d4abcd (self=0x7fffffffa0d8, err=...)
    at /checkout/src/liballoc/heap.rs:98
#4  0x0000555555569bf3 in _$LT$alloc..raw_vec..RawVec$LT$T$C$$u20$A$GT$$GT$::allocate_in::h0a977bbc2783dfb5 (cap=18446744073709551593, zeroed=false, a=...)
    at /checkout/src/liballoc/raw_vec.rs:104
#5  0x00005555555698c7 in _$LT$alloc..raw_vec..RawVec$LT$T$GT$$GT$::with_capacity::h38e8752646d23957 (cap=18446744073709551593) at /checkout/src/liballoc/raw_vec.rs:144
#6  0x0000555555561d23 in _$LT$alloc..vec..Vec$LT$T$GT$$GT$::with_capacity::hbfa1c0e496f2e102 (capacity=18446744073709551593) at /checkout/src/liballoc/vec.rs:363
#7  0x0000555555577db2 in avro_rs::decode::decode::he8cedaf96e7cba3b (schema=0x7ffff6c3f138, reader=0x7fffffffd898)
    at /home/auser/.cargo/registry/src/jackfan.us.kg-1ecc6299db9ec823/avro-rs-0.4.1/src/decode.rs:63
#8  0x0000555555579303 in avro_rs::decode::decode::he8cedaf96e7cba3b (schema=0x7fffffffd748, reader=0x7fffffffd898)
    at /home/auser/.cargo/registry/src/jackfan.us.kg-1ecc6299db9ec823/avro-rs-0.4.1/src/decode.rs:144
#9  0x000055555557b922 in avro_rs::reader::from_avro_datum::hd7a70573a9cc0e81 (writer_schema=0x7fffffffd748, reader=0x7fffffffd898, reader_schema=...)
    at /home/auser/.cargo/registry/src/jackfan.us.kg-1ecc6299db9ec823/avro-rs-0.4.1/src/reader.rs:281
#10 0x0000555555565a39 in avro_fuzz::main::_$u7b$$u7b$closure$u7d$$u7d$::h8e9620717b10cc48 (bs=...) at src/main.rs:44
#11 0x000055555556521e in afl::read_stdio_bytes::_$u7b$$u7b$closure$u7d$$u7d$::h25ae575caf141e40 ()
    at /home/auser/.cargo/registry/src/jackfan.us.kg-1ecc6299db9ec823/afl-0.3.2/src/lib.rs:41
#12 0x000055555556989d in std::panicking::try::do_call::hb310bfec1bd0ec47 (data=0x7fffffffda08 "\360\332\377\377\377\177") at /checkout/src/libstd/panicking.rs:306
#13 0x00005555556192ff in __rust_maybe_catch_panic () at libpanic_unwind/lib.rs:102
#14 0x00005555555697a5 in std::panicking::try::h0850987f79ce6779 (f=...) at /checkout/src/libstd/panicking.rs:285
#15 0x000055555556e3d3 in std::panic::catch_unwind::hdba5ab291cfbb63a (f=...) at /checkout/src/libstd/panic.rs:361
#16 0x00005555555650d4 in afl::read_stdio_bytes::h97d6ddb36a756b7c (closure=...) at /home/auser/.cargo/registry/src/jackfan.us.kg-1ecc6299db9ec823/afl-0.3.2/src/lib.rs:40
#17 0x0000555555571ba9 in avro_fuzz::main::hc231d9a9a639f5c8 () at src/main.rs:42
#18 0x000055555556c1e2 in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h6e6dc05bbb08cd31 () at /checkout/src/libstd/rt.rs:74
#19 0x000055555560a4b8 in std::rt::lang_start_internal::_$u7b$$u7b$closure$u7d$$u7d$::hb3d070a2bac9f126 () at libstd/rt.rs:59
#20 std::panicking::try::do_call::hfce3050be9508e94 () at libstd/panicking.rs:306
#21 0x00005555556192ff in __rust_maybe_catch_panic () at libpanic_unwind/lib.rs:102
#22 0x0000555555608d36 in std::panicking::try::h181b418ccf9daec0 () at libstd/panicking.rs:285
#23 std::panic::catch_unwind::h2e22b8787335a1ba () at libstd/panic.rs:361
#24 std::rt::lang_start_internal::h4193b9a4ab9d505a () at libstd/rt.rs:58
#25 0x000055555556c1c2 in std::rt::lang_start::h2b8b9f3038528e14 (main=0x555555571ba0 <avro_fuzz::main::hc231d9a9a639f5c8>, argc=1, argv=0x7fffffffde18)
    at /checkout/src/libstd/rt.rs:74
#26 0x0000555555571bde in main ()

@poros poros added the bug label Jun 22, 2018
@poros
Copy link
Collaborator

poros commented Jun 22, 2018

Thank you for the report! Never happened to us so far. We'll try to reproduce.

@collosi
Copy link
Contributor Author

collosi commented Jun 22, 2018

So apparently there's a movement afoot to add the ability to handle out of memory conditions. However, as far as I can tell, it's not even a nightly feature yet. As an interim step, would you consider putting an optional upper bound on the size of any allocations that happen with a "user specified" size?

@collosi
Copy link
Contributor Author

collosi commented Jun 22, 2018

Ok, so here's a simple program that can reproduce two different types of crashes:


extern crate avro_rs;
use avro_rs::{from_avro_datum, Schema};

static SCHEMA: &'static str = r#"
            {
                "type": "record",
                "name": "test",
                "fields": [
                    {"name": "a", "type": "long", "default": 42},
                    {"name": "b", "type": "string"}
                ]
            }
        "#;

fn main() {
    let causes_out_of_memory : &[u8] = &[0x3e,0x15,0xff,0x1f,0x15,0xff];
    let causes_left_shift_overflow: &[u8] = &[
        0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1,
        0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1,
        0xe1, 0xe1, 0xe1,
    ];
    let schema = Schema::parse_str(SCHEMA).unwrap();
    let _ = from_avro_datum(&schema, &mut &causes_out_of_memory[..], None);
}

Change 'causes_out_of_memory' to 'causes_left_shift_overflow' to see the other one.

@flavray
Copy link
Owner

flavray commented Jun 24, 2018

Thanks for the report!
I've just merged #42 which should fix both issues (at least, the code in the last comment does not panic anymore). Let us know if you find any other crashes when using the library, we've definitely not battle-tested it against bogus input 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants