Comment by oguz-ismail 1 day ago >if (n + 1 < n)No one does this 4 comments oguz-ismail Reply matheusmoreira 20 hours 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 19 hours 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 16 hours ago Just stop using signed integers to hold sizes. malloc itself takes size_t, which is unsigned.
matheusmoreira 20 hours 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 19 hours 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 16 hours ago Just stop using signed integers to hold sizes. malloc itself takes size_t, which is unsigned.
Joker_vD 19 hours 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 16 hours ago Just stop using signed integers to hold sizes. malloc itself takes size_t, which is unsigned.
ryao 16 hours 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.