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

Integer overflow in rotate_left #758

Closed
RalfJung opened this issue May 31, 2019 · 2 comments
Closed

Integer overflow in rotate_left #758

RalfJung opened this issue May 31, 2019 · 2 comments

Comments

@RalfJung
Copy link
Member

Running the following program in Miri when rustc was compiled with debug assertions leads to an integer overflow:

fn main() {
    assert_eq!(0i16.rotate_left(124), 0);
}

Relevant part of the backtrace:

  12: core::panicking::panic
             at src/libcore/panicking.rs:49
  13: rustc_mir::interpret::intrinsics::<impl rustc_mir::interpret::eval_context::InterpretCx<M>>::emulate_intrinsic
             at /home/r/src/rust/rustc/src/librustc_mir/interpret/intrinsics.rs:197
  14: miri::intrinsic::EvalContextExt::call_intrinsic
             at src/intrinsic.rs:20
  15: <miri::Evaluator as rustc_mir::interpret::machine::Machine>::call_intrinsic
             at src/lib.rs:421
  16: rustc_mir::interpret::terminator::<impl rustc_mir::interpret::eval_context::InterpretCx<M>>::eval_fn_call
             at /home/r/src/rust/rustc/src/librustc_mir/interpret/terminator.rs:250
  17: rustc_mir::interpret::terminator::<impl rustc_mir::interpret::eval_context::InterpretCx<M>>::eval_terminator
             at /home/r/src/rust/rustc/src/librustc_mir/interpret/terminator.rs:95
  18: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpretCx<M>>::terminator
             at /home/r/src/rust/rustc/src/librustc_mir/interpret/step.rs:287
  19: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpretCx<M>>::step
             at /home/r/src/rust/rustc/src/librustc_mir/interpret/step.rs:69
  20: rustc_mir::interpret::step::<impl rustc_mir::interpret::eval_context::InterpretCx<M>>::run
             at /home/r/src/rust/rustc/src/librustc_mir/interpret/step.rs:40
  21: miri::eval_main::{{closure}}
             at src/lib.rs:229
  22: miri::eval_main
             at src/lib.rs:228
@RalfJung
Copy link
Member Author

The bug is actually on the rustc side, in the implementation of rotate_left.

                let layout = self.layout_of(substs.type_at(0))?;
                let val_bits = self.read_scalar(args[0])?.to_bits(layout.size)?;
                let raw_shift_bits = self.read_scalar(args[1])?.to_bits(layout.size)?;
                let width_bits = layout.size.bits() as u128;
                let shift_bits = raw_shift_bits % width_bits;
                let inv_shift_bits = (width_bits - raw_shift_bits) % width_bits;
                let result_bits = if intrinsic_name == "rotate_left" {
                    (val_bits << shift_bits) | (val_bits >> inv_shift_bits)
                } else {
                    (val_bits >> shift_bits) | (val_bits << inv_shift_bits)
                };
                let truncated_bits = self.truncate(result_bits, layout);
                let result = Scalar::from_uint(truncated_bits, layout.size);

The computation of "width_bits - raw_shift_bits" can overflow.

Looks like our CTFE intrinsic test suite is insufficient. ;)

@RalfJung
Copy link
Member Author

Closing in favor of rust-lang/rust#61406.

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

No branches or pull requests

1 participant