@@ -442,27 +442,30 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
442
442
443
443
// Issue #27023: must add any necessary padding to `size`
444
444
// (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) ) )
455
453
}
456
454
ty:: Dynamic ( ..) => {
457
455
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) .
459
457
Ok ( Some ( self . read_size_and_align_from_vtable ( vtable) ?) )
460
458
}
461
459
462
460
ty:: Slice ( _) | ty:: Str => {
463
461
let len = metadata. expect ( "slice fat ptr must have vtable" ) . to_usize ( self ) ?;
464
462
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 ) ) )
466
469
}
467
470
468
471
ty:: Foreign ( _) => {
0 commit comments