Skip to content

Commit b2b430e

Browse files
FnAbi checks
1 parent 8815286 commit b2b430e

File tree

3 files changed

+63
-3
lines changed

3 files changed

+63
-3
lines changed

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
54a0f387ea8c7bcb79b8e40c074a484d31b51990
1+
8c07d140e00dfa5b0988754051d07d8a91ff01f7

src/helpers.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
1414
use rustc_middle::middle::dependency_format::Linkage;
1515
use rustc_middle::middle::exported_symbols::ExportedSymbol;
1616
use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, MaybeResult, TyAndLayout};
17-
use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, UintTy};
17+
use rustc_middle::ty::{self, Binder, FloatTy, FnSig, IntTy, Ty, TyCtxt, UintTy};
1818
use rustc_session::config::CrateType;
1919
use rustc_span::{Span, Symbol};
2020
use rustc_target::callconv::{Conv, FnAbi};
@@ -1187,6 +1187,58 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
11871187

11881188
interp_ok(array)
11891189
}
1190+
1191+
fn check_fn_abi(
1192+
&mut self,
1193+
input_args: &[Ty<'tcx>],
1194+
output_ty: Ty<'tcx>,
1195+
safety: Safety,
1196+
abi: ExternAbi,
1197+
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
1198+
) -> InterpResult<'tcx, ()> {
1199+
let this = self.eval_context_mut();
1200+
let mut inputs_and_output = input_args.to_vec();
1201+
inputs_and_output.push(output_ty);
1202+
let fn_sig_binder = Binder::dummy(FnSig {
1203+
inputs_and_output: this.machine.tcx.mk_type_list(&inputs_and_output),
1204+
c_variadic: false,
1205+
safety,
1206+
abi,
1207+
});
1208+
let exp_fn_abi = this.fn_abi_of_fn_ptr(fn_sig_binder, Default::default())?;
1209+
if !self.check_abi_compat(fn_abi, exp_fn_abi)? {
1210+
throw_ub_format!("Invalid argument type: ABI mismatch");
1211+
}
1212+
interp_ok(())
1213+
}
1214+
1215+
// Check where two FnAbi's are compatible
1216+
fn check_abi_compat(
1217+
&mut self,
1218+
caller_fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
1219+
callee_fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
1220+
) -> InterpResult<'tcx, bool> {
1221+
let this = self.eval_context_mut();
1222+
let caller_args_abi = &caller_fn_abi.args;
1223+
let callee_args_abi = &callee_fn_abi.args;
1224+
1225+
if caller_fn_abi.c_variadic != callee_fn_abi.c_variadic
1226+
|| callee_fn_abi.fixed_count != caller_fn_abi.fixed_count
1227+
|| callee_fn_abi.can_unwind != caller_fn_abi.can_unwind
1228+
|| !this.check_argument_compat(&caller_fn_abi.ret, &callee_fn_abi.ret)?
1229+
|| !caller_args_abi
1230+
.iter()
1231+
.zip(callee_args_abi.iter())
1232+
.map(|(caller_arg, callee_arg)| this.check_argument_compat(caller_arg, callee_arg))
1233+
.collect::<InterpResult<'tcx, Vec<bool>>>()?
1234+
.into_iter()
1235+
.all(|b| b)
1236+
{
1237+
return interp_ok(false);
1238+
}
1239+
1240+
interp_ok(true)
1241+
}
11901242
}
11911243

11921244
impl<'tcx> MiriMachine<'tcx> {

src/shims/unix/foreign_items.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use std::ffi::OsStr;
22
use std::str;
33

4-
use rustc_abi::Size;
4+
use rustc_abi::{ExternAbi, Size};
5+
use rustc_hir::Safety;
56
use rustc_middle::ty::Ty;
67
use rustc_middle::ty::layout::LayoutOf;
78
use rustc_span::Symbol;
@@ -200,6 +201,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
200201
this.write(fd, buf, count, Some(offset), dest)?;
201202
}
202203
"close" => {
204+
this.check_fn_abi(
205+
&[this.machine.layouts.i32.ty],
206+
this.machine.layouts.i32.ty,
207+
Safety::Unsafe,
208+
ExternAbi::C { unwind: false },
209+
abi,
210+
)?;
203211
let [fd] = this.check_shim(abi, Conv::C, link_name, args)?;
204212
let result = this.close(fd)?;
205213
this.write_scalar(result, dest)?;

0 commit comments

Comments
 (0)