← Back to context Comment by oguz-ismail 1 day ago >if (n + 1 < n)No one does this 4 comments oguz-ismail Reply matheusmoreira 1 day ago Oh people absolutely do this.Here's a 2018 example.https://github.com/mruby/mruby/commit/180f39bf4c5246ff77ef71...https://github.com/mruby/mruby/issues/4062 while (l >= bsiz - blen) { bsiz *= 2; if (bsiz < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); } > bsiz*=2 can become negative.> However with -O2 the mrb_raise is never triggered, since bsiz is a signed integer.> Signed integer overflows are undefined behaviour and thus gcc removes the check.People have even categorized this as a compiler vulnerability.https://www.kb.cert.org/vuls/id/162289> C compilers may silently discard some wraparound checksAnd they aren't wrong.The programmer wrote reasonable code that makes sense and perfectly aligns with their mental model of the machine.The compiler took this code and screwed it up because it violates compiler assumptions about some abstract C machine nobody really cares about. Joker_vD 1 day ago I propose we rewrite everything in my yet-unnamed new low-level language: loop while l >= bsize - blen; bsiz, ovf := bsiz * 2; if ovf <> 0 then mrb_raise(mrb, E_ARGUMENT_ERROR, ("too big specifier\x00")); end end ryao 1 day ago Just stop using signed integers to hold sizes. malloc itself takes size_t, which is unsigned.
matheusmoreira 1 day ago Oh people absolutely do this.Here's a 2018 example.https://github.com/mruby/mruby/commit/180f39bf4c5246ff77ef71...https://github.com/mruby/mruby/issues/4062 while (l >= bsiz - blen) { bsiz *= 2; if (bsiz < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); } > bsiz*=2 can become negative.> However with -O2 the mrb_raise is never triggered, since bsiz is a signed integer.> Signed integer overflows are undefined behaviour and thus gcc removes the check.People have even categorized this as a compiler vulnerability.https://www.kb.cert.org/vuls/id/162289> C compilers may silently discard some wraparound checksAnd they aren't wrong.The programmer wrote reasonable code that makes sense and perfectly aligns with their mental model of the machine.The compiler took this code and screwed it up because it violates compiler assumptions about some abstract C machine nobody really cares about. Joker_vD 1 day ago I propose we rewrite everything in my yet-unnamed new low-level language: loop while l >= bsize - blen; bsiz, ovf := bsiz * 2; if ovf <> 0 then mrb_raise(mrb, E_ARGUMENT_ERROR, ("too big specifier\x00")); end end ryao 1 day ago Just stop using signed integers to hold sizes. malloc itself takes size_t, which is unsigned.
Joker_vD 1 day ago I propose we rewrite everything in my yet-unnamed new low-level language: loop while l >= bsize - blen; bsiz, ovf := bsiz * 2; if ovf <> 0 then mrb_raise(mrb, E_ARGUMENT_ERROR, ("too big specifier\x00")); end end ryao 1 day ago Just stop using signed integers to hold sizes. malloc itself takes size_t, which is unsigned.
ryao 1 day ago Just stop using signed integers to hold sizes. malloc itself takes size_t, which is unsigned.
Oh people absolutely do this.
Here's a 2018 example.
https://github.com/mruby/mruby/commit/180f39bf4c5246ff77ef71...
https://github.com/mruby/mruby/issues/4062
> bsiz*=2 can become negative.
> However with -O2 the mrb_raise is never triggered, since bsiz is a signed integer.
> Signed integer overflows are undefined behaviour and thus gcc removes the check.
People have even categorized this as a compiler vulnerability.
https://www.kb.cert.org/vuls/id/162289
> C compilers may silently discard some wraparound checks
And they aren't wrong.
The programmer wrote reasonable code that makes sense and perfectly aligns with their mental model of the machine.
The compiler took this code and screwed it up because it violates compiler assumptions about some abstract C machine nobody really cares about.
I propose we rewrite everything in my yet-unnamed new low-level language:
Just stop using signed integers to hold sizes. malloc itself takes size_t, which is unsigned.