Crystal: algorithm complexity attack on big

Created on 22 May 2019  路  10Comments  路  Source: crystal-lang/crystal

require "big"
BigDecimal.new("1e10000000000")

block and cup 100% and memory 100%

require "bigdecimal"
BigDecimal.new("1e10000000000")

ruby is ok

All 10 comments

Good find. For me this is the output I get:

icr(0.28.0) > BigDecimal.new("1e10000000000")
GC Warning: Failed to expand heap by 4179820544 bytes
GC Warning: Failed to expand heap by 4179689472 bytes
GC Warning: Out of Memory! Heap size: 0 MiB. Returning NULL!
Invalid memory access (signal 11) at address 0x0
[0x55fa4df27dc6] *CallStack::print_backtrace:Int32 +118
[0x55fa4df1b300] __crystal_sigfault_handler +192
[0x7f5b6ee944d0] ???
[0x7f5b6efa42d0] __gmpz_n_pow_ui +352
[0x55fa4df69872] *BigInt#**<UInt64>:BigInt +146
[0x55fa4df6b361] *BigDecimal#initialize<String>:UInt64 +4673
[0x55fa4df6a0da] *BigDecimal::new<String>:BigDecimal +90
[0x55fa4df1b3c2] *__icr_exec__:BigDecimal +34
[0x55fa4df0dcf6] __crystal_main +1734
[0x55fa4df6c086] *Crystal::main_user_code<Int32, Pointer(Pointer(UInt8))>:Nil +6
[0x55fa4df6bfe9] *Crystal::main<Int32, Pointer(Pointer(UInt8))>:Int32 +41
[0x55fa4df18776] main +6
[0x7f5b6ec5dce3] __libc_start_main +243
[0x55fa4df0d55e] _start +46
[0x0] ???

Reduced:

require "big"

10.to_big_i ** 10000000000

But ** just delegates to a gmp method. It consumes time and memory by (GMP's) design.

I'm not sure there's a problem to solve here.

the problem is e, it 's easy to create a big big number, if we read a user form such as price or amount, and new with BigDecimal, is hard to validate before new, only use regex to test e, and easy to forget to do.

should we have a 64bits version of Decimal, more time, we just want Decimal, not Big.

BigDecimal.new("1e1000000000000000000")
# gmp: overflow in mpz type

add more zero, it crash.

In Ruby:

> BigDecimal("1e10000000000000000000")
=> Infinity

Interesting... 馃

But I don't know whether we can do the same. It's the same issue for BigInt.

can we have some limitation for gmp, eg max value or max bits.

and limit to a low value, then if we really need big, increment it explicit.

there is no "attack" here, it's a developer self-destructing their code manually

happens in literally every language

@girng but ruby is ok

@girng no more suck.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

RX14 picture RX14  路  3Comments

Sija picture Sija  路  3Comments

costajob picture costajob  路  3Comments

pbrusco picture pbrusco  路  3Comments

oprypin picture oprypin  路  3Comments