@@ -690,6 +690,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
690690 let right = this. read_pointer ( right) ?;
691691 let n = Size :: from_bytes ( this. read_target_usize ( n) ?) ;
692692
693+ // C requires that this must always be a valid pointer (C18 §7.1.4).
694+ this. ptr_get_alloc_id ( left) ?;
695+ this. ptr_get_alloc_id ( right) ?;
696+
693697 let result = {
694698 let left_bytes = this. read_bytes_ptr_strip_provenance ( left, n) ?;
695699 let right_bytes = this. read_bytes_ptr_strip_provenance ( right, n) ?;
@@ -714,6 +718,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
714718 #[ allow( clippy:: cast_sign_loss, clippy:: cast_possible_truncation) ]
715719 let val = val as u8 ;
716720
721+ // C requires that this must always be a valid pointer (C18 §7.1.4).
722+ this. ptr_get_alloc_id ( ptr) ?;
723+
717724 if let Some ( idx) = this
718725 . read_bytes_ptr_strip_provenance ( ptr, Size :: from_bytes ( num) ) ?
719726 . iter ( )
@@ -738,6 +745,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
738745 #[ allow( clippy:: cast_sign_loss, clippy:: cast_possible_truncation) ]
739746 let val = val as u8 ;
740747
748+ // C requires that this must always be a valid pointer (C18 §7.1.4).
749+ this. ptr_get_alloc_id ( ptr) ?;
750+
741751 let idx = this
742752 . read_bytes_ptr_strip_provenance ( ptr, Size :: from_bytes ( num) ) ?
743753 . iter ( )
@@ -752,6 +762,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
752762 "strlen" => {
753763 let [ ptr] = this. check_shim ( abi, Abi :: C { unwind : false } , link_name, args) ?;
754764 let ptr = this. read_pointer ( ptr) ?;
765+ // This reads at least 1 byte, so we are already enforcing that this is a valid pointer.
755766 let n = this. read_c_str ( ptr) ?. len ( ) ;
756767 this. write_scalar (
757768 Scalar :: from_target_usize ( u64:: try_from ( n) . unwrap ( ) , this) ,
@@ -791,6 +802,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
791802 // pointer provenance is preserved by this implementation of `strcpy`.
792803 // That is probably overly cautious, but there also is no fundamental
793804 // reason to have `strcpy` destroy pointer provenance.
805+ // This reads at least 1 byte, so we are already enforcing that this is a valid pointer.
794806 let n = this. read_c_str ( ptr_src) ?. len ( ) . checked_add ( 1 ) . unwrap ( ) ;
795807 this. mem_copy (
796808 ptr_src,
0 commit comments