Commit cf8749e
authored
Fix provenance UB and alignment UB (#27)
Fix provenance UB and alignment UB
These issues were unlikely to cause any miscompilations
today, but it's best to fix them right away. Thanks to
miri for finding these issues!
Alignment:
In the default configuration (**not** gecko-ffi), types with alignment
equal to the header size (16 on x64; 8 on x86) were incorrectly handled
by an optimization. This could result in misaligned empty slices
being produced when accessing a 0-capacity ThinVec
(which is produced by ThinVec::new()).
Such a slice of course can't be used to load or store any memory,
but Rust requires references (including slices) to always be aligned
even if they aren't ever used to load/store memory.
The destructor for ThinVec creates a slice to its elements, so
this dropping any ThinVec::new() with such a highly aligned
type was technically UB. That said, it's quite unlikely it could
have lead to miscompilations in practice, since the compiler
would be unable to "see" the misalignment and Rust doesn't
currently do any runtime optimizations based on alignment
(such as Option-style enum layout optimizations).
Types with higher and lower alignments were handled fine,
it was just this *specific* alignment that was taking the wrong
path.
The specific issue is that 0-cap ThinVecs all point to statically
allocated empty singleton. This singleton is designed to
Do The Right Thing without additional branches for many
operations, meaning we get non-allocating ThinVec::new()
*without* needing to compromise the performance of most
other operations. One such "just work" situation is the
data pointer, which will generally just be one-past-the-end
of the empty singleton, which is in-bounds for the singleton.
But for highly-aligned elements, the data pointer needs
to be "padded" and that would go beyond the static
singleton's "allocation". So in general we actually check
if cap==0 and return NonNull::dangling for the data pointer.
The *optimization* was to identify the cases where no
such padding was required and statically eliminate the
cap == 0 path. Unfortunately "has no padding" isn't
sufficient: in the specific case of align==header_size,
there is no padding but the singleton is underaligned!
In this case the NonNull::dangling path must be taken.
The code has been fixed and the optimization now
works correctly for all alignments.
Provenance:
Many places ran afoul of Stacked Borrows. The issues found were:
A &Header cannot be used to get a useful pointer to data beyond it,
because the pointer from the as-cast of the &Header only has
provenance over the Header.
After a set_len call that decreases the length, it is invalid to create a
slice then try to get_unchecked into the region between the old and new
length, because the reference in the slice that the ThinVec now Derefs
to does not have provenance over that region. Alternatively, this is UB
because the docs stipulate that you're not allowed to use
`get_unchecked` to index out of bounds.
I think the use of align_offset in tests is subtly wrong, align_offset
seems to be for optimizations only. The docs say that a valid
implementation may always return usize::MAX.1 parent 9705b3c commit cf8749e
1 file changed
+104
-36
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
247 | 247 | | |
248 | 248 | | |
249 | 249 | | |
250 | | - | |
251 | | - | |
252 | | - | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
253 | 266 | | |
254 | 267 | | |
255 | 268 | | |
| |||
264 | 277 | | |
265 | 278 | | |
266 | 279 | | |
267 | | - | |
268 | | - | |
269 | | - | |
270 | | - | |
271 | | - | |
272 | | - | |
273 | | - | |
274 | | - | |
275 | | - | |
276 | | - | |
277 | | - | |
278 | | - | |
279 | | - | |
280 | | - | |
281 | | - | |
282 | | - | |
283 | | - | |
284 | 280 | | |
285 | 281 | | |
286 | 282 | | |
| |||
321 | 317 | | |
322 | 318 | | |
323 | 319 | | |
324 | | - | |
| 320 | + | |
325 | 321 | | |
326 | 322 | | |
327 | | - | |
| 323 | + | |
328 | 324 | | |
329 | 325 | | |
330 | 326 | | |
| |||
442 | 438 | | |
443 | 439 | | |
444 | 440 | | |
445 | | - | |
446 | | - | |
447 | | - | |
448 | | - | |
449 | | - | |
450 | | - | |
| 441 | + | |
451 | 442 | | |
452 | 443 | | |
453 | 444 | | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
454 | 454 | | |
455 | | - | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
456 | 461 | | |
457 | 462 | | |
458 | 463 | | |
| |||
470 | 475 | | |
471 | 476 | | |
472 | 477 | | |
473 | | - | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
474 | 519 | | |
475 | 520 | | |
476 | 521 | | |
| |||
565 | 610 | | |
566 | 611 | | |
567 | 612 | | |
568 | | - | |
| 613 | + | |
569 | 614 | | |
570 | 615 | | |
571 | 616 | | |
| |||
915 | 960 | | |
916 | 961 | | |
917 | 962 | | |
918 | | - | |
| 963 | + | |
919 | 964 | | |
920 | 965 | | |
921 | 966 | | |
| |||
931 | 976 | | |
932 | 977 | | |
933 | 978 | | |
934 | | - | |
935 | | - | |
| 979 | + | |
| 980 | + | |
| 981 | + | |
936 | 982 | | |
937 | 983 | | |
938 | 984 | | |
| |||
1373 | 1419 | | |
1374 | 1420 | | |
1375 | 1421 | | |
| 1422 | + | |
| 1423 | + | |
| 1424 | + | |
| 1425 | + | |
| 1426 | + | |
| 1427 | + | |
| 1428 | + | |
| 1429 | + | |
| 1430 | + | |
| 1431 | + | |
| 1432 | + | |
| 1433 | + | |
| 1434 | + | |
| 1435 | + | |
| 1436 | + | |
| 1437 | + | |
| 1438 | + | |
| 1439 | + | |
| 1440 | + | |
| 1441 | + | |
| 1442 | + | |
| 1443 | + | |
1376 | 1444 | | |
1377 | 1445 | | |
1378 | 1446 | | |
| |||
2654 | 2722 | | |
2655 | 2723 | | |
2656 | 2724 | | |
2657 | | - | |
| 2725 | + | |
2658 | 2726 | | |
2659 | | - | |
| 2727 | + | |
2660 | 2728 | | |
2661 | 2729 | | |
2662 | 2730 | | |
| |||
0 commit comments