Skip to content

Function pointers need to be checked against their original types #22

Closed

Description

@solson

The following code demonstrates the problem:

fn cast_fn_ptr() {
    fn f() {}

    let g = unsafe {
        transmute::<fn(), fn(i32)>(f)
    };

    // Here Miri blindly lets us call `f` as if it took an argument.
    // This causes Miri to go out bounds on the arguments `Vec`
    // (see backtrace below).
    g(42)
}

Logs and backtrace:

DEBUG:miri 0 Interpreting: cast_fn_ptr
TRACE:miri::interpreter::stepper 0  tmp0 = cast_fn_ptr::f as fn() (ReifyFnPointer)
DEBUG:miri::memory 0  creating fn ptr: 4
TRACE:miri::interpreter::stepper 0  var0 = std::mem::transmute::<fn(), fn(i32)>(tmp0) -> bb1
TRACE:miri::interpreter::stepper 0  // bb1
TRACE:miri::interpreter::stepper 0  tmp1 = var0
TRACE:miri::interpreter::stepper 0  return = tmp1(const 42i32) -> bb2
DEBUG:miri::memory 0  reading fn ptr: 4
thread 'main' panicked at 'index out of bounds: the len is 0 but the index is 0', ../src/libcollections/vec.rs:1167
stack backtrace:
   1:     0x7f9c6bc0561f - std::sys::backtrace::tracing::imp::write::h6528da8103c51ab9
   2:     0x7f9c6bc1324b - std::panicking::default_hook::_$u7b$$u7b$closure$u7d$$u7d$::hbe741a5cc3c49508
   3:     0x7f9c6bc12e7f - std::panicking::default_hook::he0146e6a74621cb4
   4:     0x7f9c6bbd916e - std::panicking::rust_panic_with_hook::h983af77c1a2e581b
   5:     0x7f9c6bc13491 - std::panicking::begin_panic::he426e15a3766089a
   6:     0x7f9c6bbdb1ca - std::panicking::begin_panic_fmt::hdddb415186c241e7
   7:     0x7f9c6bc1342e - rust_begin_unwind
   8:     0x7f9c6bc5c4cf - core::panicking::panic_fmt::hf4e16cb7f0d41a25
   9:     0x7f9c6bc5c6b2 - core::panicking::panic_bounds_check::h14f942e6ac026712
  10:     0x56106d71c38f - _<collections..vec..Vec<T> as core..ops..Index<usize>>::index::h21bed189d0a022e0
                        at ../src/libcollections/vec.rs:1167
  11:     0x56106d711465 - miri::interpreter::EvalContext::eval_fn_call::h0ffe2222a9193951
                        at src/interpreter/mod.rs:551
  12:     0x56106d70a974 - miri::interpreter::EvalContext::eval_terminator::h906ffc9b7c429822
                        at src/interpreter/mod.rs:438
  13:     0x56106d73bbf6 - miri::interpreter::stepper::Stepper::terminator::he5b0f785cd245fcf
                        at src/interpreter/stepper.rs:38
  14:     0x56106d6a7354 - miri::interpreter::stepper::Stepper::step::hc3a72975df25ed8c
                        at src/interpreter/stepper.rs:85
  15:     0x56106d6a68ed - miri::interpreter::step::h5d73db301ea80161
                        at src/interpreter/mod.rs:29
  16:     0x56106d65973e - miri::interpret_start_points::hdb489d38e2bc843c
                        at src/bin/miri.rs:68
  17:     0x56106d658ff4 - _<miri..MiriCompilerCalls as rustc_driver..CompilerCalls<'a>>::build_controller::_$u7b$$u7b$closure$u7d$$u7d$::h44743d57da4e97a6
                        at src/bin/miri.rs:37
  18:     0x7f9c6ddf974d - rustc_driver::driver::compile_input::_$u7b$$u7b$closure$u7d$$u7d$::hf187cb470aad2bf2
  19:     0x7f9c6ddf616d - rustc_driver::driver::phase_3_run_analysis_passes::_$u7b$$u7b$closure$u7d$$u7d$::hd565ad56c5876a16
  20:     0x7f9c6ddef939 - rustc::ty::context::TyCtxt::create_and_enter::habef58c7230d34f9
  21:     0x7f9c6ddb9dff - rustc_driver::driver::compile_input::hfd60b020f6d0208d
  22:     0x7f9c6dda5d24 - rustc_driver::run_compiler::h884d01d12eb76bbb
  23:     0x56106d6704b1 - miri::main::h496a9d1b73279651
                        at src/bin/miri.rs:119
  24:     0x7f9c6bc127d8 - std::panicking::try::call::h852b0d5f2eec25e4
  25:     0x7f9c6bc2170b - __rust_try
  26:     0x7f9c6bc216ae - __rust_maybe_catch_panic
  27:     0x7f9c6bc1227e - std::rt::lang_start::hfe4efe1fc39e4a30
  28:     0x56106d68d9e9 - main
  29:     0x7f9c6b332abf - __libc_start_main
  30:     0x56106d658c58 - _start
  31:                0x0 - <unknown>

Activity

  1. solson commented on Jun 14, 2016

    @solson
    ContributorAuthor

    @oli-obk Can you take a look at this? I guess we need a way to get the correct function type from the stored (DefId, Substs), or we could also store the function type there.

  2. oli-obk commented on Jun 14, 2016

    @oli-obk
    Contributor

    Is transmute<fn(*const i32), fn(*const u32)>(f) legal in Rust? We can simply decide to hold off on that question and forbid it for now.

  3. solson commented on Jun 14, 2016

    @solson
    ContributorAuthor

    Yeah, I'd forbid it for now and relax it later if necessary.

  4. changed the title [-]function pointers need to be checked against their original types[/-] [+]Function pointers need to be checked against their original types[/+] on Jun 15, 2016
  5. added a commit that references this issue on Feb 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions