-
Notifications
You must be signed in to change notification settings - Fork 97
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
Valid value checks does not check char
surrogate values
#3241
Comments
I've been investigating this issue and here's what I've found out. First, the Note: 1114111 is 0x10FFFF (i.e., I tried to special-case the diff --git a/kani-compiler/src/kani_middle/transform/check_values.rs b/kani-compiler/src/kani_middle/transform/check_values.rs
index a7d0f14d270..253963a4ef6 100644
--- a/kani-compiler/src/kani_middle/transform/check_values.rs
+++ b/kani-compiler/src/kani_middle/transform/check_values.rs
@@ -839,8 +839,21 @@ pub fn ty_validity_per_offset(
ty: Ty,
current_offset: usize,
) -> Result<Vec<ValidValueReq>, String> {
+ debug!(typ=?ty, kind=?ty.kind(), "ty_validity_per_offset");
let layout = ty.layout().unwrap().shape();
let ty_req = || {
+ if ty.kind() == TyKind::RigidTy(RigidTy::Char) {
+ let shape = ty.layout().unwrap().shape();
+ let value_size = match shape.abi {
+ ValueAbi::Scalar(Scalar::Initialized { value, .. })
+ | ValueAbi::ScalarPair(Scalar::Initialized { value, .. }, _) => {
+ Some(value.size(machine_info))
+ }
+ _ => None,
+ };
+ return vec![ValidValueReq { offset: 0, size: value_size.unwrap(), valid_range: WrappingRange { start: 0, end: 0xD7FF }},
+ ValidValueReq { offset: 0, size: value_size.unwrap(), valid_range: WrappingRange { start: 0xE000, end: 0x10FFFF }}]
+ };
if let Some(mut req) = ValidValueReq::try_from_ty(machine_info, ty) However, that didn't have the intended effect as each range check is being encoded separately. In other words, this change will generate two separate checks as follows:
which doesn't work well because it's requiring It's not clear to me that the check generation should be done this way for multiple ranges. For example, in this code SourceOp::BytesValidity { ranges, target_ty, rvalue } => {
let value = body.new_assignment(rvalue, &mut source, InsertPosition::Before);
let rvalue_ptr = Rvalue::AddressOf(Mutability::Not, Place::from(value));
for range in ranges {
let result = build_limits(body, &range, rvalue_ptr.clone(), &mut source);
let msg =
format!("Undefined Behavior: Invalid value of type `{target_ty}`",);
body.add_check(
tcx,
&self.check_type,
&mut source,
InsertPosition::Before,
result,
&msg,
);
}
} in which cases does it make sense to generate more than one check? Another option is to extend |
Unfortunately, the option of extending
It's not clear to me such changes would pay off if Would it be OK to change the range loop above so that |
I tried this code:
using the following command line invocation:
with Kani version: 0.52.0
I expected to see this happen: A valid value check failure
Instead, this happened: An unreachable block being reached due to UB
The text was updated successfully, but these errors were encountered: