authorgravatar for carl@astholm.seCarl Åstholm <carl@astholm.se> 2023-12-19 21:14:48+01:00
committergravatar for carl@astholm.seCarl Åstholm <carl@astholm.se> 2024-01-01 16:18:57+01:00
log781c3a985c2c6e31c57165c02582aa79c286e431
treeb7beb0020c37fd91e2fd68eeb8e297be53ad1b31
parent4129996211edd30b25c23454520fd78b2a70394b

Prevent reading over a page boundary in `mem.indexOfSentinel`

The size of the slice element was not correctly taken into account when determining whether a read would cross a page boundary.

1 files changed, 3 insertions(+), 2 deletions(-)

lib/std/mem.zig+3-2
...@@ -967,14 +967,15 @@ pub fn indexOfSentinel(comptime T: type, comptime sentinel: T, p: [*:sentinel]co...@@ -967,14 +967,15 @@ pub fn indexOfSentinel(comptime T: type, comptime sentinel: T, p: [*:sentinel]co
967 // as we don't read into a new page. This should be the case for most architectures967 // as we don't read into a new page. This should be the case for most architectures
968 // which use paged memory, however should be confirmed before adding a new arch below.968 // which use paged memory, however should be confirmed before adding a new arch below.
969 .aarch64, .x86, .x86_64 => if (std.simd.suggestVectorSize(T)) |block_len| {969 .aarch64, .x86, .x86_64 => if (std.simd.suggestVectorSize(T)) |block_len| {
970 comptime std.debug.assert(std.mem.page_size % block_len == 0);
971 const Block = @Vector(block_len, T);970 const Block = @Vector(block_len, T);
972 const mask: Block = @splat(sentinel);971 const mask: Block = @splat(sentinel);
973972
973 comptime std.debug.assert(std.mem.page_size % @sizeOf(Block) == 0);
974
974 // First block may be unaligned975 // First block may be unaligned
975 const start_addr = @intFromPtr(&p[i]);976 const start_addr = @intFromPtr(&p[i]);
976 const offset_in_page = start_addr & (std.mem.page_size - 1);977 const offset_in_page = start_addr & (std.mem.page_size - 1);
977 if (offset_in_page < std.mem.page_size - block_len) {978 if (offset_in_page < std.mem.page_size - @sizeOf(Block)) {
978 // Will not read past the end of a page, full block.979 // Will not read past the end of a page, full block.
979 const block: Block = p[i..][0..block_len].*;980 const block: Block = p[i..][0..block_len].*;
980 const matches = block == mask;981 const matches = block == mask;