Skip to content

Commit a417911

Browse files
committed
catch overflow in slice size computation
1 parent 53c540a commit a417911

File tree

4 files changed

+69
-43
lines changed

4 files changed

+69
-43
lines changed

compiler/rustc_const_eval/src/interpret/eval_context.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -694,7 +694,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
694694
let elem = layout.field(self, 0);
695695

696696
// Make sure the slice is not too big.
697-
let size = elem.size * len;
697+
let size = elem.size.bytes().saturating_mul(len); // we rely on `max_size_of_val` being smaller than `u64::MAX`.
698+
let size = Size::from_bytes(size);
698699
if size > self.max_size_of_val() {
699700
throw_ub!(InvalidMeta("slice is bigger than largest supported object"));
700701
}

src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr

+32-21
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,17 @@ LL | const SLICE_TOO_LONG: &[u8] = unsafe { mem::transmute((&42u8, 999usize)) };
104104
error[E0080]: it is undefined behavior to use this value
105105
--> $DIR/ub-wide-ptr.rs:71:1
106106
|
107+
LL | const SLICE_TOO_LONG_OVERFLOW: &[u32] = unsafe { mem::transmute((&42u32, isize::MAX)) };
108+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid reference metadata: slice is bigger than largest supported object
109+
|
110+
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
111+
= note: the raw bytes of the constant (size: 8, align: 4) {
112+
╾─allocN─╼ ff ff ff 7f │ ╾──╼....
113+
}
114+
115+
error[E0080]: it is undefined behavior to use this value
116+
--> $DIR/ub-wide-ptr.rs:74:1
117+
|
107118
LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
108119
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
109120
|
@@ -113,7 +124,7 @@ LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) };
113124
}
114125

115126
error[E0080]: it is undefined behavior to use this value
116-
--> $DIR/ub-wide-ptr.rs:74:1
127+
--> $DIR/ub-wide-ptr.rs:77:1
117128
|
118129
LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999usize)) };
119130
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a dangling box (going beyond the bounds of its allocation)
@@ -124,7 +135,7 @@ LL | const SLICE_TOO_LONG_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, 999us
124135
}
125136

126137
error[E0080]: it is undefined behavior to use this value
127-
--> $DIR/ub-wide-ptr.rs:77:1
138+
--> $DIR/ub-wide-ptr.rs:80:1
128139
|
129140
LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) };
130141
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
@@ -135,7 +146,7 @@ LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)
135146
}
136147

137148
error[E0080]: it is undefined behavior to use this value
138-
--> $DIR/ub-wide-ptr.rs:81:1
149+
--> $DIR/ub-wide-ptr.rs:84:1
139150
|
140151
LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
141152
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>[0]: encountered 0x03, but expected a boolean
@@ -146,29 +157,29 @@ LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }];
146157
}
147158

148159
error[E0080]: it is undefined behavior to use this value
149-
--> $DIR/ub-wide-ptr.rs:87:1
160+
--> $DIR/ub-wide-ptr.rs:90:1
150161
|
151162
LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]);
152163
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>.0: encountered 0x03, but expected a boolean
153164
|
154165
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
155166
= note: the raw bytes of the constant (size: 4, align: 4) {
156-
allocN─╼ │ ╾──╼
167+
╾allocN─╼ │ ╾──╼
157168
}
158169

159170
error[E0080]: it is undefined behavior to use this value
160-
--> $DIR/ub-wide-ptr.rs:90:1
171+
--> $DIR/ub-wide-ptr.rs:93:1
161172
|
162173
LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]);
163174
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>.1[0]: encountered 0x03, but expected a boolean
164175
|
165176
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior.
166177
= note: the raw bytes of the constant (size: 4, align: 4) {
167-
allocN─╼ │ ╾──╼
178+
╾allocN─╼ │ ╾──╼
168179
}
169180

170181
error[E0080]: it is undefined behavior to use this value
171-
--> $DIR/ub-wide-ptr.rs:97:1
182+
--> $DIR/ub-wide-ptr.rs:100:1
172183
|
173184
LL | / const RAW_SLICE_LENGTH_UNINIT: *const [u8] = unsafe {
174185
LL | |
@@ -183,7 +194,7 @@ LL | | };
183194
}
184195

