static __always_inline bool memory_is_poisoned_2_4_8(unsigned long addr, unsigned long size) { u8 *shadow_addr = (u8 *)kasan_mem_to_shadow((void *)addr); /* * Access crosses 8(shadow size)-byte boundary. Such access maps * into 2 shadow bytes, so we need to check them both. */ if (unlikely(((addr + size - 1) & KASAN_SHADOW_MASK) < size - 1)) return *shadow_addr || memory_is_poisoned_1(addr + size - 1); return memory_is_poisoned_1(addr + size - 1); }
static __always_inline bool memory_is_poisoned_16(unsigned long addr) { u16 *shadow_addr = (u16 *)kasan_mem_to_shadow((void *)addr); /* Unaligned 16-bytes access maps into 3 shadow bytes. */ if (unlikely(!IS_ALIGNED(addr, KASAN_SHADOW_SCALE_SIZE))) return *shadow_addr || memory_is_poisoned_1(addr + 15); return *shadow_addr; }
static __always_inline bool memory_is_poisoned(unsigned long addr, size_t size) { if (__builtin_constant_p(size)) { switch (size) { case 1: return memory_is_poisoned_1(addr); case 2: case 4: case 8: return memory_is_poisoned_2_4_8(addr, size); case 16: return memory_is_poisoned_16(addr); default: BUILD_BUG(); } } return memory_is_poisoned_n(addr, size); }
static __always_inline bool memory_is_poisoned_8(unsigned long addr) { u16 *shadow_addr = (u16 *)kasan_mem_to_shadow((void *)addr); if (unlikely(*shadow_addr)) { if (memory_is_poisoned_1(addr + 7)) return true; /* * If single shadow byte covers 8-byte access, we don't * need to do anything more. Otherwise, test the first * shadow byte. */ if (likely(IS_ALIGNED(addr, KASAN_SHADOW_SCALE_SIZE))) return false; return unlikely(*(u8 *)shadow_addr); } return false; }
static __always_inline bool memory_is_poisoned_16(unsigned long addr) { u32 *shadow_addr = (u32 *)kasan_mem_to_shadow((void *)addr); if (unlikely(*shadow_addr)) { u16 shadow_first_bytes = *(u16 *)shadow_addr; if (unlikely(shadow_first_bytes)) return true; /* * If two shadow bytes covers 16-byte access, we don't * need to do anything more. Otherwise, test the last * shadow byte. */ if (likely(IS_ALIGNED(addr, KASAN_SHADOW_SCALE_SIZE))) return false; return memory_is_poisoned_1(addr + 15); } return false; }