In the following code snippet an extra 2 bits (22–23) leak through due to $FFFFFF vs the correct $3FFFFF contribute (idx mod 4) * 4MB of error to the result.
function vtop(address : uint32) : uint32;
var
idx : uint32;
paddress : uint32;
loadd : uint32;
begin
push_trace('vmemorymanager.vtop');
idx:= address SHR 22;
paddress:= uint32(KERNEL_PAGE_DIRECTORY^[idx].address) SHL 12;
loadd:= address AND $FFFFFF;
vtop:= paddress + loadd;
pop_trace;
end;
Kernel pages are mapped starting at KERNEL_PAGE_NUMBER = $C0000000 SHR 22 = 768. And 768 mod 4 = 0. So for any address in that first kernel page, bits 22–23 are both zero, and as such, the wrong mask produces the identical result to the correct one. Which is why this has gone unnoticed for so long.
Proposed fix is a simple modification, where the $FFFFFF bitmask becomes $3FFFFF.
function vtop(address : uint32) : uint32;
var
idx : uint32;
paddress : uint32;
loadd : uint32;
begin
push_trace('vmemorymanager.vtop');
idx:= address SHR 22;
paddress:= uint32(KERNEL_PAGE_DIRECTORY^[idx].address) SHL 12;
loadd:= address AND $3FFFFF;
vtop:= paddress + loadd;
pop_trace;
end;
In the following code snippet an extra 2 bits (22–23) leak through due to $FFFFFF vs the correct $3FFFFF contribute (idx mod 4) * 4MB of error to the result.
```
function vtop(address : uint32) : uint32;
var
idx : uint32;
paddress : uint32;
loadd : uint32;
begin
push_trace('vmemorymanager.vtop');
idx:= address SHR 22;
paddress:= uint32(KERNEL_PAGE_DIRECTORY^[idx].address) SHL 12;
loadd:= address AND $FFFFFF;
vtop:= paddress + loadd;
pop_trace;
end;
```
Kernel pages are mapped starting at KERNEL_PAGE_NUMBER = $C0000000 SHR 22 = 768. And 768 mod 4 = 0. So for any address in that first kernel page, bits 22–23 are both zero, and as such, the wrong mask produces the identical result to the correct one. Which is why this has gone unnoticed for so long.
Proposed fix is a simple modification, where the $FFFFFF bitmask becomes $3FFFFF.
```
function vtop(address : uint32) : uint32;
var
idx : uint32;
paddress : uint32;
loadd : uint32;
begin
push_trace('vmemorymanager.vtop');
idx:= address SHR 22;
paddress:= uint32(KERNEL_PAGE_DIRECTORY^[idx].address) SHL 12;
loadd:= address AND $3FFFFF;
vtop:= paddress + loadd;
pop_trace;
end;
```
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
In the following code snippet an extra 2 bits (22–23) leak through due to $FFFFFF vs the correct $3FFFFF contribute (idx mod 4) * 4MB of error to the result.
Kernel pages are mapped starting at KERNEL_PAGE_NUMBER = $C0000000 SHR 22 = 768. And 768 mod 4 = 0. So for any address in that first kernel page, bits 22–23 are both zero, and as such, the wrong mask produces the identical result to the correct one. Which is why this has gone unnoticed for so long.
Proposed fix is a simple modification, where the $FFFFFF bitmask becomes $3FFFFF.