@@ -442,27 +442,30 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
442442
443443 // Issue #27023: must add any necessary padding to `size`
444444 // (to make it a multiple of `align`) before returning it.
445- //
446- // Namely, the returned size should be, in C notation:
447- //
448- // `size + ((size & (align-1)) ? align : 0)`
449- //
450- // emulated via the semi-standard fast bit trick:
451- //
452- // `(size + (align-1)) & -align`
453-
454- Ok ( Some ( ( size. align_to ( align) , align) ) )
445+ let size = size. align_to ( align) ;
446+
447+ // Check if this brought us over the size limit.
448+ if size. bytes ( ) >= self . tcx . data_layout ( ) . obj_size_bound ( ) {
449+ throw_ub_format ! ( "wide pointer metadata contains invalid information: \
450+ total size is bigger than largest supported object") ;
451+ }
452+ Ok ( Some ( ( size, align) ) )
455453 }
456454 ty:: Dynamic ( ..) => {
457455 let vtable = metadata. expect ( "dyn trait fat ptr must have vtable" ) ;
458- // the second entry in the vtable is the dynamic size of the object .
456+ // Read size and align from vtable (already checks size) .
459457 Ok ( Some ( self . read_size_and_align_from_vtable ( vtable) ?) )
460458 }
461459
462460 ty:: Slice ( _) | ty:: Str => {
463461 let len = metadata. expect ( "slice fat ptr must have vtable" ) . to_usize ( self ) ?;
464462 let elem = layout. field ( self , 0 ) ?;
465- Ok ( Some ( ( elem. size * len, elem. align . abi ) ) )
463+
464+ // Make sure the slice is not too big.
465+ let size = elem. size . checked_mul ( len, & * self . tcx )
466+ . ok_or_else ( || err_ub_format ! ( "invalid slice: \
467+ total size is bigger than largest supported object") ) ?;
468+ Ok ( Some ( ( size, elem. align . abi ) ) )
466469 }
467470
468471 ty:: Foreign ( _) => {
0 commit comments