Commit 093f70a
Fix soundness issue: avoid UB in swap_columns/swap_elements when indices alias
When swap_columns is called with a == b, the previous implementation created
two mutable references (&mut self[a] and &mut self[b]) to the same memory
location (aliased &mut UB). Additionally, even for distinct indices a != b,
using ptr::swap(&mut self[a], &mut self[b]) is UB under Miri (Stacked
Borrows): the second IndexMut call creates a new unique reborrow of all of
self, invalidating the tag from the first call.
The same class of bug existed in:
- Array::swap_elements (structure.rs)
- Matrix{2,3,4}::swap_columns
- Matrix{2,3,4}::swap_elements
Fix: since S: BaseFloat implies S: Copy, column vectors and scalar elements
are Copy. We can swap entirely without unsafe by using a temporary variable:
let tmp = self[a];
self[a] = self[b];
self[b] = tmp;
This avoids creating multiple mutable references simultaneously and requires
no unsafe code at all. Verified clean under Miri.
Tests added in tests/matrix.rs covering all three matrix sizes for:
- swap_columns with equal indices (no-op, was UB)
- swap_columns with distinct indices (correct swap)
- swap_elements with same position (no-op, was UB)
- swap_elements with same column, different rows
Note: the tests verify correctness but do not catch the soundness bug in a
regular cargo test run. Use cargo +nightly miri test to detect aliasing UB.
Fixes: #565
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>1 parent ff840cb commit 093f70a
3 files changed
Lines changed: 177 additions & 10 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
580 | 580 | | |
581 | 581 | | |
582 | 582 | | |
583 | | - | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
584 | 590 | | |
585 | 591 | | |
586 | 592 | | |
587 | 593 | | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
588 | 597 | | |
589 | 598 | | |
590 | | - | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
591 | 603 | | |
592 | 604 | | |
593 | 605 | | |
| |||
679 | 691 | | |
680 | 692 | | |
681 | 693 | | |
682 | | - | |
| 694 | + | |
| 695 | + | |
| 696 | + | |
| 697 | + | |
| 698 | + | |
| 699 | + | |
| 700 | + | |
683 | 701 | | |
684 | 702 | | |
685 | 703 | | |
686 | 704 | | |
| 705 | + | |
| 706 | + | |
| 707 | + | |
687 | 708 | | |
688 | 709 | | |
689 | | - | |
| 710 | + | |
| 711 | + | |
| 712 | + | |
| 713 | + | |
690 | 714 | | |
691 | 715 | | |
692 | 716 | | |
| |||
795 | 819 | | |
796 | 820 | | |
797 | 821 | | |
798 | | - | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
799 | 829 | | |
800 | 830 | | |
801 | 831 | | |
802 | 832 | | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
803 | 836 | | |
804 | 837 | | |
805 | | - | |
| 838 | + | |
| 839 | + | |
| 840 | + | |
| 841 | + | |
806 | 842 | | |
807 | 843 | | |
808 | 844 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
72 | 72 | | |
73 | 73 | | |
74 | 74 | | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
79 | 82 | | |
80 | 83 | | |
81 | 84 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
16 | 16 | | |
17 | 17 | | |
18 | 18 | | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
19 | 147 | | |
20 | 148 | | |
21 | 149 | | |
| |||
0 commit comments