lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Tue, 23 Sep 2008 22:53:06 -0700
From:	Andrew Morton <akpm@...ux-foundation.org>
To:	Arjan van de Ven <arjan@...radead.org>
Cc:	linux-kernel@...r.kernel.org, mingo@...e.hu,
	Hugh Dickins <hugh@...itas.com>,
	Jeremy Fitzhardinge <jeremy.fitzhardinge@...rix.com>,
	"Randy.Dunlap" <rdunlap@...otime.net>
Subject: Re: [PATCH 1/3] corruption check: move the corruption checks into
 their own file

On Tue, 23 Sep 2008 21:53:35 -0700 Arjan van de Ven <arjan@...radead.org> wrote:

> 
> >From 19058f850aaf82d8185f06b54582a3d8e1ca8d97 Mon Sep 17 00:00:00 2001
> From: Arjan van de Ven <arjan@...ux.intel.com>
> Date: Mon, 22 Sep 2008 09:35:06 -0700
> Subject: [PATCH] corruption check: move the corruption checks into their own file
> 
> There'll be more checks over time (based on kerneloops data I have
> several ideas already) and making the checks their own file rather
> than setup.c makes sense in that light.
> 
> Signed-off-by: Arjan van de Ven <arjan@...ux.intel.com>
> ---
>  arch/x86/kernel/Makefile |    1 +
>  arch/x86/kernel/check.c  |  156 ++++++++++++++++++++++++++++++++++++++++++++++
>  arch/x86/kernel/setup.c  |  151 --------------------------------------------

So this is long-standing code.  Let's pretend otherwise ;)

>  include/asm-x86/setup.h  |    4 +
>  4 files changed, 161 insertions(+), 151 deletions(-)
>  create mode 100644 arch/x86/kernel/check.c
> 
> diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
> index c71722d..5d788ea 100644
> --- a/arch/x86/kernel/Makefile
> +++ b/arch/x86/kernel/Makefile
> @@ -36,6 +36,7 @@ obj-y			+= bootflag.o e820.o
>  obj-y			+= pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
>  obj-y			+= alternative.o i8253.o pci-nommu.o
>  obj-y			+= tsc.o io_delay.o rtc.o
> +obj-y			+= check.o
>  
>  obj-$(CONFIG_X86_TRAMPOLINE)	+= trampoline.o
>  obj-y				+= process.o
> diff --git a/arch/x86/kernel/check.c b/arch/x86/kernel/check.c
> new file mode 100644
> index 0000000..a7e80ed
> --- /dev/null
> +++ b/arch/x86/kernel/check.c
> @@ -0,0 +1,156 @@
> +#include <linux/module.h>
> +#include <linux/sched.h>
> +
> +#include <asm/e820.h>
> +#include <asm/proto.h>
> +
> +/*
> + * Some BIOSes seem to corrupt the low 64k of memory during events
> + * like suspend/resume and unplugging an HDMI cable.  Reserve all
> + * remaining free memory in that area and fill it with a distinct
> + * pattern.
> + */
> +#ifdef CONFIG_X86_CHECK_BIOS_CORRUPTION
> +#define MAX_SCAN_AREAS	8
> +
> +static int __read_mostly memory_corruption_check = -1;
> +
> +static unsigned __read_mostly corruption_check_size = 64*1024;
> +static unsigned __read_mostly corruption_check_period = 60; /* seconds */
> +
> +static struct e820entry scan_areas[MAX_SCAN_AREAS];
> +static int num_scan_areas;
> +
> +
> +static int set_corruption_check(char *arg)
> +{
> +	char *end;
> +
> +	memory_corruption_check = simple_strtol(arg, &end, 10);
> +
> +	return (*end == 0) ? 0 : -EINVAL;
> +}
> +early_param("memory_corruption_check", set_corruption_check);

__init?

