Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 201532
b: refs/heads/master
c: 14764b0
h: refs/heads/master
v: v3
  • Loading branch information
Russell King committed Jul 21, 2010
1 parent bfa36b0 commit cc5055e
Show file tree
Hide file tree
Showing 14 changed files with 373 additions and 12 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 5ccd4302a20bfe56eb72a5e27ad0be046fc820a5
refs/heads/master: 14764b01a5576ce23a9d0c95a027049206a19cef
13 changes: 13 additions & 0 deletions trunk/arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ config ARCH_MSM
bool "Qualcomm MSM"
select HAVE_CLK
select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB
help
Support for Qualcomm MSM/QSD based systems. This runs on the
apps processor of the MSM/QSD and depends on a shared memory
Expand Down Expand Up @@ -1375,6 +1376,18 @@ config UACCESS_WITH_MEMCPY
However, if the CPU data cache is using a write-allocate mode,
this option is unlikely to provide any performance gain.

config CC_STACKPROTECTOR
bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)"
help
This option turns on the -fstack-protector GCC feature. This
feature puts, at the beginning of functions, a canary value on
the stack just before the return address, and validates
the value just before actually returning. Stack based buffer
overflows (that need to overwrite this return address) now also
overwrite the canary, which gets detected and the attack is then
neutralized via a kernel panic.
This feature requires gcc version 4.2 or above.

endmenu

menu "Boot options"
Expand Down
4 changes: 4 additions & 0 deletions trunk/arch/arm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ ifeq ($(CONFIG_FRAME_POINTER),y)
KBUILD_CFLAGS +=-fno-omit-frame-pointer -mapcs -mno-sched-prolog
endif

ifeq ($(CONFIG_CC_STACKPROTECTOR),y)
KBUILD_CFLAGS +=-fstack-protector
endif

ifeq ($(CONFIG_CPU_BIG_ENDIAN),y)
KBUILD_CPPFLAGS += -mbig-endian
AS += -EB
Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/arm/include/asm/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,4 +121,7 @@ int dump_task_regs(struct task_struct *t, elf_gregset_t *elfregs);
extern void elf_set_personality(const struct elf32_hdr *);
#define SET_PERSONALITY(ex) elf_set_personality(&(ex))

extern unsigned long arch_randomize_brk(struct mm_struct *mm);
#define arch_randomize_brk arch_randomize_brk

#endif
38 changes: 38 additions & 0 deletions trunk/arch/arm/include/asm/stackprotector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* GCC stack protector support.
*
* Stack protector works by putting predefined pattern at the start of
* the stack frame and verifying that it hasn't been overwritten when
* returning from the function. The pattern is called stack canary
* and gcc expects it to be defined by a global variable called
* "__stack_chk_guard" on ARM. This unfortunately means that on SMP
* we cannot have a different canary value per task.
*/

#ifndef _ASM_STACKPROTECTOR_H
#define _ASM_STACKPROTECTOR_H 1

#include <linux/random.h>
#include <linux/version.h>

extern unsigned long __stack_chk_guard;

/*
* Initialize the stackprotector canary value.
*
* NOTE: this must only be called from functions that never return,
* and it must always be inlined.
*/
static __always_inline void boot_init_stack_canary(void)
{
unsigned long canary;

/* Try to get a semi random initial value. */
get_random_bytes(&canary, sizeof(canary));
canary ^= LINUX_VERSION_CODE;

current->stack_canary = canary;
__stack_chk_guard = current->stack_canary;
}

