Path: blob/master/arch/x86/mm/kmemcheck/kmemcheck.c
10818 views
/**1* kmemcheck - a heavyweight memory checker for the linux kernel2* Copyright (C) 2007, 2008 Vegard Nossum <[email protected]>3* (With a lot of help from Ingo Molnar and Pekka Enberg.)4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License (version 2) as7* published by the Free Software Foundation.8*/910#include <linux/init.h>11#include <linux/interrupt.h>12#include <linux/kallsyms.h>13#include <linux/kernel.h>14#include <linux/kmemcheck.h>15#include <linux/mm.h>16#include <linux/module.h>17#include <linux/page-flags.h>18#include <linux/percpu.h>19#include <linux/ptrace.h>20#include <linux/string.h>21#include <linux/types.h>2223#include <asm/cacheflush.h>24#include <asm/kmemcheck.h>25#include <asm/pgtable.h>26#include <asm/tlbflush.h>2728#include "error.h"29#include "opcode.h"30#include "pte.h"31#include "selftest.h"32#include "shadow.h"333435#ifdef CONFIG_KMEMCHECK_DISABLED_BY_DEFAULT36# define KMEMCHECK_ENABLED 037#endif3839#ifdef CONFIG_KMEMCHECK_ENABLED_BY_DEFAULT40# define KMEMCHECK_ENABLED 141#endif4243#ifdef CONFIG_KMEMCHECK_ONESHOT_BY_DEFAULT44# define KMEMCHECK_ENABLED 245#endif4647int kmemcheck_enabled = KMEMCHECK_ENABLED;4849int __init kmemcheck_init(void)50{51#ifdef CONFIG_SMP52/*53* Limit SMP to use a single CPU. We rely on the fact that this code54* runs before SMP is set up.55*/56if (setup_max_cpus > 1) {57printk(KERN_INFO58"kmemcheck: Limiting number of CPUs to 1.\n");59setup_max_cpus = 1;60}61#endif6263if (!kmemcheck_selftest()) {64printk(KERN_INFO "kmemcheck: self-tests failed; disabling\n");65kmemcheck_enabled = 0;66return -EINVAL;67}6869printk(KERN_INFO "kmemcheck: Initialized\n");70return 0;71}7273early_initcall(kmemcheck_init);7475/*76* We need to parse the kmemcheck= option before any memory is allocated.77*/78static int __init param_kmemcheck(char *str)79{80if (!str)81return -EINVAL;8283sscanf(str, "%d", &kmemcheck_enabled);84return 0;85}8687early_param("kmemcheck", param_kmemcheck);8889int kmemcheck_show_addr(unsigned long address)90{91pte_t *pte;9293pte = kmemcheck_pte_lookup(address);94if (!pte)95return 0;9697set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT));98__flush_tlb_one(address);99return 1;100}101102int kmemcheck_hide_addr(unsigned long address)103{104pte_t *pte;105106pte = kmemcheck_pte_lookup(address);107if (!pte)108return 0;109110set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT));111__flush_tlb_one(address);112return 1;113}114115struct kmemcheck_context {116bool busy;117int balance;118119/*120* There can be at most two memory operands to an instruction, but121* each address can cross a page boundary -- so we may need up to122* four addresses that must be hidden/revealed for each fault.123*/124unsigned long addr[4];125unsigned long n_addrs;126unsigned long flags;127128/* Data size of the instruction that caused a fault. */129unsigned int size;130};131132static DEFINE_PER_CPU(struct kmemcheck_context, kmemcheck_context);133134bool kmemcheck_active(struct pt_regs *regs)135{136struct kmemcheck_context *data = &__get_cpu_var(kmemcheck_context);137138return data->balance > 0;139}140141/* Save an address that needs to be shown/hidden */142static void kmemcheck_save_addr(unsigned long addr)143{144struct kmemcheck_context *data = &__get_cpu_var(kmemcheck_context);145146BUG_ON(data->n_addrs >= ARRAY_SIZE(data->addr));147data->addr[data->n_addrs++] = addr;148}149150static unsigned int kmemcheck_show_all(void)151{152struct kmemcheck_context *data = &__get_cpu_var(kmemcheck_context);153unsigned int i;154unsigned int n;155156n = 0;157for (i = 0; i < data->n_addrs; ++i)158n += kmemcheck_show_addr(data->addr[i]);159160return n;161}162163static unsigned int kmemcheck_hide_all(void)164{165struct kmemcheck_context *data = &__get_cpu_var(kmemcheck_context);166unsigned int i;167unsigned int n;168169n = 0;170for (i = 0; i < data->n_addrs; ++i)171n += kmemcheck_hide_addr(data->addr[i]);172173return n;174}175176/*177* Called from the #PF handler.178*/179void kmemcheck_show(struct pt_regs *regs)180{181struct kmemcheck_context *data = &__get_cpu_var(kmemcheck_context);182183BUG_ON(!irqs_disabled());184185if (unlikely(data->balance != 0)) {186kmemcheck_show_all();187kmemcheck_error_save_bug(regs);188data->balance = 0;189return;190}191192/*193* None of the addresses actually belonged to kmemcheck. Note that194* this is not an error.195*/196if (kmemcheck_show_all() == 0)197return;198199++data->balance;200201/*202* The IF needs to be cleared as well, so that the faulting203* instruction can run "uninterrupted". Otherwise, we might take204* an interrupt and start executing that before we've had a chance205* to hide the page again.206*207* NOTE: In the rare case of multiple faults, we must not override208* the original flags:209*/210if (!(regs->flags & X86_EFLAGS_TF))211data->flags = regs->flags;212213regs->flags |= X86_EFLAGS_TF;214regs->flags &= ~X86_EFLAGS_IF;215}216217/*218* Called from the #DB handler.219*/220void kmemcheck_hide(struct pt_regs *regs)221{222struct kmemcheck_context *data = &__get_cpu_var(kmemcheck_context);223int n;224225BUG_ON(!irqs_disabled());226227if (unlikely(data->balance != 1)) {228kmemcheck_show_all();229kmemcheck_error_save_bug(regs);230data->n_addrs = 0;231data->balance = 0;232233if (!(data->flags & X86_EFLAGS_TF))234regs->flags &= ~X86_EFLAGS_TF;235if (data->flags & X86_EFLAGS_IF)236regs->flags |= X86_EFLAGS_IF;237return;238}239240if (kmemcheck_enabled)241n = kmemcheck_hide_all();242else243n = kmemcheck_show_all();244245if (n == 0)246return;247248--data->balance;249250data->n_addrs = 0;251252if (!(data->flags & X86_EFLAGS_TF))253regs->flags &= ~X86_EFLAGS_TF;254if (data->flags & X86_EFLAGS_IF)255regs->flags |= X86_EFLAGS_IF;256}257258void kmemcheck_show_pages(struct page *p, unsigned int n)259{260unsigned int i;261262for (i = 0; i < n; ++i) {263unsigned long address;264pte_t *pte;265unsigned int level;266267address = (unsigned long) page_address(&p[i]);268pte = lookup_address(address, &level);269BUG_ON(!pte);270BUG_ON(level != PG_LEVEL_4K);271272set_pte(pte, __pte(pte_val(*pte) | _PAGE_PRESENT));273set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_HIDDEN));274__flush_tlb_one(address);275}276}277278bool kmemcheck_page_is_tracked(struct page *p)279{280/* This will also check the "hidden" flag of the PTE. */281return kmemcheck_pte_lookup((unsigned long) page_address(p));282}283284void kmemcheck_hide_pages(struct page *p, unsigned int n)285{286unsigned int i;287288for (i = 0; i < n; ++i) {289unsigned long address;290pte_t *pte;291unsigned int level;292293address = (unsigned long) page_address(&p[i]);294pte = lookup_address(address, &level);295BUG_ON(!pte);296BUG_ON(level != PG_LEVEL_4K);297298set_pte(pte, __pte(pte_val(*pte) & ~_PAGE_PRESENT));299set_pte(pte, __pte(pte_val(*pte) | _PAGE_HIDDEN));300__flush_tlb_one(address);301}302}303304/* Access may NOT cross page boundary */305static void kmemcheck_read_strict(struct pt_regs *regs,306unsigned long addr, unsigned int size)307{308void *shadow;309enum kmemcheck_shadow status;310311shadow = kmemcheck_shadow_lookup(addr);312if (!shadow)313return;314315kmemcheck_save_addr(addr);316status = kmemcheck_shadow_test(shadow, size);317if (status == KMEMCHECK_SHADOW_INITIALIZED)318return;319320if (kmemcheck_enabled)321kmemcheck_error_save(status, addr, size, regs);322323if (kmemcheck_enabled == 2)324kmemcheck_enabled = 0;325326/* Don't warn about it again. */327kmemcheck_shadow_set(shadow, size);328}329330bool kmemcheck_is_obj_initialized(unsigned long addr, size_t size)331{332enum kmemcheck_shadow status;333void *shadow;334335shadow = kmemcheck_shadow_lookup(addr);336if (!shadow)337return true;338339status = kmemcheck_shadow_test_all(shadow, size);340341return status == KMEMCHECK_SHADOW_INITIALIZED;342}343344/* Access may cross page boundary */345static void kmemcheck_read(struct pt_regs *regs,346unsigned long addr, unsigned int size)347{348unsigned long page = addr & PAGE_MASK;349unsigned long next_addr = addr + size - 1;350unsigned long next_page = next_addr & PAGE_MASK;351352if (likely(page == next_page)) {353kmemcheck_read_strict(regs, addr, size);354return;355}356357/*358* What we do is basically to split the access across the359* two pages and handle each part separately. Yes, this means360* that we may now see reads that are 3 + 5 bytes, for361* example (and if both are uninitialized, there will be two362* reports), but it makes the code a lot simpler.363*/364kmemcheck_read_strict(regs, addr, next_page - addr);365kmemcheck_read_strict(regs, next_page, next_addr - next_page);366}367368static void kmemcheck_write_strict(struct pt_regs *regs,369unsigned long addr, unsigned int size)370{371void *shadow;372373shadow = kmemcheck_shadow_lookup(addr);374if (!shadow)375return;376377kmemcheck_save_addr(addr);378kmemcheck_shadow_set(shadow, size);379}380381static void kmemcheck_write(struct pt_regs *regs,382unsigned long addr, unsigned int size)383{384unsigned long page = addr & PAGE_MASK;385unsigned long next_addr = addr + size - 1;386unsigned long next_page = next_addr & PAGE_MASK;387388if (likely(page == next_page)) {389kmemcheck_write_strict(regs, addr, size);390return;391}392393/* See comment in kmemcheck_read(). */394kmemcheck_write_strict(regs, addr, next_page - addr);395kmemcheck_write_strict(regs, next_page, next_addr - next_page);396}397398/*399* Copying is hard. We have two addresses, each of which may be split across400* a page (and each page will have different shadow addresses).401*/402static void kmemcheck_copy(struct pt_regs *regs,403unsigned long src_addr, unsigned long dst_addr, unsigned int size)404{405uint8_t shadow[8];406enum kmemcheck_shadow status;407408unsigned long page;409unsigned long next_addr;410unsigned long next_page;411412uint8_t *x;413unsigned int i;414unsigned int n;415416BUG_ON(size > sizeof(shadow));417418page = src_addr & PAGE_MASK;419next_addr = src_addr + size - 1;420next_page = next_addr & PAGE_MASK;421422if (likely(page == next_page)) {423/* Same page */424x = kmemcheck_shadow_lookup(src_addr);425if (x) {426kmemcheck_save_addr(src_addr);427for (i = 0; i < size; ++i)428shadow[i] = x[i];429} else {430for (i = 0; i < size; ++i)431shadow[i] = KMEMCHECK_SHADOW_INITIALIZED;432}433} else {434n = next_page - src_addr;435BUG_ON(n > sizeof(shadow));436437/* First page */438x = kmemcheck_shadow_lookup(src_addr);439if (x) {440kmemcheck_save_addr(src_addr);441for (i = 0; i < n; ++i)442shadow[i] = x[i];443} else {444/* Not tracked */445for (i = 0; i < n; ++i)446shadow[i] = KMEMCHECK_SHADOW_INITIALIZED;447}448449/* Second page */450x = kmemcheck_shadow_lookup(next_page);451if (x) {452kmemcheck_save_addr(next_page);453for (i = n; i < size; ++i)454shadow[i] = x[i - n];455} else {456/* Not tracked */457for (i = n; i < size; ++i)458shadow[i] = KMEMCHECK_SHADOW_INITIALIZED;459}460}461462page = dst_addr & PAGE_MASK;463next_addr = dst_addr + size - 1;464next_page = next_addr & PAGE_MASK;465466if (likely(page == next_page)) {467/* Same page */468x = kmemcheck_shadow_lookup(dst_addr);469if (x) {470kmemcheck_save_addr(dst_addr);471for (i = 0; i < size; ++i) {472x[i] = shadow[i];473shadow[i] = KMEMCHECK_SHADOW_INITIALIZED;474}475}476} else {477n = next_page - dst_addr;478BUG_ON(n > sizeof(shadow));479480/* First page */481x = kmemcheck_shadow_lookup(dst_addr);482if (x) {483kmemcheck_save_addr(dst_addr);484for (i = 0; i < n; ++i) {485x[i] = shadow[i];486shadow[i] = KMEMCHECK_SHADOW_INITIALIZED;487}488}489490/* Second page */491x = kmemcheck_shadow_lookup(next_page);492if (x) {493kmemcheck_save_addr(next_page);494for (i = n; i < size; ++i) {495x[i - n] = shadow[i];496shadow[i] = KMEMCHECK_SHADOW_INITIALIZED;497}498}499}500501status = kmemcheck_shadow_test(shadow, size);502if (status == KMEMCHECK_SHADOW_INITIALIZED)503return;504505if (kmemcheck_enabled)506kmemcheck_error_save(status, src_addr, size, regs);507508if (kmemcheck_enabled == 2)509kmemcheck_enabled = 0;510}511512enum kmemcheck_method {513KMEMCHECK_READ,514KMEMCHECK_WRITE,515};516517static void kmemcheck_access(struct pt_regs *regs,518unsigned long fallback_address, enum kmemcheck_method fallback_method)519{520const uint8_t *insn;521const uint8_t *insn_primary;522unsigned int size;523524struct kmemcheck_context *data = &__get_cpu_var(kmemcheck_context);525526/* Recursive fault -- ouch. */527if (data->busy) {528kmemcheck_show_addr(fallback_address);529kmemcheck_error_save_bug(regs);530return;531}532533data->busy = true;534535insn = (const uint8_t *) regs->ip;536insn_primary = kmemcheck_opcode_get_primary(insn);537538kmemcheck_opcode_decode(insn, &size);539540switch (insn_primary[0]) {541#ifdef CONFIG_KMEMCHECK_BITOPS_OK542/* AND, OR, XOR */543/*544* Unfortunately, these instructions have to be excluded from545* our regular checking since they access only some (and not546* all) bits. This clears out "bogus" bitfield-access warnings.547*/548case 0x80:549case 0x81:550case 0x82:551case 0x83:552switch ((insn_primary[1] >> 3) & 7) {553/* OR */554case 1:555/* AND */556case 4:557/* XOR */558case 6:559kmemcheck_write(regs, fallback_address, size);560goto out;561562/* ADD */563case 0:564/* ADC */565case 2:566/* SBB */567case 3:568/* SUB */569case 5:570/* CMP */571case 7:572break;573}574break;575#endif576577/* MOVS, MOVSB, MOVSW, MOVSD */578case 0xa4:579case 0xa5:580/*581* These instructions are special because they take two582* addresses, but we only get one page fault.583*/584kmemcheck_copy(regs, regs->si, regs->di, size);585goto out;586587/* CMPS, CMPSB, CMPSW, CMPSD */588case 0xa6:589case 0xa7:590kmemcheck_read(regs, regs->si, size);591kmemcheck_read(regs, regs->di, size);592goto out;593}594595/*596* If the opcode isn't special in any way, we use the data from the597* page fault handler to determine the address and type of memory598* access.599*/600switch (fallback_method) {601case KMEMCHECK_READ:602kmemcheck_read(regs, fallback_address, size);603goto out;604case KMEMCHECK_WRITE:605kmemcheck_write(regs, fallback_address, size);606goto out;607}608609out:610data->busy = false;611}612613bool kmemcheck_fault(struct pt_regs *regs, unsigned long address,614unsigned long error_code)615{616pte_t *pte;617618/*619* XXX: Is it safe to assume that memory accesses from virtual 86620* mode or non-kernel code segments will _never_ access kernel621* memory (e.g. tracked pages)? For now, we need this to avoid622* invoking kmemcheck for PnP BIOS calls.623*/624if (regs->flags & X86_VM_MASK)625return false;626if (regs->cs != __KERNEL_CS)627return false;628629pte = kmemcheck_pte_lookup(address);630if (!pte)631return false;632633WARN_ON_ONCE(in_nmi());634635if (error_code & 2)636kmemcheck_access(regs, address, KMEMCHECK_WRITE);637else638kmemcheck_access(regs, address, KMEMCHECK_READ);639640kmemcheck_show(regs);641return true;642}643644bool kmemcheck_trap(struct pt_regs *regs)645{646if (!kmemcheck_active(regs))647return false;648649/* We're done. */650kmemcheck_hide(regs);651return true;652}653654655