Skip to content
This repository has been archived by the owner on Oct 12, 2022. It is now read-only.

Commit

Permalink
Prevent buffer overread in core.internal.gc.bits
Browse files Browse the repository at this point in the history
Bug found with AddressSanitizer, for the unittest with this code:
```
        GCBits bits;
        bits.alloc(10000);
        auto data = bits.data;

        GCBits src;
        src.alloc(67);
        src.data[0] = 0x4;

        bits.copyRangeRepeating(2, 10000, src.data, 67);  <---- triggers the bug
```
The bug happens for the loop iteration in copyRangeRepeating that calls copyRange where these are the values of variables in copyRange:
cntWords = 2
target = 1342
last = 1408
lastWord = 22
lastOff = 0
firstOff = 62
len = 67
Overread happens on `source[cntWords]`.

Proof of correctness of this fix:
Let's assume `firstOff == 3`, then `source[cntWords] << firstOff` has value `0bxx...xxxxx000` in bits.
For `lastOff == 2`, then `mask = (BITS_2 << lastOff) - 1  ==  (2 << lastOff) - 1 == 0b1000 - 1 == 0b111`. `src&mask` would always be 0.
For `lastOff == 3`, then `mask = 0b1111`. `src&mask` would be 0bx000, i.e. actual bits of the value read would be used.
  • Loading branch information
JohanEngelen authored and dlang-bot committed Mar 4, 2022
1 parent 402d1a3 commit badb3ce
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/core/internal/gc/bits.d
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,9 @@ struct GCBits
size_t cntWords = lastWord - firstWord;
copyWordsShifted(firstWord, cntWords, firstOff, source);

wordtype src = (source[cntWords - 1] >> (BITS_PER_WORD - firstOff)) | (source[cntWords] << firstOff);
wordtype src = (source[cntWords - 1] >> (BITS_PER_WORD - firstOff));
if (lastOff >= firstOff) // prevent buffer overread
src |= (source[cntWords] << firstOff);
wordtype mask = (BITS_2 << lastOff) - 1;
data[lastWord] = (data[lastWord] & ~mask) | (src & mask);
}
Expand Down

0 comments on commit badb3ce

Please sign in to comment.