#endif /* _ASM_STACKPROTECTOR_H */
3 changes: 3 additions & 0 deletions trunk/arch/arm/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
int main(void)
{
DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm));
#ifdef CONFIG_CC_STACKPROTECTOR
DEFINE(TSK_STACK_CANARY, offsetof(struct task_struct, stack_canary));
#endif
BLANK();
DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
Expand Down
8 changes: 8 additions & 0 deletions trunk/arch/arm/kernel/entry-armv.S
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,11 @@ ENTRY(__switch_to)
mov r4, #0xffff0fff
str r3, [r4, #-15] @ TLS val at 0xffff0ff0
#endif
#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
ldr r7, [r2, #TI_TASK]
ldr r8, =__stack_chk_guard
ldr r7, [r7, #TSK_STACK_CANARY]
#endif
#ifdef CONFIG_MMU
mcr p15, 0, r6, c3, c0, 0 @ Set domain register
#endif
Expand All @@ -749,6 +754,9 @@ ENTRY(__switch_to)
ldr r0, =thread_notify_head
mov r1, #THREAD_NOTIFY_SWITCH
bl atomic_notifier_call_chain
#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
str r7, [r8]
#endif
THUMB( mov ip, r4 )
mov r0, r5
ARM( ldmia r4, {r4 - sl, fp, sp, pc} ) @ Load all regs saved previously
Expand Down
13 changes: 13 additions & 0 deletions trunk/arch/arm/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <linux/tick.h>
#include <linux/utsname.h>
#include <linux/uaccess.h>
#include <linux/random.h>

#include <asm/leds.h>
#include <asm/processor.h>
Expand All @@ -36,6 +37,12 @@
#include <asm/stacktrace.h>
#include <asm/mach/time.h>

#ifdef CONFIG_CC_STACKPROTECTOR
#include <linux/stackprotector.h>
unsigned long __stack_chk_guard __read_mostly;
EXPORT_SYMBOL(__stack_chk_guard);
#endif

static const char *processor_modes[] = {
"USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
"UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
Expand Down Expand Up @@ -426,3 +433,9 @@ unsigned long get_wchan(struct task_struct *p)
} while (count ++ < 16);
return 0;
}

unsigned long arch_randomize_brk(struct mm_struct *mm)
{
unsigned long range_end = mm->brk + 0x02000000;
return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
}
2 changes: 1 addition & 1 deletion trunk/arch/arm/mach-msm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ obj-$(CONFIG_ARCH_QSD8X50) += sirc.o
obj-$(CONFIG_MSM_SMD) += smd.o smd_debug.o
obj-$(CONFIG_MSM_SMD) += last_radio_log.o

obj-$(CONFIG_MACH_TROUT) += board-trout.o devices-msm7x00.o
obj-$(CONFIG_MACH_TROUT) += board-trout.o board-trout-gpio.o devices-msm7x00.o
obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o devices-msm7x00.o
obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o
obj-$(CONFIG_ARCH_QSD8X50) += board-qsd8x50.o devices-qsd8x50.o
Expand Down
112 changes: 112 additions & 0 deletions trunk/arch/arm/mach-msm/board-trout-gpio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*
* linux/arch/arm/mach-msm/gpio.c
*
* Copyright (C) 2005 HP Labs
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2009 Pavel Machek <pavel@ucw.cz>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/gpio.h>

#include "board-trout.h"

struct msm_gpio_chip {
struct gpio_chip chip;
void __iomem *reg; /* Base of register bank */
u8 shadow;
};

#define to_msm_gpio_chip(c) container_of(c, struct msm_gpio_chip, chip)

static int msm_gpiolib_get(struct gpio_chip *chip, unsigned offset)
{
struct msm_gpio_chip *msm_gpio = to_msm_gpio_chip(chip);
unsigned mask = 1 << offset;

return !!(readb(msm_gpio->reg) & mask);
}

static void msm_gpiolib_set(struct gpio_chip *chip, unsigned offset, int val)
{
struct msm_gpio_chip *msm_gpio = to_msm_gpio_chip(chip);
unsigned mask = 1 << offset;

if (val)
msm_gpio->shadow |= mask;
else
msm_gpio->shadow &= ~mask;

writeb(msm_gpio->shadow, msm_gpio->reg);
}

static int msm_gpiolib_direction_input(struct gpio_chip *chip,
unsigned offset)
{
msm_gpiolib_set(chip, offset, 0);
return 0;
}

static int msm_gpiolib_direction_output(struct gpio_chip *chip,
unsigned offset, int val)
{
msm_gpiolib_set(chip, offset, val);
return 0;
}

#define TROUT_GPIO_BANK(name, reg_num, base_gpio, shadow_val) \
{ \
.chip = { \
.label = name, \
.direction_input = msm_gpiolib_direction_input,\
.direction_output = msm_gpiolib_direction_output, \
.get = msm_gpiolib_get, \
.set = msm_gpiolib_set, \
.base = base_gpio, \
.ngpio = 8, \
}, \
.reg = (void *) reg_num + TROUT_CPLD_BASE, \
.shadow = shadow_val, \
}

static struct msm_gpio_chip msm_gpio_banks[] = {
#if defined(CONFIG_MSM_DEBUG_UART1)
/* H2W pins <-> UART1 */
TROUT_GPIO_BANK("MISC2", 0x00, TROUT_GPIO_MISC2_BASE, 0x40),
#else
/* H2W pins <-> UART3, Bluetooth <-> UART1 */
TROUT_GPIO_BANK("MISC2", 0x00, TROUT_GPIO_MISC2_BASE, 0x80),
#endif
/* I2C pull */
TROUT_GPIO_BANK("MISC3", 0x02, TROUT_GPIO_MISC3_BASE, 0x04),
TROUT_GPIO_BANK("MISC4", 0x04, TROUT_GPIO_MISC4_BASE, 0),
/* mmdi 32k en */
TROUT_GPIO_BANK("MISC5", 0x06, TROUT_GPIO_MISC5_BASE, 0x04),
TROUT_GPIO_BANK("INT2", 0x08, TROUT_GPIO_INT2_BASE, 0),
TROUT_GPIO_BANK("MISC1", 0x0a, TROUT_GPIO_MISC1_BASE, 0),
TROUT_GPIO_BANK("VIRTUAL", 0x12, TROUT_GPIO_VIRTUAL_BASE, 0),
};

/*
* Called from the processor-specific init to enable GPIO pin support.
*/
int __init trout_init_gpio(void)
{
int i;

for (i = 0; i < ARRAY_SIZE(msm_gpio_banks); i++)
gpiochip_add(&msm_gpio_banks[i].chip);

return 0;
}

postcore_initcall(trout_init_gpio);

Loading

0 comments on commit cc5055e

Please sign in to comment.