Skip to content

Commit

Permalink
FnAbi checks
Browse files Browse the repository at this point in the history
  • Loading branch information
geetanshjuneja committed Feb 15, 2025
1 parent 8815286 commit b2b430e
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 3 deletions.
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
54a0f387ea8c7bcb79b8e40c074a484d31b51990
8c07d140e00dfa5b0988754051d07d8a91ff01f7
54 changes: 53 additions & 1 deletion src/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::middle::dependency_format::Linkage;
use rustc_middle::middle::exported_symbols::ExportedSymbol;
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, MaybeResult, TyAndLayout};
use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, UintTy};
use rustc_middle::ty::{self, Binder, FloatTy, FnSig, IntTy, Ty, TyCtxt, UintTy};
use rustc_session::config::CrateType;
use rustc_span::{Span, Symbol};
use rustc_target::callconv::{Conv, FnAbi};
Expand Down Expand Up @@ -1187,6 +1187,58 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

interp_ok(array)
}

fn check_fn_abi(
&mut self,
input_args: &[Ty<'tcx>],
output_ty: Ty<'tcx>,
safety: Safety,
abi: ExternAbi,
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
) -> InterpResult<'tcx, ()> {
let this = self.eval_context_mut();
let mut inputs_and_output = input_args.to_vec();
inputs_and_output.push(output_ty);
let fn_sig_binder = Binder::dummy(FnSig {
inputs_and_output: this.machine.tcx.mk_type_list(&inputs_and_output),
c_variadic: false,
safety,
abi,
});
let exp_fn_abi = this.fn_abi_of_fn_ptr(fn_sig_binder, Default::default())?;
if !self.check_abi_compat(fn_abi, exp_fn_abi)? {
throw_ub_format!("Invalid argument type: ABI mismatch");
}
interp_ok(())
}

// Check where two FnAbi's are compatible
fn check_abi_compat(
&mut self,
caller_fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
callee_fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
) -> InterpResult<'tcx, bool> {
let this = self.eval_context_mut();
let caller_args_abi = &caller_fn_abi.args;
let callee_args_abi = &callee_fn_abi.args;

if caller_fn_abi.c_variadic != callee_fn_abi.c_variadic
|| callee_fn_abi.fixed_count != caller_fn_abi.fixed_count
|| callee_fn_abi.can_unwind != caller_fn_abi.can_unwind
|| !this.check_argument_compat(&caller_fn_abi.ret, &callee_fn_abi.ret)?
|| !caller_args_abi
.iter()
.zip(callee_args_abi.iter())
.map(|(caller_arg, callee_arg)| this.check_argument_compat(caller_arg, callee_arg))
.collect::<InterpResult<'tcx, Vec<bool>>>()?
.into_iter()
.all(|b| b)
{
return interp_ok(false);
}

interp_ok(true)
}
}

impl<'tcx> MiriMachine<'tcx> {
Expand Down
10 changes: 9 additions & 1 deletion src/shims/unix/foreign_items.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use std::ffi::OsStr;
use std::str;

use rustc_abi::Size;
use rustc_abi::{ExternAbi, Size};
use rustc_hir::Safety;
use rustc_middle::ty::Ty;
use rustc_middle::ty::layout::LayoutOf;
use rustc_span::Symbol;
Expand Down Expand Up @@ -200,6 +201,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write(fd, buf, count, Some(offset), dest)?;
}
"close" => {
this.check_fn_abi(
&[this.machine.layouts.i32.ty],
this.machine.layouts.i32.ty,
Safety::Unsafe,
ExternAbi::C { unwind: false },
abi,
)?;
let [fd] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.close(fd)?;
this.write_scalar(result, dest)?;
Expand Down

0 comments on commit b2b430e

Please sign in to comment.