185196
error[E0080]: it is undefined behavior to use this value
186-
--> $DIR/ub-wide-ptr.rs:105:1
197+
--> $DIR/ub-wide-ptr.rs:108:1
187198
|
188199
LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u8))) };
189200
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0: encountered too small vtable
@@ -194,7 +205,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_1: W<&dyn Trait> = unsafe { mem::transmute(W((
194205
}
195206

196207
error[E0080]: it is undefined behavior to use this value
197-
--> $DIR/ub-wide-ptr.rs:108:1
208+
--> $DIR/ub-wide-ptr.rs:111:1
198209
|
199210
LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &3u64))) };
200211
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0: encountered too small vtable
@@ -205,7 +216,7 @@ LL | const TRAIT_OBJ_SHORT_VTABLE_2: W<&dyn Trait> = unsafe { mem::transmute(W((
205216
}
206217

207218
error[E0080]: it is undefined behavior to use this value
208-
--> $DIR/ub-wide-ptr.rs:111:1
219+
--> $DIR/ub-wide-ptr.rs:114:1
209220
|
210221
LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, 4usize))) };
211222
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0: encountered dangling vtable pointer in wide pointer
@@ -216,7 +227,7 @@ LL | const TRAIT_OBJ_INT_VTABLE: W<&dyn Trait> = unsafe { mem::transmute(W((&92u
216227
}
217228

218229
error[E0080]: it is undefined behavior to use this value
219-
--> $DIR/ub-wide-ptr.rs:113:1
230+
--> $DIR/ub-wide-ptr.rs:116:1
220231
|
221232
LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92u8, &[0u8; 128])) };
222233
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered unaligned vtable pointer in wide pointer
@@ -227,7 +238,7 @@ LL | const TRAIT_OBJ_UNALIGNED_VTABLE: &dyn Trait = unsafe { mem::transmute((&92
227238
}
228239

229240
error[E0080]: it is undefined behavior to use this value
230-
--> $DIR/ub-wide-ptr.rs:115:1
241+
--> $DIR/ub-wide-ptr.rs:118:1
231242
|
232243
LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92u8, &[0usize; 8])) };
233244
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function)
@@ -238,7 +249,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NULL: &dyn Trait = unsafe { mem::transmute((&92
238249
}
239250

240251
error[E0080]: it is undefined behavior to use this value
241-
--> $DIR/ub-wide-ptr.rs:117:1
252+
--> $DIR/ub-wide-ptr.rs:120:1
242253
|
243254
LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u8, &[1usize; 8])) };
244255
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered invalid drop function pointer in vtable (not pointing to a function)
@@ -249,7 +260,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_INT: &dyn Trait = unsafe { mem::transmute((&92u
249260
}
250261

251262
error[E0080]: it is undefined behavior to use this value
252-
--> $DIR/ub-wide-ptr.rs:119:1
263+
--> $DIR/ub-wide-ptr.rs:122:1
253264
|
254265
LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::transmute(W((&92u8, &[&42u8; 8]))) };
255266
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .0: encountered invalid drop function pointer in vtable (not pointing to a function)
@@ -260,7 +271,7 @@ LL | const TRAIT_OBJ_BAD_DROP_FN_NOT_FN_PTR: W<&dyn Trait> = unsafe { mem::trans
260271
}
261272

262273
error[E0080]: it is undefined behavior to use this value
263-
--> $DIR/ub-wide-ptr.rs:123:1
274+
--> $DIR/ub-wide-ptr.rs:126:1
264275
|
265276
LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_, &bool>(&3u8) };
266277
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<deref>.<dyn-downcast>: encountered 0x03, but expected a boolean
@@ -271,7 +282,7 @@ LL | const TRAIT_OBJ_CONTENT_INVALID: &dyn Trait = unsafe { mem::transmute::<_,
271282
}
272283

273284
error[E0080]: it is undefined behavior to use this value
274-
--> $DIR/ub-wide-ptr.rs:127:1
285+
--> $DIR/ub-wide-ptr.rs:130:1
275286
|
276287
LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute((&92u8, 0usize)) };
277288
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling vtable pointer in wide pointer
@@ -282,7 +293,7 @@ LL | const RAW_TRAIT_OBJ_VTABLE_NULL: *const dyn Trait = unsafe { mem::transmute
282293
}
283294

284295
error[E0080]: it is undefined behavior to use this value
285-
--> $DIR/ub-wide-ptr.rs:129:1
296+
--> $DIR/ub-wide-ptr.rs:132:1
286297
|
287298
LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transmute((&92u8, &3u64)) };
288299
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered too small vtable
@@ -293,17 +304,17 @@ LL | const RAW_TRAIT_OBJ_VTABLE_INVALID: *const dyn Trait = unsafe { mem::transm
293304
}
294305

295306
error[E0080]: could not evaluate static initializer
296-
--> $DIR/ub-wide-ptr.rs:135:5
307+
--> $DIR/ub-wide-ptr.rs:138:5
297308
|
298309
LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
299310
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is not a valid pointer
300311

301312
error[E0080]: could not evaluate static initializer
302-
--> $DIR/ub-wide-ptr.rs:139:5
313+
--> $DIR/ub-wide-ptr.rs:142:5
303314
|
304315
LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
305316
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: allocN has size N, so pointer to 12 bytes starting at offset N is out-of-bounds
306317

307-
error: aborting due to 28 previous errors
318+
error: aborting due to 29 previous errors
308319

309320
For more information about this error, try `rustc --explain E0080`.

0 commit comments

Comments
 (0)