void die(struct pt_regs *regs, const char *str) { static int die_counter; oops_enter(); lgr_info_log(); debug_stop_all(); console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); printk("%s: %04x [#%d] ", str, regs->int_code & 0xffff, ++die_counter); #ifdef CONFIG_PREEMPT printk("PREEMPT "); #endif #ifdef CONFIG_SMP printk("SMP "); #endif #ifdef CONFIG_DEBUG_PAGEALLOC printk("DEBUG_PAGEALLOC"); #endif printk("\n"); notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV); print_modules(); show_regs(regs); bust_spinlocks(0); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); spin_unlock_irq(&die_lock); if (in_interrupt()) panic("Fatal exception in interrupt"); if (panic_on_oops) panic("Fatal exception: panic_on_oops"); oops_exit(); do_exit(SIGSEGV); }
/* * This function is protected against re-entrancy. */ void die(const char *str, struct pt_regs *regs, int err) { int ret; unsigned long flags; raw_spin_lock_irqsave(&die_lock, flags); oops_enter(); console_verbose(); bust_spinlocks(1); ret = __die(str, err, regs); if (regs && kexec_should_crash(current)) crash_kexec(regs); bust_spinlocks(0); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); oops_exit(); if (in_interrupt()) panic("Fatal exception in interrupt"); if (panic_on_oops) panic("Fatal exception"); raw_spin_unlock_irqrestore(&die_lock, flags); if (ret != NOTIFY_STOP) do_exit(SIGSEGV); }
void oops_end(unsigned long flags, struct pt_regs *regs, int signr) { if (regs && kexec_should_crash(current)) crash_kexec(regs); bust_spinlocks(0); die_owner = -1; add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); die_nest_count--; if (!die_nest_count) /* Nest count reaches zero, release the lock. */ arch_spin_unlock(&die_lock); raw_local_irq_restore(flags); oops_exit(); if (!signr) return; if (in_interrupt()) panic("Fatal exception in interrupt"); if (panic_on_oops) panic("Fatal exception"); /* * We're not going to return, but we might be on an IST stack or * have very little stack space left. Rewind the stack and kill * the task. */ rewind_stack_do_exit(signr); }
/* * This can be dangerous especially when we have clients such as * PMICs, therefore don't provide any real compile time configuration option * for this feature, people who want to use this will need to modify * the source code directly. */ static ssize_t regmap_map_write_file(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { char buf[32]; size_t buf_size; char *start = buf; unsigned long reg, value; struct regmap *map = file->private_data; buf_size = min(count, (sizeof(buf)-1)); if (copy_from_user(buf, user_buf, buf_size)) return -EFAULT; buf[buf_size] = 0; while (*start == ' ') start++; reg = simple_strtoul(start, &start, 16); while (*start == ' ') start++; if (strict_strtoul(start, 16, &value)) return -EINVAL; /* Userspace has been fiddling around behind the kernel's back */ add_taint(TAINT_USER); regmap_write(map, reg, value); return buf_size; }
static void acpi_table_taint(struct acpi_table_header *table) { pr_warn(PREFIX "Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n", table->signature, table->oem_table_id); add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE); }
static void kasan_end_report(unsigned long *flags) { pr_err("==================================================================\n"); add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE); spin_unlock_irqrestore(&report_lock, *flags); kasan_enable_current(); }
/*** * therm_throt_process - Process thermal throttling event from interrupt * @curr: Whether the condition is current or not (boolean), since the * thermal interrupt normally gets called both when the thermal * event begins and once the event has ended. * * This function is called by the thermal interrupt after the * IRQ has been acknowledged. * * It will take care of rate limiting and printing messages to the syslog. * * Returns: 0 : Event should NOT be further logged, i.e. still in * "timeout" from previous log message. * 1 : Event should be logged further, and a message has been * printed to the syslog. */ int therm_throt_process(int curr) { unsigned int cpu = smp_processor_id(); __u64 tmp_jiffs = get_jiffies_64(); if (curr) __get_cpu_var(thermal_throttle_count)++; if (time_before64(tmp_jiffs, __get_cpu_var(next_check))) return 0; __get_cpu_var(next_check) = tmp_jiffs + CHECK_INTERVAL; /* if we just entered the thermal event */ if (curr) { printk(KERN_CRIT "CPU%d: Temperature above threshold, " "cpu clock throttled (total events = %lu)\n", cpu, __get_cpu_var(thermal_throttle_count)); add_taint(TAINT_MACHINE_CHECK); } else { printk(KERN_CRIT "CPU%d: Temperature/speed normal\n", cpu); } return 1; }
static int __init intel_irq_remapping_supported(void) { struct dmar_drhd_unit *drhd; struct intel_iommu *iommu; if (disable_irq_remap) return 0; if (irq_remap_broken) { printk(KERN_WARNING "This system BIOS has enabled interrupt remapping\n" "on a chipset that contains an erratum making that\n" "feature unstable. To maintain system stability\n" "interrupt remapping is being disabled. Please\n" "contact your BIOS vendor for an update\n"); add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); disable_irq_remap = 1; return 0; } if (!dmar_ir_support()) return 0; for_each_iommu(iommu, drhd) if (!ecap_ir_support(iommu->ecap)) return 0; return 1; }
void __noreturn die(const char *str, struct pt_regs *regs, long err, unsigned long addr) { static int die_counter; oops_enter(); spin_lock_irq(&die_lock); console_verbose(); bust_spinlocks(1); pr_err("%s: err %04lx (%s) addr %08lx [#%d]\n", str, err & 0xffff, trap_name(err & 0xffff), addr, ++die_counter); print_modules(); show_regs(regs); pr_err("Process: %s (pid: %d, stack limit = %p)\n", current->comm, task_pid_nr(current), task_stack_page(current) + THREAD_SIZE); bust_spinlocks(0); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); if (kexec_should_crash(current)) crash_kexec(regs); if (in_interrupt()) panic("Fatal exception in interrupt"); if (panic_on_oops) panic("Fatal exception"); spin_unlock_irq(&die_lock); oops_exit(); do_exit(SIGSEGV); }
/* * This function is protected against re-entrancy. */ void die(const char *str, struct pt_regs *regs, int err) { enum bug_trap_type bug_type = BUG_TRAP_TYPE_NONE; struct thread_info *thread = current_thread_info(); int ret; oops_enter(); raw_spin_lock_irq(&die_lock); console_verbose(); bust_spinlocks(1); if (!user_mode(regs)) bug_type = report_bug(regs->pc, regs); if (bug_type != BUG_TRAP_TYPE_NONE) str = "Oops - BUG"; ret = __die(str, err, thread, regs); if (regs && kexec_should_crash(thread->task)) crash_kexec(regs); bust_spinlocks(0); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); raw_spin_unlock_irq(&die_lock); oops_exit(); if (in_interrupt()) panic("Fatal exception in interrupt"); if (panic_on_oops) panic("Fatal exception"); if (ret != NOTIFY_STOP) do_exit(SIGSEGV); }
/* * This function is protected against re-entrancy. */ void die(const char *str, struct pt_regs *regs, int err) { struct thread_info *thread = current_thread_info(); int ret; oops_enter(); raw_spin_lock_irq(&die_lock); console_verbose(); bust_spinlocks(1); ret = __die(str, err, thread, regs); if (regs && kexec_should_crash(thread->task)) crash_kexec(regs); bust_spinlocks(0); add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE); raw_spin_unlock_irq(&die_lock); oops_exit(); if (in_interrupt()) panic("Fatal exception in interrupt"); if (panic_on_oops) panic("Fatal exception"); if (ret != NOTIFY_STOP) do_exit(SIGSEGV); }
void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) { if (regs && kexec_should_crash(current)) crash_kexec(regs); bust_spinlocks(0); die_owner = -1; add_taint(TAINT_DIE); die_nest_count--; if (!die_nest_count) /* Nest count reaches zero, release the lock. */ arch_spin_unlock(&die_lock); raw_local_irq_restore(flags); oops_exit(); if (!signr) return; if (in_interrupt()) panic("Fatal exception in interrupt"); if (panic_on_oops) panic("Fatal exception"); gr_handle_kernel_exploit(); do_group_exit(signr); }
static void mce_checkregs(void *info) { u32 low, high; int i; for (i = firstbank; i < nr_mce_banks; i++) { rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high); if (high & (1<<31)) { printk(KERN_INFO "MCE: The hardware reports a non " "fatal, correctable incident occurred on " "CPU %d.\n", smp_processor_id()); printk(KERN_INFO "Bank %d: %08x%08x\n", i, high, low); /* * Scrub the error so we don't pick it up in MCE_RATE * seconds time. */ wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL); /* Serialize */ wmb(); add_taint(TAINT_MACHINE_CHECK); } } }
static int user_read(abi_long ret, abi_long fd, void *p){ if (ret > 0 && fd == infd){ TaintOpBuffer *tempBuf = tob_new(5*1048576 /* 1MB */); add_taint(shadow, tempBuf, (uint64_t)p /*pointer*/, ret /*length*/); tob_delete(tempBuf); } return 0; }
/* Machine check handler for WinChip C6: */ static void winchip_machine_check(struct pt_regs *regs, long error_code) { ist_enter(regs); pr_emerg("CPU0: Machine Check Exception.\n"); add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE); ist_exit(regs); }
static ssize_t cm_write(struct file *file, const char __user * user_buf, size_t count, loff_t *ppos) { static char *buf; static u32 max_size; static u32 uncopied_bytes; struct acpi_table_header table; acpi_status status; #ifdef CONFIG_GRKERNSEC_KMEM return -EPERM; #endif if (!(*ppos)) { /* parse the table header to get the table length */ if (count <= sizeof(struct acpi_table_header)) return -EINVAL; if (copy_from_user(&table, user_buf, sizeof(struct acpi_table_header))) return -EFAULT; uncopied_bytes = max_size = table.length; buf = kzalloc(max_size, GFP_KERNEL); if (!buf) return -ENOMEM; } if (buf == NULL) return -EINVAL; if ((*ppos > max_size) || (*ppos + count > max_size) || (*ppos + count < count) || (count > uncopied_bytes)) return -EINVAL; if (copy_from_user(buf + (*ppos), user_buf, count)) { kfree(buf); buf = NULL; return -EFAULT; } uncopied_bytes -= count; *ppos += count; if (!uncopied_bytes) { status = acpi_install_method(buf); kfree(buf); buf = NULL; if (ACPI_FAILURE(status)) return -EINVAL; add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE); } return count; }
/* Machine check handler for Pentium class Intel */ static fastcall void pentium_machine_check(struct pt_regs * regs, long error_code) { u32 loaddr, hi, lotype; rdmsr(MSR_IA32_P5_MC_ADDR, loaddr, hi); rdmsr(MSR_IA32_P5_MC_TYPE, lotype, hi); printk(KERN_EMERG "CPU#%d: Machine Check Exception: 0x%8X (type 0x%8X).\n", smp_processor_id(), loaddr, lotype); if(lotype&(1<<5)) printk(KERN_EMERG "CPU#%d: Possible thermal failure (CPU on fire ?).\n", smp_processor_id()); add_taint(TAINT_MACHINE_CHECK); }
int guest_hypercall_callback(CPUState *env){ #ifdef TARGET_I386 if (env->regs[R_EAX] == 0xdeadbeef){ target_ulong buf_start = env->regs[R_ECX]; target_ulong buf_len = env->regs[R_EDX]; if (env->regs[R_EBX] == 0){ //Taint label if (!taintEnabled){ printf("Taint plugin: Label operation detected\n"); printf("Enabling taint processing\n"); taintJustEnabled = true; taintEnabled = true; enable_taint(); } TaintOpBuffer *tempBuf = tob_new(5*1048576 /* 5MB */); #ifndef CONFIG_SOFTMMU add_taint(shadow, tempBuf, (uint64_t)buf_start, (int)buf_len); #else add_taint(shadow, tempBuf, cpu_get_phys_addr(env, buf_start), (int)buf_len); #endif //CONFIG_SOFTMMU tob_delete(tempBuf); } else if (env->regs[R_EBX] == 1){ //Query taint on label #ifndef CONFIG_SOFTMMU bufplot(shadow, (uint64_t)buf_start, (int)buf_len); #else bufplot(shadow, cpu_get_phys_addr(env, buf_start), (int)buf_len); #endif //CONFIG_SOFTMMU printf("Taint plugin: Query operation detected\n"); printf("Disabling taint processing\n"); taintEnabled = false; taintJustDisabled = true; } } #endif // TARGET_I386 return 1; }
/* This is a non __init function. Force it to be noinline otherwise gcc * makes it inline to init() and it becomes part of init.text section */ static int noinline init_post(void) { free_initmem(); #ifdef CONFIG_RG_MAINFS do_mount_mainfs(); #endif #ifdef CONFIG_OPENRG /* OpenRG uses propietary modules */ add_taint(TAINT_PROPRIETARY_MODULE); /* Initialize all OpenRG kernel code */ rg_load_kernel_modules_initial(); rg_load_kernel_modules(); #endif unlock_kernel(); mark_rodata_ro(); system_state = SYSTEM_RUNNING; numa_default_policy(); if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) printk(KERN_WARNING "Warning: unable to open an initial console.\n"); (void) sys_dup(0); (void) sys_dup(0); if (ramdisk_execute_command) { run_init_process(ramdisk_execute_command); printk(KERN_WARNING "Failed to execute %s\n", ramdisk_execute_command); } /* * We try each of these until one succeeds. * * The Bourne shell can be used instead of init if we are * trying to recover a really broken machine. */ if (execute_command) { run_init_process(execute_command); printk(KERN_WARNING "Failed to execute %s. Attempting " "defaults...\n", execute_command); } run_init_process("/sbin/init"); run_init_process("/etc/init"); run_init_process("/bin/init"); run_init_process("/bin/sh"); panic("No init found. Try passing init= option to kernel."); }
/* Machine Check Handler For AMD Athlon/Duron */ static void k7_machine_check(struct pt_regs * regs, long error_code) { int recover=1; u32 alow, ahigh, high, low; u32 mcgstl, mcgsth; int i; rdmsr (MSR_IA32_MCG_STATUS, mcgstl, mcgsth); if (mcgstl & (1<<0)) /* Recoverable ? */ recover=0; printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", smp_processor_id(), mcgsth, mcgstl); for (i = 1; i < nr_mce_banks; i++) { rdmsr(MSR_IA32_MC0_STATUS+i*4, low, high); if (high&(1<<31)) { char misc[20]; char addr[24]; misc[0] = addr[0] = '\0'; if (high & (1<<29)) recover |= 1; if (high & (1<<25)) recover |= 2; high &= ~(1<<31); if (high & (1<<27)) { rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh); snprintf(misc, 20, "[%08x%08x]", ahigh, alow); } if (high & (1<<26)) { rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh); snprintf(addr, 24, " at %08x%08x", ahigh, alow); } printk(KERN_EMERG "CPU %d: Bank %d: %08x%08x%s%s\n", smp_processor_id(), i, high, low, misc, addr); /* Clear it */ wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL); /* Serialize */ wmb(); add_taint(TAINT_MACHINE_CHECK); } } if (recover&2) panic ("CPU context corrupt"); if (recover&1) panic ("Unable to continue"); printk (KERN_EMERG "Attempting to continue.\n"); mcgstl &= ~(1<<2); wrmsr (MSR_IA32_MCG_STATUS,mcgstl, mcgsth); }
void warn_on_slowpath(const char *file, int line) { char function[KSYM_SYMBOL_LEN]; unsigned long caller = (unsigned long) __builtin_return_address(0); sprint_symbol(function, caller); printk(KERN_WARNING "------------[ cut here ]------------\n"); printk(KERN_WARNING "WARNING: at %s:%d %s()\n", file, line, function); print_modules(); dump_stack(); print_oops_end_marker(); add_taint(TAINT_WARN); }
void efi_call_virt_check_flags(unsigned long flags, const char *call) { unsigned long cur_flags, mismatch; local_save_flags(cur_flags); mismatch = flags ^ cur_flags; if (!WARN_ON_ONCE(mismatch & ARCH_EFI_IRQ_FLAGS_MASK)) return; add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_NOW_UNRELIABLE); pr_err_ratelimited(FW_BUG "IRQ flags corrupted (0x%08lx=>0x%08lx) by EFI %s\n", flags, cur_flags, call); local_irq_restore(flags); }
/* Mark parts of the kernel as 'Tech Preview', to make it clear to our * support organization and customers what we do not fully support yet. * NOTE: this will TAINT the kernel to signify the machine is running * code that is not fully supported. Use with caution. */ void mark_tech_preview(const char *msg, struct module *mod) { const char *str = NULL; if (msg) str = msg; else if (mod && mod->name) str = mod->name; pr_warning("TECH PREVIEW: %s may not be fully supported.\n" "Please review provided documentation for limitations.\n", (str ? str : "kernel")); add_taint(TAINT_TECH_PREVIEW); if (mod) mod->taints |= (1U << TAINT_TECH_PREVIEW); }
/* * process pending MCE event from the mce event queue. This function will be * called during syscall exit. */ static void machine_check_process_queued_event(struct irq_work *work) { int index; add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE); /* * For now just print it to console. * TODO: log this error event to FSP or nvram. */ while (__this_cpu_read(mce_queue_count) > 0) { index = __this_cpu_read(mce_queue_count) - 1; machine_check_print_event_info( this_cpu_ptr(&mce_event_queue[index]), false); __this_cpu_dec(mce_queue_count); } }
int guest_hypercall_callback(CPUState *env) { #ifdef TARGET_I386 if(env->regs[R_EAX] == 0xdeadbeef) { target_ulong buf_start = env->regs[R_ECX]; target_ulong buf_len = env->regs[R_EDX]; if(env->regs[R_EBX] == 0) { //Taint label TaintOpBuffer *tempBuf = tob_new(5*1048576 /* 1MB */); add_taint(shadow, tempBuf, (uint64_t)buf_start, (int)buf_len); tob_delete(tempBuf); } else if(env->regs[R_EBX] == 1) { //Query taint on label bufplot(shadow, (uint64_t)buf_start, (int)buf_len); } } #endif return 1; }
static ssize_t cm_write(struct file *file, const char __user * user_buf, size_t count, loff_t *ppos) { static char *buf; static int uncopied_bytes; struct acpi_table_header table; acpi_status status; if (!(*ppos)) { /* parse the table header to get the table length */ if (count <= sizeof(struct acpi_table_header)) return -EINVAL; if (copy_from_user(&table, user_buf, sizeof(struct acpi_table_header))) return -EFAULT; uncopied_bytes = table.length; buf = kzalloc(uncopied_bytes, GFP_KERNEL); if (!buf) return -ENOMEM; } if (uncopied_bytes < count) { kfree(buf); return -EINVAL; } if (copy_from_user(buf + (*ppos), user_buf, count)) { kfree(buf); return -EFAULT; } uncopied_bytes -= count; *ppos += count; if (!uncopied_bytes) { status = acpi_install_method(buf); kfree(buf); if (ACPI_FAILURE(status)) return -EINVAL; add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); } return count; }
void __warn(const char *file, int line, void *caller, unsigned taint, struct pt_regs *regs, struct warn_args *args) { disable_trace_on_warning(); if (args) pr_warn(CUT_HERE); if (file) pr_warn("WARNING: CPU: %d PID: %d at %s:%d %pS\n", raw_smp_processor_id(), current->pid, file, line, caller); else pr_warn("WARNING: CPU: %d PID: %d at %pS\n", raw_smp_processor_id(), current->pid, caller); if (args) vprintk(args->fmt, args->args); if (panic_on_warn) { /* * This thread may hit another WARN() in the panic path. * Resetting this prevents additional WARN() from panicking the * system on this thread. Other threads are blocked by the * panic_mutex in panic(). */ panic_on_warn = 0; panic("panic_on_warn set ...\n"); } print_modules(); if (regs) show_regs(regs); else dump_stack(); print_irqtrace_events(current); print_oops_end_marker(); /* Just a warning, don't kill lockdep. */ add_taint(taint, LOCKDEP_STILL_OK); }
static int __init intel_prepare_irq_remapping(void) { struct dmar_drhd_unit *drhd; struct intel_iommu *iommu; if (irq_remap_broken) { printk(KERN_WARNING "This system BIOS has enabled interrupt remapping\n" "on a chipset that contains an erratum making that\n" "feature unstable. To maintain system stability\n" "interrupt remapping is being disabled. Please\n" "contact your BIOS vendor for an update\n"); add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK); return -ENODEV; } if (dmar_table_init() < 0) return -ENODEV; if (!dmar_ir_support()) return -ENODEV; if (parse_ioapics_under_ir() != 1) { printk(KERN_INFO "Not enabling interrupt remapping\n"); goto error; } /* First make sure all IOMMUs support IRQ remapping */ for_each_iommu(iommu, drhd) if (!ecap_ir_support(iommu->ecap)) goto error; /* Do the allocations early */ for_each_iommu(iommu, drhd) if (intel_setup_irq_remapping(iommu)) goto error; return 0; error: intel_cleanup_irq_remapping(); return -ENODEV; }
void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) { bust_spinlocks(0); die_owner = -1; add_taint(TAINT_DIE); __raw_spin_unlock(&die_lock); raw_local_irq_restore(flags); if (!regs) return; //if (kexec_should_crash(current)) //crash_kexec(regs); if (in_interrupt()) panic("Fatal exception in interrupt"); if (panic_on_oops) panic("Fatal exception"); oops_exit(); do_exit(signr); }
static void bad_page(struct page *page) { static unsigned long resume; static unsigned long nr_shown; static unsigned long nr_unshown; /* Don't complain about poisoned pages */ if (PageHWPoison(page)) { __ClearPageBuddy(page); return; } /* * Allow a burst of 60 reports, then keep quiet for that minute; * or allow a steady drip of one report per second. */ if (nr_shown == 60) { if (time_before(jiffies, resume)) { nr_unshown++; goto out; } if (nr_unshown) { printk(KERN_ALERT "BUG: Bad page state: %lu messages suppressed\n", nr_unshown); nr_unshown = 0; } nr_shown = 0; } if (nr_shown++ == 0) resume = jiffies + 60 * HZ; printk(KERN_ALERT "BUG: Bad page state in process pfn:%05lx\n", page_to_pfn(page)); // dump_page(page); dump_stack(); out: /* Leave bad fields for debug, except PageBuddy could make trouble */ __ClearPageBuddy(page); add_taint(TAINT_BAD_PAGE); }