> +static int set_corruption_check_period(char *arg)
> +{
> +	char *end;
> +
> +	corruption_check_period = simple_strtoul(arg, &end, 10);
> +
> +	return (*end == 0) ? 0 : -EINVAL;
> +}
> +early_param("memory_corruption_check_period", set_corruption_check_period);

__init?

> +static int set_corruption_check_size(char *arg)
> +{
> +	char *end;
> +	unsigned size;
> +
> +	size = memparse(arg, &end);
> +
> +	if (*end == '\0')
> +		corruption_check_size = size;
> +
> +	return (size == corruption_check_size) ? 0 : -EINVAL;
> +}
> +early_param("memory_corruption_check_size", set_corruption_check_size);

__init?

> +
> +void __init setup_bios_corruption_check(void)
> +{
> +	u64 addr = PAGE_SIZE;	/* assume first page is reserved anyway */
> +
> +	if (memory_corruption_check == -1) {
> +		memory_corruption_check =
> +#ifdef CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK
> +			1
> +#else
> +			0
> +#endif
> +			;
> +	}
> +
> +	if (corruption_check_size == 0)
> +		memory_corruption_check = 0;
> +
> +	if (!memory_corruption_check)
> +		return;
> +
> +	corruption_check_size = round_up(corruption_check_size, PAGE_SIZE);
> +
> +	while(addr < corruption_check_size && num_scan_areas < MAX_SCAN_AREAS) {
> +		u64 size;
> +		addr = find_e820_area_size(addr, &size, PAGE_SIZE);
> +
> +		if (addr == 0)
> +			break;
> +
> +		if ((addr + size) > corruption_check_size)
> +			size = corruption_check_size - addr;
> +
> +		if (size == 0)
> +			break;
> +
> +		e820_update_range(addr, size, E820_RAM, E820_RESERVED);
> +		scan_areas[num_scan_areas].addr = addr;
> +		scan_areas[num_scan_areas].size = size;
> +		num_scan_areas++;
> +
> +		/* Assume we've already mapped this early memory */
> +		memset(__va(addr), 0, size);
> +
> +		addr += size;
> +	}
> +
> +	printk(KERN_INFO "Scanning %d areas for low memory corruption\n",
> +	       num_scan_areas);
> +	update_e820();
> +}
> +
> +static struct timer_list periodic_check_timer;

Could use DEFINE_TIMER() here.

> +void check_for_bios_corruption(void)
> +{
> +	int i;
> +	int corruption = 0;
> +
> +	if (!memory_corruption_check)
> +		return;
> +
> +	for(i = 0; i < num_scan_areas; i++) {
> +		unsigned long *addr = __va(scan_areas[i].addr);
> +		unsigned long size = scan_areas[i].size;
> +
> +		for(; size; addr++, size -= sizeof(unsigned long)) {
> +			if (!*addr)
> +				continue;
> +			printk(KERN_ERR "Corrupted low memory at %p (%lx phys) = %08lx\n",
> +			       addr, __pa(addr), *addr);
> +			corruption = 1;
> +			*addr = 0;
> +		}
> +	}
> +
> +	WARN(corruption, KERN_ERR "Memory corruption detected in low memory\n");
> +}
> +
> +static void periodic_check_for_corruption(unsigned long data)
> +{
> +	check_for_bios_corruption();
> +	mod_timer(&periodic_check_timer, round_jiffies(jiffies + corruption_check_period*HZ));
> +}
> +
> +void start_periodic_check_for_corruption(void)
> +{
> +	if (!memory_corruption_check || corruption_check_period == 0)
> +		return;
> +
> +	printk(KERN_INFO "Scanning for low memory corruption every %d seconds\n",
> +	       corruption_check_period);
> +
> +	init_timer(&periodic_check_timer);
> +	periodic_check_timer.function = &periodic_check_for_corruption;

and zap those.

> +	periodic_check_for_corruption(0);
> +}
> +#endif

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