diff -urNp linux-2.4.37.7/arch/alpha/config.in linux-2.4.37.7/arch/alpha/config.in --- linux-2.4.37.7/arch/alpha/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/alpha/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -468,3 +468,12 @@ endmenu source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu + diff -urNp linux-2.4.37.7/arch/alpha/kernel/osf_sys.c linux-2.4.37.7/arch/alpha/kernel/osf_sys.c --- linux-2.4.37.7/arch/alpha/kernel/osf_sys.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/alpha/kernel/osf_sys.c 2009-11-10 19:30:27.000000000 -0500 @@ -1357,6 +1357,10 @@ arch_get_unmapped_area(struct file *filp merely specific addresses, but regions of memory -- perhaps this feature should be incorporated into all ports? */ +#ifdef CONFIG_PAX_RANDMMAP + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp) +#endif + if (addr) { addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit); if (addr != -ENOMEM) @@ -1364,8 +1368,15 @@ arch_get_unmapped_area(struct file *filp } /* Next, try allocating at TASK_UNMAPPED_BASE. */ - addr = arch_get_unmapped_area_1 (PAGE_ALIGN(TASK_UNMAPPED_BASE), - len, limit); + + addr = TASK_UNMAPPED_BASE; + +#ifdef CONFIG_PAX_RANDMMAP + if (current->mm->pax_flags & MF_PAX_RANDMMAP) + addr += current->mm->delta_mmap; +#endif + + addr = arch_get_unmapped_area_1 (PAGE_ALIGN(addr), len, limit); if (addr != -ENOMEM) return addr; diff -urNp linux-2.4.37.7/arch/alpha/kernel/ptrace.c linux-2.4.37.7/arch/alpha/kernel/ptrace.c --- linux-2.4.37.7/arch/alpha/kernel/ptrace.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/alpha/kernel/ptrace.c 2009-11-10 19:30:27.000000000 -0500 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -275,6 +276,10 @@ sys_ptrace(long request, long pid, long read_unlock(&tasklist_lock); if (!child) goto out_notsk; + + if(gr_handle_ptrace(child, request)) + goto out; + if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); goto out; diff -urNp linux-2.4.37.7/arch/alpha/kernel/setup.c linux-2.4.37.7/arch/alpha/kernel/setup.c --- linux-2.4.37.7/arch/alpha/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/alpha/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -1208,7 +1208,7 @@ c_stop(struct seq_file *f, void *v) { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { start: c_start, next: c_next, stop: c_stop, diff -urNp linux-2.4.37.7/arch/alpha/mm/fault.c linux-2.4.37.7/arch/alpha/mm/fault.c --- linux-2.4.37.7/arch/alpha/mm/fault.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/alpha/mm/fault.c 2009-11-10 19:30:27.000000000 -0500 @@ -53,6 +53,123 @@ __load_new_mm_context(struct mm_struct * __reload_thread(¤t->thread); } +#ifdef CONFIG_PAX_PAGEEXEC +/* + * PaX: decide what to do with offenders (regs->pc = fault address) + * + * returns 1 when task should be killed + * 2 when patched PLT trampoline was detected + * 3 when unpatched PLT trampoline was detected + */ +static int pax_handle_fetch_fault(struct pt_regs *regs) +{ + int err; + +#ifdef CONFIG_PAX_EMUPLT + do { /* PaX: patched PLT emulation #1 */ + unsigned int ldah, ldq, jmp; + + err = get_user(ldah, (unsigned int *)regs->pc); + err |= get_user(ldq, (unsigned int *)(regs->pc+4)); + err |= get_user(jmp, (unsigned int *)(regs->pc+8)); + + if (err) + break; + + if ((ldah & 0xFFFF0000U) == 0x277B0000U && + (ldq & 0xFFFF0000U) == 0xA77B0000U && + jmp == 0x6BFB0000U) + { + unsigned long r27, addr; + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16; + unsigned long addrl = ldq | 0xFFFFFFFFFFFF0000UL; + + addr = regs->r27 + ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL); + err = get_user(r27, (unsigned long*)addr); + if (err) + break; + + regs->r27 = r27; + regs->pc = r27; + return 2; + } + } while (0); + + do { /* PaX: patched PLT emulation #2 */ + unsigned int ldah, lda, br; + + err = get_user(ldah, (unsigned int *)regs->pc); + err |= get_user(lda, (unsigned int *)(regs->pc+4)); + err |= get_user(br, (unsigned int *)(regs->pc+8)); + + if (err) + break; + + if ((ldah & 0xFFFF0000U) == 0x277B0000U && + (lda & 0xFFFF0000U) == 0xA77B0000U && + (br & 0xFFE00000U) == 0xC3E00000U) + { + unsigned long addr = br | 0xFFFFFFFFFFE00000UL; + unsigned long addrh = (ldah | 0xFFFFFFFFFFFF0000UL) << 16; + unsigned long addrl = lda | 0xFFFFFFFFFFFF0000UL; + + regs->r27 += ((addrh ^ 0x80000000UL) + 0x80000000UL) + ((addrl ^ 0x8000UL) + 0x8000UL); + regs->pc += 12 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2); + return 2; + } + } while (0); + + do { /* PaX: unpatched PLT emulation */ + unsigned int br; + + err = get_user(br, (unsigned int *)regs->pc); + + if (!err && (br & 0xFFE00000U) == 0xC3800000U) { + unsigned int br2, ldq, nop, jmp; + unsigned long addr = br | 0xFFFFFFFFFFE00000UL, resolver; + + addr = regs->pc + 4 + (((addr ^ 0x00100000UL) + 0x00100000UL) << 2); + err = get_user(br2, (unsigned int *)addr); + err |= get_user(ldq, (unsigned int *)(addr+4)); + err |= get_user(nop, (unsigned int *)(addr+8)); + err |= get_user(jmp, (unsigned int *)(addr+12)); + err |= get_user(resolver, (unsigned long *)(addr+16)); + + if (err) + break; + + if (br2 == 0xC3600000U && + ldq == 0xA77B000CU && + nop == 0x47FF041FU && + jmp == 0x6B7B0000U) + { + regs->r28 = regs->pc+4; + regs->r27 = addr+16; + regs->pc = resolver; + return 3; + } + } + } while (0); +#endif + + return 1; +} + +void pax_report_insns(void *pc, void *sp) +{ + unsigned long i; + + printk(KERN_ERR "PAX: bytes at PC: "); + for (i = 0; i < 5; i++) { + unsigned int c; + if (get_user(c, (unsigned int*)pc+i)) + printk("???????? "); + else + printk("%08x ", c); + } + printk("\n"); +} +#endif /* * This routine handles page faults. It determines the address, @@ -133,8 +250,29 @@ do_page_fault(unsigned long address, uns good_area: info.si_code = SEGV_ACCERR; if (cause < 0) { - if (!(vma->vm_flags & VM_EXEC)) + if (!(vma->vm_flags & VM_EXEC)) { + +#ifdef CONFIG_PAX_PAGEEXEC + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->pc) + goto bad_area; + + up_read(&mm->mmap_sem); + switch(pax_handle_fetch_fault(regs)) { + +#ifdef CONFIG_PAX_EMUPLT + case 2: + case 3: + return; +#endif + + } + pax_report_fault(regs, (void*)regs->pc, (void*)rdusp()); + do_exit(SIGKILL); +#else goto bad_area; +#endif + + } } else if (!cause) { /* Allow reads even for write-only mappings */ if (!(vma->vm_flags & (VM_READ | VM_WRITE))) diff -urNp linux-2.4.37.7/arch/arm/config.in linux-2.4.37.7/arch/arm/config.in --- linux-2.4.37.7/arch/arm/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/arm/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -736,3 +736,11 @@ endmenu source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urNp linux-2.4.37.7/arch/arm/kernel/setup.c linux-2.4.37.7/arch/arm/kernel/setup.c --- linux-2.4.37.7/arch/arm/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/arm/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -611,7 +611,7 @@ static void c_stop(struct seq_file *m, v { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { .start = c_start, .next = c_next, .stop = c_stop, diff -urNp linux-2.4.37.7/arch/cris/config.in linux-2.4.37.7/arch/cris/config.in --- linux-2.4.37.7/arch/cris/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/cris/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -276,3 +276,12 @@ int 'Kernel messages buffer length shift source crypto/Config.in source lib/Config.in endmenu + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu + diff -urNp linux-2.4.37.7/arch/cris/drivers/ds1302.c linux-2.4.37.7/arch/cris/drivers/ds1302.c --- linux-2.4.37.7/arch/cris/drivers/ds1302.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/cris/drivers/ds1302.c 2009-11-10 19:30:27.000000000 -0500 @@ -473,7 +473,7 @@ print_rtc_status(void) /* The various file operations we support. */ -static struct file_operations rtc_fops = { +static const struct file_operations rtc_fops = { owner: THIS_MODULE, ioctl: rtc_ioctl, }; diff -urNp linux-2.4.37.7/arch/cris/drivers/examples/kiobuftest.c linux-2.4.37.7/arch/cris/drivers/examples/kiobuftest.c --- linux-2.4.37.7/arch/cris/drivers/examples/kiobuftest.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/cris/drivers/examples/kiobuftest.c 2009-11-10 19:30:27.000000000 -0500 @@ -78,7 +78,7 @@ kiobuf_read(struct file *filp, char *buf } -static struct file_operations kiobuf_fops = { +static const struct file_operations kiobuf_fops = { owner: THIS_MODULE, read: kiobuf_read }; diff -urNp linux-2.4.37.7/arch/cris/drivers/gpio.c linux-2.4.37.7/arch/cris/drivers/gpio.c --- linux-2.4.37.7/arch/cris/drivers/gpio.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/cris/drivers/gpio.c 2009-11-10 19:30:27.000000000 -0500 @@ -779,7 +779,7 @@ gpio_leds_ioctl(unsigned int cmd, unsign return 0; } -struct file_operations gpio_fops = { +const struct file_operations gpio_fops = { owner: THIS_MODULE, poll: gpio_poll, ioctl: gpio_ioctl, diff -urNp linux-2.4.37.7/arch/cris/drivers/i2c.c linux-2.4.37.7/arch/cris/drivers/i2c.c --- linux-2.4.37.7/arch/cris/drivers/i2c.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/cris/drivers/i2c.c 2009-11-10 19:30:27.000000000 -0500 @@ -681,7 +681,7 @@ i2c_ioctl(struct inode *inode, struct fi return 0; } -static struct file_operations i2c_fops = { +static const struct file_operations i2c_fops = { owner: THIS_MODULE, ioctl: i2c_ioctl, open: i2c_open, diff -urNp linux-2.4.37.7/arch/cris/drivers/pcf8563.c linux-2.4.37.7/arch/cris/drivers/pcf8563.c --- linux-2.4.37.7/arch/cris/drivers/pcf8563.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/cris/drivers/pcf8563.c 2009-11-10 19:30:27.000000000 -0500 @@ -51,7 +51,7 @@ int pcf8563_ioctl(struct inode *, struct int pcf8563_open(struct inode *, struct file *); int pcf8563_release(struct inode *, struct file *); -static struct file_operations pcf8563_fops = { +static const struct file_operations pcf8563_fops = { owner: THIS_MODULE, ioctl: pcf8563_ioctl, open: pcf8563_open, diff -urNp linux-2.4.37.7/arch/cris/drivers/sync_serial.c linux-2.4.37.7/arch/cris/drivers/sync_serial.c --- linux-2.4.37.7/arch/cris/drivers/sync_serial.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/cris/drivers/sync_serial.c 2009-11-10 19:30:27.000000000 -0500 @@ -214,7 +214,7 @@ static unsigned gen_config_ii_shadow = 0 #define NUMBER_OF_PORTS (sizeof(ports)/sizeof(sync_port)) -static struct file_operations sync_serial_fops = { +static const struct file_operations sync_serial_fops = { .owner = THIS_MODULE, .write = sync_serial_write, .read = sync_serial_read, diff -urNp linux-2.4.37.7/arch/cris/drivers/virtex.c linux-2.4.37.7/arch/cris/drivers/virtex.c --- linux-2.4.37.7/arch/cris/drivers/virtex.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/cris/drivers/virtex.c 2009-11-10 19:30:27.000000000 -0500 @@ -372,7 +372,7 @@ virtex_ioctl(struct inode *inode, struct return 0; } -static struct file_operations virtex_fops = { +static const struct file_operations virtex_fops = { owner: THIS_MODULE, ioctl: virtex_ioctl, open: virtex_open, diff -urNp linux-2.4.37.7/arch/cris/kernel/setup.c linux-2.4.37.7/arch/cris/kernel/setup.c --- linux-2.4.37.7/arch/cris/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/cris/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -283,7 +283,7 @@ static void c_stop(struct seq_file *m, v { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { start: c_start, next: c_next, stop: c_stop, diff -urNp linux-2.4.37.7/arch/i386/boot/bootsect.S linux-2.4.37.7/arch/i386/boot/bootsect.S --- linux-2.4.37.7/arch/i386/boot/bootsect.S 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/boot/bootsect.S 2009-11-10 19:30:27.000000000 -0500 @@ -237,7 +237,7 @@ rp_read: #ifdef __BIG_KERNEL__ # look in setup.S for bootsect_kludge bootsect_kludge = 0x220 # 0x200 + 0x20 which is the size of the - lcall bootsect_kludge # bootsector + bootsect_kludge offset + lcall *bootsect_kludge # bootsector + bootsect_kludge offset #else movw %es, %ax subw $SYSSEG, %ax diff -urNp linux-2.4.37.7/arch/i386/boot/compressed/head.S linux-2.4.37.7/arch/i386/boot/compressed/head.S --- linux-2.4.37.7/arch/i386/boot/compressed/head.S 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/boot/compressed/head.S 2009-11-10 19:30:27.000000000 -0500 @@ -38,11 +38,13 @@ startup_32: movl %eax,%gs lss SYMBOL_NAME(stack_start),%esp + movl 0x000000,%ecx xorl %eax,%eax 1: incl %eax # check that A20 really IS enabled movl %eax,0x000000 # loop forever if it isn't cmpl %eax,0x100000 je 1b + movl %ecx,0x000000 /* * Initialize eflags. Some BIOS's leave bits like NT set. This would diff -urNp linux-2.4.37.7/arch/i386/boot/setup.S linux-2.4.37.7/arch/i386/boot/setup.S --- linux-2.4.37.7/arch/i386/boot/setup.S 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/boot/setup.S 2009-11-10 19:30:27.000000000 -0500 @@ -637,7 +637,7 @@ edd_done: cmpw $0, %cs:realmode_swtch jz rmodeswtch_normal - lcall %cs:realmode_swtch + lcall *%cs:realmode_swtch jmp rmodeswtch_end diff -urNp linux-2.4.37.7/arch/i386/config.in linux-2.4.37.7/arch/i386/config.in --- linux-2.4.37.7/arch/i386/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -103,6 +103,7 @@ if [ "$CONFIG_M586MMX" = "y" ]; then fi if [ "$CONFIG_M686" = "y" ]; then define_int CONFIG_X86_L1_CACHE_SHIFT 5 + define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_HAS_TSC y define_bool CONFIG_X86_GOOD_APIC y bool 'PGE extensions (not for Cyrix/Transmeta)' CONFIG_X86_PGE @@ -112,6 +113,7 @@ if [ "$CONFIG_M686" = "y" ]; then fi if [ "$CONFIG_MPENTIUMIII" = "y" ]; then define_int CONFIG_X86_L1_CACHE_SHIFT 5 + define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_HAS_TSC y define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_PGE y @@ -120,6 +122,7 @@ if [ "$CONFIG_MPENTIUMIII" = "y" ]; then fi if [ "$CONFIG_MPENTIUM4" = "y" ]; then define_int CONFIG_X86_L1_CACHE_SHIFT 7 + define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_HAS_TSC y define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_PGE y @@ -139,6 +142,7 @@ if [ "$CONFIG_MK8" = "y" ]; then fi if [ "$CONFIG_MK7" = "y" ]; then define_int CONFIG_X86_L1_CACHE_SHIFT 6 + define_bool CONFIG_X86_ALIGNMENT_16 y define_bool CONFIG_X86_HAS_TSC y define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_USE_3DNOW y @@ -505,3 +509,11 @@ endmenu source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urNp linux-2.4.37.7/arch/i386/kernel/acpi.c linux-2.4.37.7/arch/i386/kernel/acpi.c --- linux-2.4.37.7/arch/i386/kernel/acpi.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/acpi.c 2009-11-10 19:30:27.000000000 -0500 @@ -370,7 +370,7 @@ acpi_scan_rsdp ( * RSDP signature. */ for (offset = 0; offset < length; offset += 16) { - if (strncmp((char *) (start + offset), "RSD PTR ", sig_len)) + if (strncmp((char *) (phys_to_virt(start) + offset), "RSD PTR ", sig_len)) continue; return (start + offset); } @@ -708,7 +708,7 @@ static void acpi_create_identity_pmd (vo saved_pmd = *pmd; /* set the new one */ - set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(ptep))); + set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(ptep))); /* flush the TLB */ local_flush_tlb(); diff -urNp linux-2.4.37.7/arch/i386/kernel/apm.c linux-2.4.37.7/arch/i386/kernel/apm.c --- linux-2.4.37.7/arch/i386/kernel/apm.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/apm.c 2009-11-10 19:30:27.000000000 -0500 @@ -223,7 +223,7 @@ #include extern unsigned long get_cmos_time(void); -extern void machine_real_restart(unsigned char *, int); +extern void machine_real_restart(const unsigned char *, unsigned int); #if defined(CONFIG_APM_DISPLAY_BLANK) && defined(CONFIG_VT) extern int (*console_blank_hook)(int); @@ -614,7 +614,7 @@ static u8 apm_bios_call(u32 func, u32 eb __asm__ __volatile__(APM_DO_ZERO_SEGS "pushl %%edi\n\t" "pushl %%ebp\n\t" - "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t" + "lcall *%%ss:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t" "setc %%al\n\t" "popl %%ebp\n\t" "popl %%edi\n\t" @@ -666,7 +666,7 @@ static u8 apm_bios_call_simple(u32 func, __asm__ __volatile__(APM_DO_ZERO_SEGS "pushl %%edi\n\t" "pushl %%ebp\n\t" - "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t" + "lcall *%%ss:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t" "setc %%bl\n\t" "popl %%ebp\n\t" "popl %%edi\n\t" @@ -924,7 +924,7 @@ recalc: static void apm_power_off(void) { - unsigned char po_bios_call[] = { + const unsigned char po_bios_call[] = { 0xb8, 0x00, 0x10, /* movw $0x1000,ax */ 0x8e, 0xd0, /* movw ax,ss */ 0xbc, 0x00, 0xf0, /* movw $0xf000,sp */ @@ -1883,7 +1883,7 @@ static int __init apm_setup(char *str) __setup("apm=", apm_setup); #endif -static struct file_operations apm_bios_fops = { +static const struct file_operations apm_bios_fops = { owner: THIS_MODULE, read: do_read, poll: do_poll, @@ -1985,6 +1985,12 @@ static int __init apm_init(void) __va((unsigned long)0x40 << 4)); _set_limit((char *)&gdt[APM_40 >> 3], 4095 - (0x40 << 4)); +#ifdef CONFIG_PAX_SEGMEXEC + set_base(gdt2[APM_40 >> 3], + __va((unsigned long)0x40 << 4)); + _set_limit((char *)&gdt2[APM_40 >> 3], 4095 - (0x40 << 4)); +#endif + apm_bios_entry.offset = apm_info.bios.offset; apm_bios_entry.segment = APM_CS; set_base(gdt[APM_CS >> 3], @@ -1993,6 +1999,16 @@ static int __init apm_init(void) __va((unsigned long)apm_info.bios.cseg_16 << 4)); set_base(gdt[APM_DS >> 3], __va((unsigned long)apm_info.bios.dseg << 4)); + +#ifdef CONFIG_PAX_SEGMEXEC + set_base(gdt2[APM_CS >> 3], + __va((unsigned long)apm_info.bios.cseg << 4)); + set_base(gdt2[APM_CS_16 >> 3], + __va((unsigned long)apm_info.bios.cseg_16 << 4)); + set_base(gdt2[APM_DS >> 3], + __va((unsigned long)apm_info.bios.dseg << 4)); +#endif + #ifndef APM_RELAX_SEGMENTS if (apm_info.bios.version == 0x100) { #endif @@ -2002,6 +2018,13 @@ static int __init apm_init(void) _set_limit((char *)&gdt[APM_CS_16 >> 3], 64 * 1024 - 1); /* For the DEC Hinote Ultra CT475 (and others?) */ _set_limit((char *)&gdt[APM_DS >> 3], 64 * 1024 - 1); + +#ifdef CONFIG_PAX_SEGMEXEC + _set_limit((char *)&gdt2[APM_CS >> 3], 64 * 1024 - 1); + _set_limit((char *)&gdt2[APM_CS_16 >> 3], 64 * 1024 - 1); + _set_limit((char *)&gdt2[APM_DS >> 3], 64 * 1024 - 1); +#endif + #ifndef APM_RELAX_SEGMENTS } else { _set_limit((char *)&gdt[APM_CS >> 3], @@ -2010,6 +2033,16 @@ static int __init apm_init(void) (apm_info.bios.cseg_16_len - 1) & 0xffff); _set_limit((char *)&gdt[APM_DS >> 3], (apm_info.bios.dseg_len - 1) & 0xffff); + +#ifdef CONFIG_PAX_SEGMEXEC + _set_limit((char *)&gdt2[APM_CS >> 3], + (apm_info.bios.cseg_len - 1) & 0xffff); + _set_limit((char *)&gdt2[APM_CS_16 >> 3], + (apm_info.bios.cseg_16_len - 1) & 0xffff); + _set_limit((char *)&gdt2[APM_DS >> 3], + (apm_info.bios.dseg_len - 1) & 0xffff); +#endif + } #endif diff -urNp linux-2.4.37.7/arch/i386/kernel/cpuid.c linux-2.4.37.7/arch/i386/kernel/cpuid.c --- linux-2.4.37.7/arch/i386/kernel/cpuid.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/cpuid.c 2009-11-10 19:30:27.000000000 -0500 @@ -133,7 +133,7 @@ static int cpuid_open(struct inode *inod /* * File operations we support */ -static struct file_operations cpuid_fops = { +static const struct file_operations cpuid_fops = { owner: THIS_MODULE, llseek: cpuid_seek, read: cpuid_read, diff -urNp linux-2.4.37.7/arch/i386/kernel/entry.S linux-2.4.37.7/arch/i386/kernel/entry.S --- linux-2.4.37.7/arch/i386/kernel/entry.S 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/entry.S 2009-11-10 19:30:27.000000000 -0500 @@ -84,7 +84,7 @@ processor = 52 ENOSYS = 38 -#define SAVE_ALL \ +#define __SAVE_ALL \ cld; \ pushl %es; \ pushl %ds; \ @@ -99,6 +99,18 @@ ENOSYS = 38 movl %edx,%ds; \ movl %edx,%es; +#ifdef CONFIG_PAX_KERNEXEC +#define SAVE_ALL \ + __SAVE_ALL \ + movl %cr0,%edx; \ + movl %edx,%ebp; \ + orl $0x10000,%edx; \ + xorl %edx,%ebp; \ + movl %edx,%cr0; +#else +#define SAVE_ALL __SAVE_ALL +#endif + #define RESTORE_ALL \ popl %ebx; \ popl %ecx; \ @@ -209,6 +221,17 @@ ENTRY(system_call) jae badsys call *SYMBOL_NAME(sys_call_table)(,%eax,4) movl %eax,EAX(%esp) # save the return value + +#ifdef CONFIG_PAX_RANDKSTACK + cli # need_resched and signals atomic test + cmpl $0,need_resched(%ebx) + jne reschedule + cmpl $0,sigpending(%ebx) + jne signal_return + call SYMBOL_NAME(pax_randomize_kstack) + jmp restore_all +#endif + ENTRY(ret_from_sys_call) cli # need_resched and signals atomic test cmpl $0,need_resched(%ebx) @@ -260,6 +283,13 @@ ret_from_exception: movb CS(%esp),%al testl $(VM_MASK | 3),%eax # return to VM86 mode or non-supervisor? jne ret_from_sys_call + +#ifdef CONFIG_PAX_KERNEXEC + movl %cr0, %edx + xorl %ebp, %edx + movl %edx, %cr0 +#endif + jmp restore_all ALIGN @@ -283,6 +313,15 @@ error_code: pushl %ecx pushl %ebx cld + +#ifdef CONFIG_PAX_KERNEXEC + movl %cr0,%edx + movl %edx,%ebp + orl $0x10000,%edx + xorl %edx,%ebp + movl %edx,%cr0 +#endif + movl %es,%ecx movl ORIG_EAX(%esp), %esi # get the error code movl ES(%esp), %edi # get the function address @@ -337,6 +376,13 @@ ENTRY(nmi) pushl %edx call SYMBOL_NAME(do_nmi) addl $8,%esp + +#ifdef CONFIG_PAX_KERNEXEC + movl %cr0, %edx + xorl %ebp, %edx + movl %edx, %cr0 +#endif + RESTORE_ALL ENTRY(int3) @@ -389,8 +435,77 @@ ENTRY(alignment_check) jmp error_code ENTRY(page_fault) +#ifdef CONFIG_PAX_PAGEEXEC + ALIGN + pushl $ SYMBOL_NAME(pax_do_page_fault) +#else pushl $ SYMBOL_NAME(do_page_fault) +#endif + +#ifndef CONFIG_PAX_EMUTRAMP jmp error_code +#else + pushl %ds + pushl %eax + xorl %eax,%eax + pushl %ebp + pushl %edi + pushl %esi + pushl %edx + decl %eax # eax = -1 + pushl %ecx + pushl %ebx + cld + +#ifdef CONFIG_PAX_KERNEXEC + movl %cr0,%edx + movl %edx,%ebp + orl $0x10000,%edx + xorl %edx,%ebp + movl %edx,%cr0 +#endif + + movl %es,%ecx + movl ORIG_EAX(%esp), %esi # get the error code + movl ES(%esp), %edi # get the function address + movl %eax, ORIG_EAX(%esp) + movl %ecx, ES(%esp) + movl %esp,%edx + pushl %esi # push the error code + pushl %edx # push the pt_regs pointer + movl $(__KERNEL_DS),%edx + movl %edx,%ds + movl %edx,%es + GET_CURRENT(%ebx) + call *%edi + addl $8,%esp + decl %eax + jnz ret_from_exception + + popl %ebx + popl %ecx + popl %edx + popl %esi + popl %edi + popl %ebp + popl %eax +1: popl %ds; +2: popl %es; + addl $4,%esp; + jmp system_call + +.section .fixup,"ax"; +3: movl $0,(%esp); + jmp 1b; +4: movl $0,(%esp); + jmp 2b; +.previous; +.section __ex_table,"a"; + .align 4; + .long 1b,3b; + .long 2b,4b; +.previous +#endif ENTRY(machine_check) pushl $0 @@ -402,7 +517,7 @@ ENTRY(spurious_interrupt_bug) pushl $ SYMBOL_NAME(do_spurious_interrupt_bug) jmp error_code -.data +.section .rodata,"a",@progbits ENTRY(sys_call_table) .long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/ .long SYMBOL_NAME(sys_exit) diff -urNp linux-2.4.37.7/arch/i386/kernel/head.S linux-2.4.37.7/arch/i386/kernel/head.S --- linux-2.4.37.7/arch/i386/kernel/head.S 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/head.S 2009-11-10 19:30:27.000000000 -0500 @@ -36,11 +36,23 @@ #define X86_CAPABILITY CPU_PARAMS+12 #define X86_VENDOR_ID CPU_PARAMS+36 /* tied to NCAPINTS in cpufeature.h */ +#ifdef CONFIG_PAX_KERNEXEC +/* PaX: fill first page in .text with int3 to catch NULL derefs in kernel mode */ +.fill 4096,1,0xcc +#endif + +/* + * Real beginning of normal "text" segment + */ +ENTRY(stext) +ENTRY(_stext) + /* * swapper_pg_dir is the main page directory, address 0x00101000 * * On entry, %esi points to the real-mode code as a 32-bit pointer. */ +.global startup_32 startup_32: /* * Set segments to known values @@ -51,9 +63,88 @@ startup_32: movl %eax,%es movl %eax,%fs movl %eax,%gs + movl %eax,%ss + #ifdef CONFIG_SMP orw %bx,%bx - jz 1f + jnz 1f +#endif + +#ifdef CONFIG_PAX_MEMORY_UDEREF + /* check for VMware */ + movl $0x564d5868,%eax + xorl %ebx,%ebx + movl $0xa,%ecx + movl $0x5658,%edx + in (%dx),%eax + cmpl $0x564d5868,%ebx + jz 2f + + movl $((((__PAGE_OFFSET-1) & 0xf0000000) >> 12) | 0x00c09700),%eax + movl %eax,(SYMBOL_NAME(gdt_table) - __PAGE_OFFSET + __KERNEL_DS + 4) + +#ifdef CONFIG_PAX_SEGMEXEC + movl %eax,(SYMBOL_NAME(gdt_table2) - __PAGE_OFFSET + __KERNEL_DS + 4) +#endif + +2: +#endif + +#ifdef CONFIG_PAX_KERNEXEC + movl $__KERNEL_TEXT_OFFSET,%eax + movw %ax,(SYMBOL_NAME(gdt_table) + __KERNEL_CS + 2 - __PAGE_OFFSET) + rorl $16,%eax + movb %al,(SYMBOL_NAME(gdt_table) + __KERNEL_CS + 4 - __PAGE_OFFSET) + movb %ah,(SYMBOL_NAME(gdt_table) + __KERNEL_CS + 7 - __PAGE_OFFSET) + +#ifdef CONFIG_PAX_SEGMEXEC + movb %al,(SYMBOL_NAME(gdt_table2) + __KERNEL_CS + 4 - __PAGE_OFFSET) + movb %ah,(SYMBOL_NAME(gdt_table2) + __KERNEL_CS + 7 - __PAGE_OFFSET) + rorl $16,%eax + movw %ax,(SYMBOL_NAME(gdt_table2) + __KERNEL_CS + 2 - __PAGE_OFFSET) +#endif + +#endif + +/* + * Clear BSS first so that there are no surprises... + * No need to cld as DF is already clear from cld above... + */ + xorl %eax,%eax + movl $ SYMBOL_NAME(__bss_start) - __PAGE_OFFSET,%edi + movl $ SYMBOL_NAME(__bss_end) - __PAGE_OFFSET,%ecx + subl %edi,%ecx + rep + stosb +/* + * Copy bootup parameters out of the way. First 2kB of + * _empty_zero_page is for boot parameters, second 2kB + * is for the command line. + * + * Note: %esi still has the pointer to the real-mode data. + */ + movl $ SYMBOL_NAME(empty_zero_page) - __PAGE_OFFSET,%edi + movl $512,%ecx + cld + rep + movsl + xorl %eax,%eax + movl $512,%ecx + rep + stosl + movl SYMBOL_NAME(empty_zero_page) - __PAGE_OFFSET + NEW_CL_POINTER,%esi + andl %esi,%esi + jnz 2f # New command line protocol + cmpw $(OLD_CL_MAGIC),OLD_CL_MAGIC_ADDR + jne 1f + movzwl OLD_CL_OFFSET,%esi + addl $(OLD_CL_BASE_ADDR),%esi +2: + movl $ SYMBOL_NAME(empty_zero_page) - __PAGE_OFFSET + 2048,%edi + movl $512,%ecx + rep + movsl +1: /* * New page tables may be in 4Mbyte page mode and may @@ -71,22 +162,28 @@ startup_32: */ #define cr4_bits mmu_cr4_features-__PAGE_OFFSET cmpl $0,cr4_bits - je 3f + je 1f movl %cr4,%eax # Turn on paging options (PSE,PAE,..) orl cr4_bits,%eax movl %eax,%cr4 - jmp 3f 1: + +#ifdef CONFIG_SMP + orw %bx,%bx + jnz 3f #endif + /* * Initialize page tables */ movl $pg0-__PAGE_OFFSET,%edi /* initialize page tables */ - movl $007,%eax /* "007" doesn't mean with right to kill, but - PRESENT+RW+USER */ + movl $0x63,%eax /* "0x63" is PRESENT+RW+ACCESSED+DIRTY */ 2: stosl +#ifdef CONFIG_X86_PAE + addl $4,%edi +#endif add $0x1000,%eax - cmp $empty_zero_page-__PAGE_OFFSET,%edi + cmp $0x01000063,%eax jne 2b /* @@ -100,37 +197,16 @@ startup_32: movl %eax,%cr0 /* ..and set paging (PG) bit */ jmp 1f /* flush the prefetch-queue */ 1: - movl $1f,%eax - jmp *%eax /* make sure eip is relocated */ -1: + lgdt gdt_descr + ljmp $__KERNEL_CS,$1f +1: movl $(__KERNEL_DS),%eax # reload all the segment registers + movl %eax,%ds # after changing gdt. + movl %eax,%es + movl %eax,%fs + movl %eax,%gs /* Set up the stack pointer */ lss stack_start,%esp -#ifdef CONFIG_SMP - orw %bx,%bx - jz 1f /* Initial CPU cleans BSS */ - pushl $0 - popfl - jmp checkCPUtype -1: -#endif /* CONFIG_SMP */ - -/* - * Clear BSS first so that there are no surprises... - * No need to cld as DF is already clear from cld above... - */ - xorl %eax,%eax - movl $ SYMBOL_NAME(__bss_start),%edi - movl $ SYMBOL_NAME(_end),%ecx - subl %edi,%ecx - rep - stosb - -/* - * start system 32-bit setup. We need to re-do some of the things done - * in 16-bit mode for the "real" operations. - */ - call setup_idt /* * Initialize eflags. Some BIOS's leave bits like NT set. This would * confuse the debugger if this code is traced. @@ -138,35 +214,18 @@ startup_32: */ pushl $0 popfl + +#ifdef CONFIG_SMP + orw %bx,%bx + jnz checkCPUtype +#endif /* CONFIG_SMP */ + /* - * Copy bootup parameters out of the way. First 2kB of - * _empty_zero_page is for boot parameters, second 2kB - * is for the command line. - * - * Note: %esi still has the pointer to the real-mode data. + * start system 32-bit setup. We need to re-do some of the things done + * in 16-bit mode for the "real" operations. */ - movl $ SYMBOL_NAME(empty_zero_page),%edi - movl $512,%ecx - cld - rep - movsl - xorl %eax,%eax - movl $512,%ecx - rep - stosl - movl SYMBOL_NAME(empty_zero_page)+NEW_CL_POINTER,%esi - andl %esi,%esi - jnz 2f # New command line protocol - cmpw $(OLD_CL_MAGIC),OLD_CL_MAGIC_ADDR - jne 1f - movzwl OLD_CL_OFFSET,%esi - addl $(OLD_CL_BASE_ADDR),%esi -2: - movl $ SYMBOL_NAME(empty_zero_page)+2048,%edi - movl $512,%ecx - rep - movsl -1: + call setup_idt + checkCPUtype: movl $-1,X86_CPUID # -1 for no CPUID initially @@ -241,20 +300,7 @@ is386: pushl %ecx # restore original EF 2: movl %eax,%cr0 call check_x87 incb ready - lgdt gdt_descr lidt idt_descr - ljmp $(__KERNEL_CS),$1f -1: movl $(__KERNEL_DS),%eax # reload all the segment registers - movl %eax,%ds # after changing gdt. - movl %eax,%es - movl %eax,%fs - movl %eax,%gs -#ifdef CONFIG_SMP - movl $(__KERNEL_DS), %eax - movl %eax,%ss # Reload the stack pointer (segment only) -#else - lss stack_start,%esp # Load processor stack -#endif xorl %eax,%eax lldt %ax cld # gcc2 wants the direction flag cleared at all times @@ -272,8 +318,6 @@ L6: jmp L6 # main should never return here, but # just in case, we know what happens. -ready: .byte 0 - /* * We depend on ET to be correct. This checks for 287/387. */ @@ -319,13 +363,6 @@ rp_sidt: jne rp_sidt ret -ENTRY(stack_start) - .long SYMBOL_NAME(init_task_union)+8192 - .long __KERNEL_DS - -/* This is the default interrupt "handler" :-) */ -int_msg: - .asciz "Unknown interrupt, stack: %p %p %p %p\n" ALIGN ignore_int: cld @@ -341,6 +378,18 @@ ignore_int: 1: hlt jmp 1b +.data +ready: .byte 0 + +ENTRY(stack_start) + .long SYMBOL_NAME(init_task_union)+8192-8 + .long __KERNEL_DS + +.section .rodata,"a" +/* This is the default interrupt "handler" :-) */ +int_msg: + .asciz "Unknown interrupt, stack: %p %p %p %p\n" + /* * The interrupt descriptor table has room for 256 idt's, * the global descriptor table is dependent on the number @@ -360,60 +409,134 @@ idt_descr: SYMBOL_NAME(idt): .long SYMBOL_NAME(idt_table) +.globl SYMBOL_NAME(boot_gdt_table) +boot_gdt_table: + .fill __KERNEL_CS,1,0 + .quad 0x00cf9b000000ffff /* 0x10 kernel 4GB code at 0x00000000 */ + .quad 0x00cf93000000ffff /* 0x18 kernel 4GB data at 0x00000000 */ + .word 0 gdt_descr: .word GDT_ENTRIES*8-1 SYMBOL_NAME(gdt): .long SYMBOL_NAME(gdt_table) +#ifdef CONFIG_PAX_SEGMEXEC +.globl SYMBOL_NAME(gdt2) + .word 0 +gdt_descr2: + .word GDT_ENTRIES*8-1 +SYMBOL_NAME(gdt2): + .long SYMBOL_NAME(gdt_table2) +#endif + /* - * This is initialized to create an identity-mapping at 0-8M (for bootup - * purposes) and another mapping of the 0-8M area at virtual address + * This is initialized to create an identity-mapping at 0-16M (for bootup + * purposes) and another mapping of the 0-16M area at virtual address * PAGE_OFFSET. */ -.org 0x1000 +.section .swapper_pg_dir,"a",@progbits ENTRY(swapper_pg_dir) - .long 0x00102007 - .long 0x00103007 - .fill BOOT_USER_PGD_PTRS-2,4,0 - /* default: 766 entries */ - .long 0x00102007 - .long 0x00103007 - /* default: 254 entries */ - .fill BOOT_KERNEL_PGD_PTRS-2,4,0 +#ifdef CONFIG_X86_PAE + .long swapper_pm_dir-__PAGE_OFFSET+1 + .long 0 + .long swapper_pm_dir+512*8-__PAGE_OFFSET+1 + .long 0 + .long swapper_pm_dir+512*16-__PAGE_OFFSET+1 + .long 0 + .long swapper_pm_dir+512*24-__PAGE_OFFSET+1 + .long 0 +#else + .long pg0-__PAGE_OFFSET+63 + .long pg0+1024*4-__PAGE_OFFSET+63 + .long pg0+1024*8-__PAGE_OFFSET+63 + .long pg0+1024*12-__PAGE_OFFSET+63 + .fill BOOT_USER_PGD_PTRS-4,4,0 + /* default: 764 entries */ + .long pg0-__PAGE_OFFSET+67 + .long pg0+1024*4-__PAGE_OFFSET+63 + .long pg0+1024*8-__PAGE_OFFSET+63 + .long pg0+1024*12-__PAGE_OFFSET+63 + /* default: 252 entries */ + .fill BOOT_KERNEL_PGD_PTRS-4,4,0 +#endif + +#ifdef CONFIG_X86_PAE +.section .swapper_pm_dir,"a",@progbits +ENTRY(swapper_pm_dir) + .long pg0-__PAGE_OFFSET+63 + .long 0 + .long pg0+512*8-__PAGE_OFFSET+63 + .long 0 + .long pg0+512*16-__PAGE_OFFSET+63 + .long 0 + .long pg0+512*24-__PAGE_OFFSET+63 + .long 0 + .long pg0+512*32-__PAGE_OFFSET+63 + .long 0 + .long pg0+512*40-__PAGE_OFFSET+63 + .long 0 + .long pg0+512*48-__PAGE_OFFSET+63 + .long 0 + .long pg0+512*56-__PAGE_OFFSET+63 + .long 0 + .fill BOOT_USER_PMD_PTRS-8,8,0 + /* default: 1024+512-4 entries */ + .long pg0-__PAGE_OFFSET+67 + .long 0 + .long pg0+512*8-__PAGE_OFFSET+63 + .long 0 + .long pg0+512*16-__PAGE_OFFSET+63 + .long 0 + .long pg0+512*24-__PAGE_OFFSET+63 + .long 0 + .long pg0+512*32-__PAGE_OFFSET+63 + .long 0 + .long pg0+512*40-__PAGE_OFFSET+63 + .long 0 + .long pg0+512*48-__PAGE_OFFSET+63 + .long 0 + .long pg0+512*56-__PAGE_OFFSET+63 + .long 0 + /* default: 512-4 entries */ + .fill BOOT_KERNEL_PMD_PTRS-8,8,0 +#endif /* - * The page tables are initialized to only 8MB here - the final page + * The page tables are initialized to only 16MB here - the final page * tables are set up later depending on memory size. */ -.org 0x2000 +.section .pg0,"a",@progbits ENTRY(pg0) + .fill 1024*4,4,0 -.org 0x3000 -ENTRY(pg1) +#ifdef CONFIG_X86_PAE + .fill 1024*4,4,0 +#endif /* * empty_zero_page must immediately follow the page tables ! (The * initialization loop counts until empty_zero_page) */ - -.org 0x4000 +.section .empty_zero_page,"a",@progbits ENTRY(empty_zero_page) - -.org 0x5000 + .fill 1024,4,0 /* - * Real beginning of normal "text" segment + * The IDT has to be page-aligned to simplify the Pentium + * F0 0F bug workaround.. We have a special link segment + * for this. */ -ENTRY(stext) -ENTRY(_stext) +.section .idt,"a",@progbits +ENTRY(idt_table) + .fill 256,8,0 /* * This starts the data section. Note that the above is all * in the text section because it has alignment requirements * that we cannot fulfill any other way. */ -.data +.section .rodata,"a",@progbits ALIGN /* @@ -425,18 +548,39 @@ ALIGN ENTRY(gdt_table) .quad 0x0000000000000000 /* NULL descriptor */ .quad 0x0000000000000000 /* not used */ - .quad 0x00cf9a000000ffff /* 0x10 kernel 4GB code at 0x00000000 */ - .quad 0x00cf92000000ffff /* 0x18 kernel 4GB data at 0x00000000 */ - .quad 0x00cffa000000ffff /* 0x23 user 4GB code at 0x00000000 */ - .quad 0x00cff2000000ffff /* 0x2b user 4GB data at 0x00000000 */ - .quad 0x0000000000000000 /* not used */ + .quad 0x00cf9b000000ffff /* 0x10 kernel 4GB code at 0x00000000 */ + .quad 0x00cf93000000ffff /* 0x18 kernel 4GB data at 0x00000000 */ + .quad 0x00cffb000000ffff /* 0x23 user 4GB code at 0x00000000 */ + .quad 0x00cff3000000ffff /* 0x2b user 4GB data at 0x00000000 */ + .quad 0x0000000000000000 /* PCIBIOS_CS */ + .quad 0x0000000000000000 /* PCIBIOS_DS */ + /* + * The APM segments have byte granularity and their bases + * and limits are set at run time. + */ + .quad 0x0040930000000000 /* 0x40 APM set up for bad BIOS's */ + .quad 0x00409b0000000000 /* 0x48 APM CS code */ + .quad 0x00009b0000000000 /* 0x50 APM CS 16 code (16 bit) */ + .quad 0x0040930000000000 /* 0x58 APM DS data */ + .fill NR_CPUS*4,8,0 /* space for TSS's and LDT's */ + +#ifdef CONFIG_PAX_SEGMEXEC +ENTRY(gdt_table2) + .quad 0x0000000000000000 /* NULL descriptor */ .quad 0x0000000000000000 /* not used */ + .quad 0x00cf9b000000ffff /* 0x10 kernel 4GB code at 0x00000000 */ + .quad 0x00cf93000000ffff /* 0x18 kernel 4GB data at 0x00000000 */ + .quad 0x60c5fb000000ffff /* 0x23 user 1.5GB code at 0x60000000 */ + .quad 0x00cff3000000ffff /* 0x2b user 4GB data at 0x00000000 */ + .quad 0x0000000000000000 /* PCIBIOS_CS */ + .quad 0x0000000000000000 /* PCIBIOS_DS */ /* * The APM segments have byte granularity and their bases * and limits are set at run time. */ - .quad 0x0040920000000000 /* 0x40 APM set up for bad BIOS's */ - .quad 0x00409a0000000000 /* 0x48 APM CS code */ - .quad 0x00009a0000000000 /* 0x50 APM CS 16 code (16 bit) */ - .quad 0x0040920000000000 /* 0x58 APM DS data */ + .quad 0x0040930000000000 /* 0x40 APM set up for bad BIOS's */ + .quad 0x00409b0000000000 /* 0x48 APM CS code */ + .quad 0x00009b0000000000 /* 0x50 APM CS 16 code (16 bit) */ + .quad 0x0040930000000000 /* 0x58 APM DS data */ .fill NR_CPUS*4,8,0 /* space for TSS's and LDT's */ +#endif diff -urNp linux-2.4.37.7/arch/i386/kernel/i386_ksyms.c linux-2.4.37.7/arch/i386/kernel/i386_ksyms.c --- linux-2.4.37.7/arch/i386/kernel/i386_ksyms.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/i386_ksyms.c 2009-11-10 19:30:27.000000000 -0500 @@ -34,7 +34,7 @@ extern void dump_thread(struct pt_regs * extern spinlock_t rtc_lock; #if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE) -extern void machine_real_restart(unsigned char *, int); +extern void machine_real_restart(const unsigned char *, unsigned int); EXPORT_SYMBOL(machine_real_restart); extern void default_idle(void); EXPORT_SYMBOL(default_idle); @@ -74,6 +74,11 @@ EXPORT_SYMBOL(pm_power_off); EXPORT_SYMBOL(get_cmos_time); EXPORT_SYMBOL(apm_info); EXPORT_SYMBOL(gdt); + +#ifdef CONFIG_PAX_SEGMEXEC +EXPORT_SYMBOL(gdt2); +#endif + EXPORT_SYMBOL(empty_zero_page); #ifdef CONFIG_DEBUG_IOVIRT @@ -86,6 +91,8 @@ EXPORT_SYMBOL_NOVERS(__down_failed_trylo EXPORT_SYMBOL_NOVERS(__up_wakeup); /* Networking helper routines. */ EXPORT_SYMBOL(csum_partial_copy_generic); +EXPORT_SYMBOL(csum_partial_copy_generic_to_user); +EXPORT_SYMBOL(csum_partial_copy_generic_from_user); /* Delay loops */ EXPORT_SYMBOL(__ndelay); EXPORT_SYMBOL(__udelay); diff -urNp linux-2.4.37.7/arch/i386/kernel/i8259.c linux-2.4.37.7/arch/i386/kernel/i8259.c --- linux-2.4.37.7/arch/i386/kernel/i8259.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/i8259.c 2009-11-10 19:30:27.000000000 -0500 @@ -107,7 +107,8 @@ BUILD_SMP_INTERRUPT(spurious_interrupt,S IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f) -void (*interrupt[NR_IRQS])(void) = { +typedef void (*interrupt_t)(void); +const interrupt_t interrupt[NR_IRQS] = { IRQLIST_16(0x0), #ifdef CONFIG_X86_IO_APIC diff -urNp linux-2.4.37.7/arch/i386/kernel/init_task.c linux-2.4.37.7/arch/i386/kernel/init_task.c --- linux-2.4.37.7/arch/i386/kernel/init_task.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/init_task.c 2009-11-10 19:30:27.000000000 -0500 @@ -29,5 +29,9 @@ union task_union init_task_union * section. Since TSS's are completely CPU-local, we want them * on exact cacheline boundaries, to eliminate cacheline ping-pong. */ -struct tss_struct init_tss[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = INIT_TSS }; +#ifdef CONFIG_PAX_KERNEXEC +struct tss_struct init_tss[NR_CPUS] __attribute__((__aligned__(SMP_CACHE_BYTES), __section__(".rodata"))) = { [0 ... NR_CPUS-1] = INIT_TSS }; +#else +struct tss_struct init_tss[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1] = INIT_TSS }; +#endif diff -urNp linux-2.4.37.7/arch/i386/kernel/io_apic.c linux-2.4.37.7/arch/i386/kernel/io_apic.c --- linux-2.4.37.7/arch/i386/kernel/io_apic.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/io_apic.c 2009-11-10 19:30:27.000000000 -0500 @@ -620,7 +620,8 @@ next: return current_vector; } -extern void (*interrupt[NR_IRQS])(void); +typedef void (*interrupt_t)(void); +extern const interrupt_t interrupt[NR_IRQS]; static struct hw_interrupt_type ioapic_level_irq_type; static struct hw_interrupt_type ioapic_edge_irq_type; diff -urNp linux-2.4.37.7/arch/i386/kernel/ioport.c linux-2.4.37.7/arch/i386/kernel/ioport.c --- linux-2.4.37.7/arch/i386/kernel/ioport.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/ioport.c 2009-11-10 19:30:27.000000000 -0500 @@ -14,6 +14,8 @@ #include #include #include +#include +#include /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ static void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value) @@ -57,10 +59,22 @@ asmlinkage int sys_ioperm(unsigned long struct thread_struct * t = ¤t->thread; struct tss_struct * tss = init_tss + smp_processor_id(); +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; +#endif + if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32)) return -EINVAL; +#ifdef CONFIG_GRKERNSEC_IO + if (turn_on) { + gr_handle_ioperm(); +#else if (turn_on && !capable(CAP_SYS_RAWIO)) +#endif return -EPERM; +#ifdef CONFIG_GRKERNSEC_IO + } +#endif /* * If it's the first ioperm() call in this thread's lifetime, set the * IO bitmap up. ioperm() is much less timing critical than clone(), @@ -78,6 +92,11 @@ asmlinkage int sys_ioperm(unsigned long * do it in the per-thread copy and in the TSS ... */ set_bitmap(t->io_bitmap, from, num, !turn_on); + +#ifdef CONFIG_PAX_KERNEXEC + pax_open_kernel(cr0); +#endif + if (tss->bitmap == IO_BITMAP_OFFSET) { /* already active? */ set_bitmap(tss->io_bitmap, from, num, !turn_on); } else { @@ -85,6 +104,10 @@ asmlinkage int sys_ioperm(unsigned long tss->bitmap = IO_BITMAP_OFFSET; /* Activate it in the TSS */ } +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + return 0; } @@ -109,8 +132,13 @@ asmlinkage int sys_iopl(unsigned long un return -EINVAL; /* Trying to gain more privileges? */ if (level > old) { +#ifdef CONFIG_GRKERNSEC_IO + gr_handle_iopl(); + return -EPERM; +#else if (!capable(CAP_SYS_RAWIO)) return -EPERM; +#endif } regs->eflags = (regs->eflags & 0xffffcfff) | (level << 12); return 0; diff -urNp linux-2.4.37.7/arch/i386/kernel/ldt.c linux-2.4.37.7/arch/i386/kernel/ldt.c --- linux-2.4.37.7/arch/i386/kernel/ldt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/ldt.c 2009-11-10 19:30:27.000000000 -0500 @@ -151,7 +151,7 @@ static int read_default_ldt(void * ptr, { int err; unsigned long size; - void *address; + const void *address; err = 0; address = &default_ldt[0]; @@ -214,6 +214,13 @@ static int write_ldt(void * ptr, unsigne } } +#ifdef CONFIG_PAX_SEGMEXEC + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && (ldt_info.contents & 2)) { + error = -EINVAL; + goto out_unlock; + } +#endif + entry_1 = ((ldt_info.base_addr & 0x0000ffff) << 16) | (ldt_info.limit & 0x0ffff); entry_2 = (ldt_info.base_addr & 0xff000000) | @@ -224,7 +231,7 @@ static int write_ldt(void * ptr, unsigne ((ldt_info.seg_not_present ^ 1) << 15) | (ldt_info.seg_32bit << 22) | (ldt_info.limit_in_pages << 23) | - 0x7000; + 0x7100; if (!oldmode) entry_2 |= (ldt_info.useable << 20); diff -urNp linux-2.4.37.7/arch/i386/kernel/microcode.c linux-2.4.37.7/arch/i386/kernel/microcode.c --- linux-2.4.37.7/arch/i386/kernel/microcode.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/microcode.c 2009-11-10 19:30:27.000000000 -0500 @@ -474,7 +474,7 @@ static int microcode_ioctl (struct inode } /* shared between misc device and devfs regular file */ -static struct file_operations microcode_fops = { +static const struct file_operations microcode_fops = { .owner = THIS_MODULE, .write = microcode_write, .ioctl = microcode_ioctl, diff -urNp linux-2.4.37.7/arch/i386/kernel/mpparse.c linux-2.4.37.7/arch/i386/kernel/mpparse.c --- linux-2.4.37.7/arch/i386/kernel/mpparse.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/mpparse.c 2009-11-10 19:30:27.000000000 -0500 @@ -833,7 +833,7 @@ void __init get_smp_config (void) * Read the physical hardware table. Anything here will * override the defaults. */ - if (!smp_read_mpc((void *)mpf->mpf_physptr)) { + if (!smp_read_mpc(phys_to_virt(mpf->mpf_physptr))) { smp_found_config = 0; printk(KERN_ERR "BIOS bug, MP table errors detected!...\n"); printk(KERN_ERR "... disabling SMP support. (tell your hw vendor)\n"); diff -urNp linux-2.4.37.7/arch/i386/kernel/msr.c linux-2.4.37.7/arch/i386/kernel/msr.c --- linux-2.4.37.7/arch/i386/kernel/msr.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/msr.c 2009-11-10 19:30:27.000000000 -0500 @@ -240,7 +240,7 @@ static int msr_open(struct inode *inode, /* * File operations we support */ -static struct file_operations msr_fops = { +static const struct file_operations msr_fops = { owner: THIS_MODULE, llseek: msr_seek, read: msr_read, diff -urNp linux-2.4.37.7/arch/i386/kernel/mtrr.c linux-2.4.37.7/arch/i386/kernel/mtrr.c --- linux-2.4.37.7/arch/i386/kernel/mtrr.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/mtrr.c 2009-11-10 19:30:27.000000000 -0500 @@ -1675,7 +1675,7 @@ static ssize_t mtrr_write (struct file * char line[LINE_SIZE]; if (!len) return -EINVAL; - if ( !suser () ) return -EPERM; + if ( !capable(CAP_SYS_ADMIN) ) return -EPERM; /* Can't seek (pwrite) on this device */ if (ppos != &file->f_pos) return -ESPIPE; memset (line, 0, LINE_SIZE); diff -urNp linux-2.4.37.7/arch/i386/kernel/pci-pc.c linux-2.4.37.7/arch/i386/kernel/pci-pc.c --- linux-2.4.37.7/arch/i386/kernel/pci-pc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/pci-pc.c 2009-11-10 19:30:27.000000000 -0500 @@ -17,6 +17,7 @@ #include #include #include +#include #include "pci-i386.h" @@ -575,11 +576,10 @@ union bios32 { * we'll make pcibios_present() take a memory start parameter and store * the array there. */ - static struct { unsigned long address; unsigned short segment; -} bios32_indirect = { 0, __KERNEL_CS }; +} bios32_indirect = { 0, __PCIBIOS_CS }; /* * Returns the entry point for the given service, NULL on error @@ -593,34 +593,122 @@ static unsigned long bios32_service(unsi unsigned long entry; /* %edx */ unsigned long flags; +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; +#endif + __save_flags(flags); __cli(); - __asm__("lcall (%%edi); cld" + +#ifdef CONFIG_PAX_KERNEXEC + pax_open_kernel(cr0); +#endif + + gdt_table[6].a = 0x0000FFFFUL; + gdt_table[6].b = 0x00CF9B00UL; + gdt_table[7].a = 0x0000FFFFUL; + gdt_table[7].b = 0x00CF9300UL; + +#ifdef CONFIG_PAX_SEGMEXEC + gdt_table2[6].a = 0x0000FFFFUL; + gdt_table2[6].b = 0x00CF9B00UL; + gdt_table2[7].a = 0x0000FFFFUL; + gdt_table2[7].b = 0x00CF9300UL; +#endif + +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + + __asm__("movw %w7, %%ds; lcall *(%%edi); push %%ss; pop %%ds; cld" : "=a" (return_code), "=b" (address), "=c" (length), "=d" (entry) : "0" (service), "1" (0), - "D" (&bios32_indirect)); + "D" (&bios32_indirect), + "r" (__PCIBIOS_DS) + : "memory"); + +#ifdef CONFIG_PAX_KERNEXEC + pax_open_kernel(cr0); +#endif + + gdt_table[6].a = 0; + gdt_table[6].b = 0; + gdt_table[7].a = 0; + gdt_table[7].b = 0; + +#ifdef CONFIG_PAX_SEGMEXEC + gdt_table2[6].a = 0; + gdt_table2[6].b = 0; + gdt_table2[7].a = 0; + gdt_table2[7].b = 0; +#endif + +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + __restore_flags(flags); switch (return_code) { - case 0: - return address + entry; - case 0x80: /* Not present */ - printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service); - return 0; - default: /* Shouldn't happen */ - printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n", - service, return_code); + case 0: { + unsigned long a, b1, b2; + unsigned char flags; + + printk(KERN_INFO "bios32_service: base:%08lx length:%08lx entry:%08lx\n", address, length, entry); + if (address >= 0xFFFF0 || length >= 0xFFFF0 - address || length <= entry) { + printk(KERN_WARNING "bios32_service: not valid\n"); return 0; + } + address = address + PAGE_OFFSET; + length += 16UL; /* some BIOSs underreport this... */ + flags = 4; + if (length >= 64*1024*1024) { + length >>= PAGE_SHIFT; + flags |= 8; + } + a = (length & 0xFFFFUL) | ((address & 0xFFFFUL) << 16); + b1 = (address & 0xFF000000UL) | ((address & 0x00FF0000UL) >> 16) | (length & 0xF0000UL) | (flags << 20) | 0x9B00UL; + b2 = (address & 0xFF000000UL) | ((address & 0x00FF0000UL) >> 16) | (length & 0xF0000UL) | (flags << 20) | 0x9300UL; + +#ifdef CONFIG_PAX_KERNEXEC + pax_open_kernel(cr0); +#endif + + gdt_table[6].a = a; + gdt_table[6].b = b1; + gdt_table[7].a = a; + gdt_table[7].b = b2; + +#ifdef CONFIG_PAX_SEGMEXEC + gdt_table2[6].a = a; + gdt_table2[6].b = b1; + gdt_table2[7].a = a; + gdt_table2[7].b = b2; +#endif + +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + + return entry; + } + case 0x80: /* Not present */ + printk(KERN_WARNING "bios32_service(0x%lx): not present\n", service); + return 0; + default: /* Shouldn't happen */ + printk(KERN_WARNING "bios32_service(0x%lx): returned 0x%x -- BIOS bug!\n", + service, return_code); + return 0; } } static struct { unsigned long address; unsigned short segment; -} pci_indirect = { 0, __KERNEL_CS }; +} pci_indirect = { 0, __PCIBIOS_CS }; static int pci_bios_present; @@ -631,11 +719,13 @@ static int __devinit check_pcibios(void) unsigned long flags, pcibios_entry; if ((pcibios_entry = bios32_service(PCI_SERVICE))) { - pci_indirect.address = pcibios_entry + PAGE_OFFSET; + pci_indirect.address = pcibios_entry; __save_flags(flags); __cli(); - __asm__( - "lcall (%%edi); cld\n\t" + __asm__("movw %w6, %%ds\n\t" + "lcall *%%ss:(%%edi); cld\n\t" + "push %%ss\n\t" + "pop %%ds\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -644,7 +734,8 @@ static int __devinit check_pcibios(void) "=b" (ebx), "=c" (ecx) : "1" (PCIBIOS_PCI_BIOS_PRESENT), - "D" (&pci_indirect) + "D" (&pci_indirect), + "r" (__PCIBIOS_DS) : "memory"); __restore_flags(flags); @@ -680,7 +771,10 @@ static int __devinit pci_bios_find_devic unsigned short bx; unsigned short ret; - __asm__("lcall (%%edi); cld\n\t" + __asm__("movw %w7, %%ds\n\t" + "lcall *%%ss:(%%edi); cld\n\t" + "push %%ss\n\t" + "pop %%ds\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -690,7 +784,8 @@ static int __devinit pci_bios_find_devic "c" (device_id), "d" (vendor), "S" ((int) index), - "D" (&pci_indirect)); + "D" (&pci_indirect), + "r" (__PCIBIOS_DS)); *bus = (bx >> 8) & 0xff; *device_fn = bx & 0xff; return (int) (ret & 0xff00) >> 8; @@ -709,7 +804,10 @@ static int pci_bios_read (int seg, int b switch (len) { case 1: - __asm__("lcall (%%esi); cld\n\t" + __asm__("movw %w6, %%ds\n\t" + "lcall *%%ss:(%%esi); cld\n\t" + "push %%ss\n\t" + "pop %%ds\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -718,10 +816,14 @@ static int pci_bios_read (int seg, int b : "1" (PCIBIOS_READ_CONFIG_BYTE), "b" (bx), "D" ((long)reg), - "S" (&pci_indirect)); + "S" (&pci_indirect), + "r" (__PCIBIOS_DS)); break; case 2: - __asm__("lcall (%%esi); cld\n\t" + __asm__("movw %w6, %%ds\n\t" + "lcall *%%ss:(%%esi); cld\n\t" + "push %%ss\n\t" + "pop %%ds\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -730,10 +832,14 @@ static int pci_bios_read (int seg, int b : "1" (PCIBIOS_READ_CONFIG_WORD), "b" (bx), "D" ((long)reg), - "S" (&pci_indirect)); + "S" (&pci_indirect), + "r" (__PCIBIOS_DS)); break; case 4: - __asm__("lcall (%%esi); cld\n\t" + __asm__("movw %w6, %%ds\n\t" + "lcall *%%ss:(%%esi); cld\n\t" + "push %%ss\n\t" + "pop %%ds\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -742,7 +848,8 @@ static int pci_bios_read (int seg, int b : "1" (PCIBIOS_READ_CONFIG_DWORD), "b" (bx), "D" ((long)reg), - "S" (&pci_indirect)); + "S" (&pci_indirect), + "r" (__PCIBIOS_DS)); break; } @@ -764,7 +871,10 @@ static int pci_bios_write (int seg, int switch (len) { case 1: - __asm__("lcall (%%esi); cld\n\t" + __asm__("movw %w6, %%ds\n\t" + "lcall *%%ss:(%%esi); cld\n\t" + "push %%ss\n\t" + "pop %%ds\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -773,10 +883,14 @@ static int pci_bios_write (int seg, int "c" (value), "b" (bx), "D" ((long)reg), - "S" (&pci_indirect)); + "S" (&pci_indirect), + "r" (__PCIBIOS_DS)); break; case 2: - __asm__("lcall (%%esi); cld\n\t" + __asm__("movw %w6, %%ds\n\t" + "lcall *%%ss:(%%esi); cld\n\t" + "push %%ss\n\t" + "pop %%ds\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -785,10 +899,14 @@ static int pci_bios_write (int seg, int "c" (value), "b" (bx), "D" ((long)reg), - "S" (&pci_indirect)); + "S" (&pci_indirect), + "r" (__PCIBIOS_DS)); break; case 4: - __asm__("lcall (%%esi); cld\n\t" + __asm__("movw %w6, %%ds\n\t" + "lcall *%%ss:(%%esi); cld\n\t" + "push %%ss\n\t" + "pop %%ds\n\t" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -797,7 +915,8 @@ static int pci_bios_write (int seg, int "c" (value), "b" (bx), "D" ((long)reg), - "S" (&pci_indirect)); + "S" (&pci_indirect), + "r" (__PCIBIOS_DS)); break; } @@ -1009,10 +1128,13 @@ struct irq_routing_table * __devinit pci DBG("PCI: Fetching IRQ routing table... "); __asm__("push %%es\n\t" + "movw %w8, %%ds\n\t" "push %%ds\n\t" "pop %%es\n\t" - "lcall (%%esi); cld\n\t" + "lcall *%%ss:(%%esi); cld\n\t" "pop %%es\n\t" + "push %%ss\n\t" + "pop %%ds\n" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -1023,7 +1145,8 @@ struct irq_routing_table * __devinit pci "1" (0), "D" ((long) &opt), "S" (&pci_indirect), - "m" (opt) + "m" (opt), + "r" (__PCIBIOS_DS) : "memory"); DBG("OK ret=%d, size=%d, map=%x\n", ret, opt.size, map); if (ret & 0xff00) @@ -1047,7 +1170,10 @@ int pcibios_set_irq_routing(struct pci_d { int ret; - __asm__("lcall (%%esi); cld\n\t" + __asm__("movw %w5, %%ds\n\t" + "lcall *%%ss:(%%esi); cld\n\t" + "push %%ss\n\t" + "pop %%ds\n" "jc 1f\n\t" "xor %%ah, %%ah\n" "1:" @@ -1055,7 +1181,8 @@ int pcibios_set_irq_routing(struct pci_d : "0" (PCIBIOS_SET_PCI_HW_INT), "b" ((dev->bus->number << 8) | dev->devfn), "c" ((irq << 8) | (pin + 10)), - "S" (&pci_indirect)); + "S" (&pci_indirect), + "r" (__PCIBIOS_DS)); return !(ret & 0xff00); } diff -urNp linux-2.4.37.7/arch/i386/kernel/process.c linux-2.4.37.7/arch/i386/kernel/process.c --- linux-2.4.37.7/arch/i386/kernel/process.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/process.c 2009-11-10 19:30:27.000000000 -0500 @@ -153,7 +153,7 @@ static int __init idle_setup (char *str) __setup("idle=", idle_setup); -static int reboot_mode; +static unsigned short reboot_mode; int reboot_thru_bios; #ifdef CONFIG_SMP @@ -209,18 +209,18 @@ __setup("reboot=", reboot_setup); doesn't work with at least one type of 486 motherboard. It is easy to stop this code working; hence the copious comments. */ -static unsigned long long +static const unsigned long long real_mode_gdt_entries [3] = { 0x0000000000000000ULL, /* Null descriptor */ - 0x00009a000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */ - 0x000092000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ + 0x00009b000000ffffULL, /* 16-bit real-mode 64k code at 0x00000000 */ + 0x000093000100ffffULL /* 16-bit real-mode 64k data at 0x00000100 */ }; -static struct +static const struct { unsigned short size __attribute__ ((packed)); - unsigned long long * base __attribute__ ((packed)); + const unsigned long long * base __attribute__ ((packed)); } real_mode_gdt = { sizeof (real_mode_gdt_entries) - 1, real_mode_gdt_entries }, real_mode_idt = { 0x3ff, 0 }, @@ -245,7 +245,7 @@ no_idt = { 0, 0 }; More could be done here to set up the registers as if a CPU reset had occurred; hopefully real BIOSs don't assume much. */ -static unsigned char real_mode_switch [] = +static const unsigned char real_mode_switch [] = { 0x66, 0x0f, 0x20, 0xc0, /* movl %cr0,%eax */ 0x66, 0x83, 0xe0, 0x11, /* andl $0x00000011,%eax */ @@ -259,7 +259,7 @@ static unsigned char real_mode_switch [] 0x24, 0x10, /* f: andb $0x10,al */ 0x66, 0x0f, 0x22, 0xc0 /* movl %eax,%cr0 */ }; -static unsigned char jump_to_bios [] = +static const unsigned char jump_to_bios [] = { 0xea, 0x00, 0x00, 0xff, 0xff /* ljmp $0xffff,$0x0000 */ }; @@ -278,10 +278,14 @@ static inline void kb_wait(void) * specified by the code and length parameters. * We assume that length will aways be less that 100! */ -void machine_real_restart(unsigned char *code, int length) +void machine_real_restart(const unsigned char *code, unsigned int length) { unsigned long flags; +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; +#endif + cli(); /* Write zero to CMOS register number 0x0f, which the BIOS POST @@ -302,9 +306,17 @@ void machine_real_restart(unsigned char from the kernel segment. This assumes the kernel segment starts at virtual address PAGE_OFFSET. */ +#ifdef CONFIG_PAX_KERNEXEC + pax_open_kernel(cr0); +#endif + memcpy (swapper_pg_dir, swapper_pg_dir + USER_PGD_PTRS, sizeof (swapper_pg_dir [0]) * KERNEL_PGD_PTRS); +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + /* Make sure the first page is mapped to the start of physical memory. It is normally not mapped, to trap kernel NULL pointer dereferences. */ @@ -321,7 +333,7 @@ void machine_real_restart(unsigned char REBOOT.COM programs, and the previous reset routine did this too. */ - *((unsigned short *)0x472) = reboot_mode; + __put_user(reboot_mode, (unsigned short *)0x472); /* For the switch to real mode, copy some code to low memory. It has to be in the first 64k because it is running in 16-bit mode, and it @@ -329,9 +341,9 @@ void machine_real_restart(unsigned char off paging. Copy it near the end of the first page, out of the way of BIOS variables. */ - memcpy ((void *) (0x1000 - sizeof (real_mode_switch) - 100), + __copy_to_user ((void *) (0x1000 - sizeof (real_mode_switch) - 100), real_mode_switch, sizeof (real_mode_switch)); - memcpy ((void *) (0x1000 - 100), code, length); + __copy_to_user ((void *) (0x1000 - 100), code, length); /* Set up the IDT for real mode. */ @@ -414,7 +426,7 @@ void machine_restart(char * __unused) if(!reboot_thru_bios) { /* rebooting needs to touch the page at absolute addr 0 */ - *((unsigned short *)__va(0x472)) = reboot_mode; + __put_user(reboot_mode, (unsigned short *)0x472); for (;;) { int i; for (i=0; i<100; i++) { @@ -552,7 +564,7 @@ int copy_thread(int nr, unsigned long cl { struct pt_regs * childregs; - childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1; + childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p - sizeof(unsigned long))) - 1; struct_cpy(childregs, regs); childregs->eax = 0; childregs->esp = esp; @@ -613,6 +625,19 @@ void dump_thread(struct pt_regs * regs, dump->u_fpvalid = dump_fpu (regs, &dump->i387); } +#ifdef CONFIG_PAX_SEGMEXEC +void pax_switch_segments(struct task_struct * tsk) +{ + if (!tsk->mm) + return; + + if (tsk->mm->pax_flags & MF_PAX_SEGMEXEC) + __asm__ __volatile__("lgdt %0": "=m" (gdt_descr2)); + else + __asm__ __volatile__("lgdt %0": "=m" (gdt_descr)); +} +#endif + /* * This special macro can be used to load a debugging register */ @@ -650,12 +675,15 @@ void fastcall __switch_to(struct task_st *next = &next_p->thread; struct tss_struct *tss = init_tss + smp_processor_id(); +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; +#endif + unlazy_fpu(prev_p); - /* - * Reload esp0, LDT and the page table pointer: - */ - tss->esp0 = next->esp0; +#ifdef CONFIG_PAX_SEGMEXEC + pax_switch_segments(next_p); +#endif /* * Save away %fs and %gs. No need to save %es and %ds, as @@ -683,6 +711,15 @@ void fastcall __switch_to(struct task_st loaddebug(next, 7); } +#ifdef CONFIG_PAX_KERNEXEC + pax_open_kernel(cr0); +#endif + + /* + * Reload esp0, LDT and the page table pointer: + */ + tss->esp0 = next->esp0; + if (prev->ioperm || next->ioperm) { if (next->ioperm) { /* @@ -705,6 +742,11 @@ void fastcall __switch_to(struct task_st */ tss->bitmap = INVALID_IO_BITMAP_OFFSET; } + +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + } asmlinkage int sys_fork(struct pt_regs regs) @@ -792,3 +834,44 @@ unsigned long get_wchan(struct task_stru } #undef last_sched #undef first_sched + +#ifdef CONFIG_PAX_RANDKSTACK +asmlinkage void pax_randomize_kstack(void) +{ + struct tss_struct *tss; + unsigned long time; + +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; +#endif + +#ifdef CONFIG_PAX_SOFTMODE + if (!pax_aslr) + return; +#endif + + tss = init_tss + smp_processor_id(); + rdtscl(time); + + /* P4 seems to return a 0 LSB, ignore it */ +#ifdef CONFIG_MPENTIUM4 + time &= 0x1EUL; + time <<= 2; +#else + time &= 0xFUL; + time <<= 3; +#endif + +#ifdef CONFIG_PAX_KERNEXEC + pax_open_kernel(cr0); +#endif + + tss->esp0 ^= time; + current->thread.esp0 = tss->esp0; + +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + +} +#endif diff -urNp linux-2.4.37.7/arch/i386/kernel/ptrace.c linux-2.4.37.7/arch/i386/kernel/ptrace.c --- linux-2.4.37.7/arch/i386/kernel/ptrace.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/ptrace.c 2009-11-10 19:30:27.000000000 -0500 @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -177,6 +178,9 @@ asmlinkage int sys_ptrace(long request, if (pid == 1) /* you may not mess with init */ goto out_tsk; + if(gr_handle_ptrace(child, request)) + goto out_tsk; + if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); goto out_tsk; @@ -256,6 +260,17 @@ asmlinkage int sys_ptrace(long request, if(addr < (long) &dummy->u_debugreg[4] && ((unsigned long) data) >= TASK_SIZE-3) break; +#ifdef CONFIG_GRKERNSEC + if(addr >= (long) &dummy->u_debugreg[0] && + addr <= (long) &dummy->u_debugreg[3]){ + long reg = (addr - (long) &dummy->u_debugreg[0]) >> 2; + long type = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 4*reg)) & 3; + long align = (child->thread.debugreg[7] >> (DR_CONTROL_SHIFT + 2 + 4*reg)) & 3; + if((type & 1) && (data & align)) + break; + } +#endif + if(addr == (long) &dummy->u_debugreg[7]) { data &= ~DR_CONTROL_RESERVED; for(i=0; i<4; i++) diff -urNp linux-2.4.37.7/arch/i386/kernel/setup.c linux-2.4.37.7/arch/i386/kernel/setup.c --- linux-2.4.37.7/arch/i386/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -129,7 +129,11 @@ char ignore_irq13; /* set if exception 16 works */ struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 }; +#ifdef CONFIG_X86_PAE +unsigned long mmu_cr4_features = X86_CR4_PAE; +#else unsigned long mmu_cr4_features; +#endif EXPORT_SYMBOL(mmu_cr4_features); /* @@ -170,7 +174,7 @@ unsigned char aux_device_present; extern void mcheck_init(struct cpuinfo_x86 *c); extern void dmi_scan_machine(void); extern int root_mountflags; -extern char _text, _etext, _edata, _end; +extern char _text, _etext, _data, _edata, _end; static int have_cpuid_p(void) __init; @@ -1209,14 +1213,14 @@ void __init setup_arch(char **cmdline_p) if (!MOUNT_ROOT_RDONLY) root_mountflags &= ~MS_RDONLY; - init_mm.start_code = (unsigned long) &_text; - init_mm.end_code = (unsigned long) &_etext; + init_mm.start_code = (unsigned long) &_text + __KERNEL_TEXT_OFFSET; + init_mm.end_code = (unsigned long) &_etext + __KERNEL_TEXT_OFFSET; init_mm.end_data = (unsigned long) &_edata; init_mm.brk = (unsigned long) &_end; - code_resource.start = virt_to_bus(&_text); - code_resource.end = virt_to_bus(&_etext)-1; - data_resource.start = virt_to_bus(&_etext); + code_resource.start = virt_to_bus(&_text + __KERNEL_TEXT_OFFSET); + code_resource.end = virt_to_bus(&_etext + __KERNEL_TEXT_OFFSET)-1; + data_resource.start = virt_to_bus(&_data); data_resource.end = virt_to_bus(&_edata)-1; parse_cmdline_early(cmdline_p); @@ -3164,7 +3168,7 @@ static void *c_next(struct seq_file *m, static void c_stop(struct seq_file *m, void *v) { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { start: c_start, next: c_next, stop: c_stop, @@ -3184,6 +3188,10 @@ void __init cpu_init (void) int nr = smp_processor_id(); struct tss_struct * t = &init_tss[nr]; +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; +#endif + if (test_and_set_bit(nr, &cpu_initialized)) { printk(KERN_WARNING "CPU#%d already initialized!\n", nr); for (;;) __sti(); @@ -3218,10 +3226,19 @@ void __init cpu_init (void) BUG(); enter_lazy_tlb(&init_mm, current, nr); - t->esp0 = current->thread.esp0; set_tss_desc(nr,t); - gdt_table[__TSS(nr)].b &= 0xfffffdff; + +#ifdef CONFIG_PAX_KERNEXEC + pax_open_kernel(cr0); +#endif + + t->esp0 = current->thread.esp0; load_TR(nr); + +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + load_LDT(&init_mm.context); /* @@ -3288,7 +3305,53 @@ int __init ppro_with_ram_bug(void) printk(KERN_INFO "Your Pentium Pro seems ok.\n"); return 0; } - + +static int current_ypos = 25, current_xpos; +#define VGABASE (0xb8000) +#define VGAXY(x, y) (VGABASE + 2 * (x + y * SCREEN_INFO.orig_video_cols)) + +static void early_vga_write(const char *str, int n) +{ + char c; + int i, k, j; + + while ((c = *str++) != '\0' && n-- > 0) { + if (current_ypos >= SCREEN_INFO.orig_video_lines) { + /* scroll 1 line up */ + for (k = 1, j = 0; k < SCREEN_INFO.orig_video_lines; k++, j++) { + for (i = 0; i < SCREEN_INFO.orig_video_cols; i++) { + isa_writew(isa_readw(VGAXY(i, k)), VGAXY(i, j)); + } + } + for (i = 0; i < SCREEN_INFO.orig_video_cols; i++) + isa_writew(0x720, VGAXY(i, j)); + current_ypos = SCREEN_INFO.orig_video_lines-1; + } + if (c == '\n') { + current_xpos = 0; + current_ypos++; + } else if (c != '\r') { + isa_writew((0x700 | (unsigned short) c), VGAXY(current_xpos, current_ypos)); + if (++current_xpos >= SCREEN_INFO.orig_video_cols) { + current_xpos = 0; + current_ypos++; + } + } + } +} + +asmlinkage void __init early_printk(const char *fmt, ...) +{ + char buf[512]; + int n; + va_list ap; + + va_start(ap, fmt); + n = vsnprintf(buf, 512, fmt, ap); + early_vga_write(buf, n); + va_end(ap); +} + /* * Local Variables: * mode:c diff -urNp linux-2.4.37.7/arch/i386/kernel/sys_i386.c linux-2.4.37.7/arch/i386/kernel/sys_i386.c --- linux-2.4.37.7/arch/i386/kernel/sys_i386.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/sys_i386.c 2009-11-10 19:30:27.000000000 -0500 @@ -48,6 +48,11 @@ static inline long do_mmap2( int error = -EBADF; struct file * file = NULL; +#ifdef CONFIG_PAX_SEGMEXEC + if (flags & MAP_MIRROR) + return -EINVAL; +#endif + flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); if (!(flags & MAP_ANONYMOUS)) { file = fget(fd); diff -urNp linux-2.4.37.7/arch/i386/kernel/trampoline.S linux-2.4.37.7/arch/i386/kernel/trampoline.S --- linux-2.4.37.7/arch/i386/kernel/trampoline.S 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/trampoline.S 2009-11-10 19:30:27.000000000 -0500 @@ -54,7 +54,7 @@ r_base = . lmsw %ax # into protected mode jmp flush_instr flush_instr: - ljmpl $__KERNEL_CS, $0x00100000 + ljmpl $__KERNEL_CS, $SYMBOL_NAME(startup_32) + __KERNEL_TEXT_OFFSET - __PAGE_OFFSET # jump to startup_32 in arch/i386/kernel/head.S idt_48: @@ -62,8 +62,8 @@ idt_48: .word 0, 0 # idt base = 0L gdt_48: - .word 0x0800 # gdt limit = 2048, 256 GDT entries - .long gdt_table-__PAGE_OFFSET # gdt base = gdt (first SMP CPU) + .word __KERNEL_DS+7 # gdt limit = just the minimum + .long boot_gdt_table-__PAGE_OFFSET # gdt base = boot_gdt (first SMP CPU) .globl SYMBOL_NAME(trampoline_end) SYMBOL_NAME_LABEL(trampoline_end) diff -urNp linux-2.4.37.7/arch/i386/kernel/traps.c linux-2.4.37.7/arch/i386/kernel/traps.c --- linux-2.4.37.7/arch/i386/kernel/traps.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/traps.c 2009-11-10 19:30:27.000000000 -0500 @@ -54,15 +54,10 @@ asmlinkage int system_call(void); asmlinkage void lcall7(void); asmlinkage void lcall27(void); -struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, +const struct desc_struct default_ldt[] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; -/* - * The IDT has to be page-aligned to simplify the Pentium - * F0 0F bug workaround.. We have a special link segment - * for this. - */ -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, }; +extern struct desc_struct idt_table[256]; asmlinkage void divide_error(void); asmlinkage void debug(void); @@ -87,6 +82,7 @@ asmlinkage void machine_check(void); int kstack_depth_to_print = 24; +extern char _text, _sinittext, _einittext; /* * If the address is either in the .text section of the @@ -104,6 +100,10 @@ static inline int kernel_text_address(un int retval = 0; struct module *mod; + if (addr >= (unsigned long) &_sinittext && + addr <= (unsigned long) &_einittext) + return 1; + if (addr >= (unsigned long) &_stext && addr <= (unsigned long) &_etext) return 1; @@ -125,8 +125,15 @@ static inline int kernel_text_address(un static inline int kernel_text_address(unsigned long addr) { - return (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext); + if (addr >= (unsigned long) &_sinittext && + addr <= (unsigned long) &_einittext) + return 1; + + if (addr >= (unsigned long) &_stext && + addr <= (unsigned long) &_etext) + return 1; + + return 0; } #endif @@ -228,13 +235,13 @@ void show_registers(struct pt_regs *regs show_stack((unsigned long*)esp); printk("\nCode: "); - if(regs->eip < PAGE_OFFSET) + if(regs->eip + __KERNEL_TEXT_OFFSET < PAGE_OFFSET) goto bad; for(i=0;i<20;i++) { unsigned char c; - if(__get_user(c, &((unsigned char*)regs->eip)[i])) { + if(__get_user(c, &((unsigned char*)regs->eip)[i+__KERNEL_TEXT_OFFSET])) { bad: printk(" Bad EIP value."); break; @@ -256,7 +263,7 @@ static void handle_BUG(struct pt_regs *r if (regs->xcs & 3) goto no_bug; /* Not in kernel */ - eip = regs->eip; + eip = regs->eip + __KERNEL_TEXT_OFFSET; if (eip < PAGE_OFFSET) goto no_bug; @@ -264,10 +271,11 @@ static void handle_BUG(struct pt_regs *r goto no_bug; if (ud2 != 0x0b0f) goto no_bug; - if (__get_user(line, (unsigned short *)(eip + 2))) + if (__get_user(line, (unsigned short *)(eip + 7))) goto bug; - if (__get_user(file, (char **)(eip + 4)) || - (unsigned long)file < PAGE_OFFSET || __get_user(c, file)) + if (__get_user(file, (char **)(eip + 3)) || file < &_text + __KERNEL_TEXT_OFFSET) + goto bug; + if (__get_user(c, file)) file = ""; printk("kernel BUG at %s:%d!\n", file, line); @@ -422,6 +430,13 @@ gp_in_kernel: regs->eip = fixup; return; } + +#ifdef CONFIG_PAX_KERNEXEC + if ((regs->xcs & 0xFFFF) == __KERNEL_CS) + die("PAX: suspicious general protection fault", regs, error_code); + else +#endif + die("general protection fault", regs, error_code); } } @@ -527,13 +542,12 @@ asmlinkage void do_debug(struct pt_regs { unsigned int condition; struct task_struct *tsk = current; - unsigned long eip = regs->eip; siginfo_t info; __asm__ __volatile__("movl %%db6,%0" : "=r" (condition)); /* If the user set TF, it's simplest to clear it right away. */ - if ((eip >=PAGE_OFFSET) && (regs->eflags & TF_MASK)) + if (!(regs->xcs & 3) && (regs->eflags & TF_MASK) && !(regs->eflags & VM_MASK)) goto clear_TF; /* Mask out spurious debug traps due to lazy DR7 setting */ @@ -778,6 +792,8 @@ asmlinkage void math_emulate(long arg) #ifndef CONFIG_X86_F00F_WORKS_OK void __init trap_init_f00f_bug(void) { + +#ifndef CONFIG_PAX_KERNEXEC /* * "idt" is magic - it overlaps the idt_descr * variable so that updating idt will automatically @@ -787,12 +803,17 @@ void __init trap_init_f00f_bug(void) idt = (struct desc_struct *)__fix_to_virt(FIX_F00F); __asm__ __volatile__("lidt %0": "=m" (idt_descr)); +#endif + } #endif +#ifdef CONFIG_PAX_KERNEXEC #define _set_gate(gate_addr,type,dpl,addr) \ do { \ int __d0, __d1; \ + unsigned long cr0; \ + pax_open_kernel(cr0); \ __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ "movw %4,%%dx\n\t" \ "movl %%eax,%0\n\t" \ @@ -801,8 +822,22 @@ do { \ "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \ :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ "3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \ + pax_close_kernel(cr0); \ } while (0) - +#else +#define _set_gate(gate_addr,type,dpl,addr) \ +do { \ + int __d0, __d1; \ + __asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ + "movw %4,%%dx\n\t" \ + "movl %%eax,%0\n\t" \ + "movl %%edx,%1" \ + :"=m" (*((long *) (gate_addr))), \ + "=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \ + :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ + "3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \ +} while (0) +#endif /* * This needs to use 'idt_table' rather than 'idt', and @@ -810,26 +845,42 @@ do { \ * Pentium F0 0F bugfix can have resulted in the mapped * IDT being write-protected. */ -void set_intr_gate(unsigned int n, void *addr) +void set_intr_gate(unsigned int n, const void *addr) { _set_gate(idt_table+n,14,0,addr); } -static void __init set_trap_gate(unsigned int n, void *addr) +static void __init set_trap_gate(unsigned int n, const void *addr) { _set_gate(idt_table+n,15,0,addr); } -static void __init set_system_gate(unsigned int n, void *addr) +static void __init set_system_gate(unsigned int n, const void *addr) { _set_gate(idt_table+n,15,3,addr); } -static void __init set_call_gate(void *a, void *addr) +static void __init set_call_gate(const void *a, const void *addr) { _set_gate(a,12,3,addr); } +#ifdef CONFIG_PAX_KERNEXEC +#define _set_seg_desc(gate_addr,type,dpl,base,limit) \ +do {\ + unsigned long cr0; \ + pax_open_kernel(cr0); \ + *((gate_addr)+1) = ((base) & 0xff000000) | \ + (((base) & 0x00ff0000)>>16) | \ + ((limit) & 0xf0000) | \ + ((dpl)<<13) | \ + (0x00408000) | \ + ((type)<<8); \ + *(gate_addr) = (((base) & 0x0000ffff)<<16) | \ + ((limit) & 0x0ffff); \ + pax_close_kernel(cr0); \ +} while (0) +#else #define _set_seg_desc(gate_addr,type,dpl,base,limit) {\ *((gate_addr)+1) = ((base) & 0xff000000) | \ (((base) & 0x00ff0000)>>16) | \ @@ -839,7 +890,25 @@ static void __init set_call_gate(void *a ((type)<<8); \ *(gate_addr) = (((base) & 0x0000ffff)<<16) | \ ((limit) & 0x0ffff); } +#endif +#ifdef CONFIG_PAX_KERNEXEC +#define _set_tssldt_desc(n,addr,limit,type) \ +do { \ + unsigned long cr0; \ + pax_open_kernel(cr0); \ + __asm__ __volatile__ ("movw %w3,0(%2)\n\t" \ + "movw %%ax,2(%2)\n\t" \ + "rorl $16,%%eax\n\t" \ + "movb %%al,4(%2)\n\t" \ + "movb %4,5(%2)\n\t" \ + "movb $0,6(%2)\n\t" \ + "movb %%ah,7(%2)\n\t" \ + "rorl $16,%%eax" \ + : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type)); \ + pax_close_kernel(cr0); \ +} while (0) +#else #define _set_tssldt_desc(n,addr,limit,type) \ __asm__ __volatile__ ("movw %w3,0(%2)\n\t" \ "movw %%ax,2(%2)\n\t" \ @@ -850,15 +919,26 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\ "movb %%ah,7(%2)\n\t" \ "rorl $16,%%eax" \ : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type)) +#endif -void set_tss_desc(unsigned int n, void *addr) +void set_tss_desc(unsigned int n, const void *addr) { _set_tssldt_desc(gdt_table+__TSS(n), (int)addr, 235, 0x89); + +#ifdef CONFIG_PAX_SEGMEXEC + _set_tssldt_desc(gdt_table2+__TSS(n), (int)addr, 235, 0x89); +#endif + } -void set_ldt_desc(unsigned int n, void *addr, unsigned int size) +void set_ldt_desc(unsigned int n, const void *addr, unsigned int size) { _set_tssldt_desc(gdt_table+__LDT(n), (int)addr, ((size << 3)-1), 0x82); + +#ifdef CONFIG_PAX_SEGMEXEC + _set_tssldt_desc(gdt_table2+__LDT(n), (int)addr, ((size << 3)-1), 0x82); +#endif + } #ifdef CONFIG_X86_VISWS_APIC diff -urNp linux-2.4.37.7/arch/i386/kernel/vm86.c linux-2.4.37.7/arch/i386/kernel/vm86.c --- linux-2.4.37.7/arch/i386/kernel/vm86.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/kernel/vm86.c 2009-11-10 19:30:27.000000000 -0500 @@ -44,6 +44,7 @@ #include #include #include +#include /* * Known problems: @@ -97,6 +98,10 @@ struct pt_regs * fastcall save_v86_state struct pt_regs *ret; unsigned long tmp; +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; +#endif + if (!current->thread.vm86_info) { printk("no vm86_info: BAD\n"); do_exit(SIGSEGV); @@ -111,7 +116,17 @@ struct pt_regs * fastcall save_v86_state do_exit(SIGSEGV); } tss = init_tss + smp_processor_id(); + +#ifdef CONFIG_PAX_KERNEXEC + pax_open_kernel(cr0); +#endif + tss->esp0 = current->thread.esp0 = current->thread.saved_esp0; + +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + current->thread.saved_esp0 = 0; ret = KVM86->regs32; return ret; @@ -237,6 +252,11 @@ out: static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk) { struct tss_struct *tss; + +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr3; +#endif + /* * make sure the vm86() system call doesn't try to do anything silly */ @@ -278,8 +298,17 @@ static void do_sys_vm86(struct kernel_vm info->regs32->eax = 0; tsk->thread.saved_esp0 = tsk->thread.esp0; tss = init_tss + smp_processor_id(); + +#ifdef CONFIG_PAX_KERNEXEC + pax_open_kernel(cr3); +#endif + tss->esp0 = tsk->thread.esp0 = (unsigned long) &info->VM86_TSS_ESP0; +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr3); +#endif + tsk->thread.screen_bitmap = info->screen_bitmap; if (info->flags & VM86_SCREEN_BITMAP) mark_screen_rdonly(tsk); diff -urNp linux-2.4.37.7/arch/i386/lib/checksum.S linux-2.4.37.7/arch/i386/lib/checksum.S --- linux-2.4.37.7/arch/i386/lib/checksum.S 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/lib/checksum.S 2009-11-10 19:30:27.000000000 -0500 @@ -27,7 +27,8 @@ #include #include - +#include + /* * computes a partial checksum, e.g. for TCP/UDP fragments */ @@ -281,12 +282,23 @@ unsigned int csum_partial_copy_generic ( .align 4 .globl csum_partial_copy_generic - +.globl csum_partial_copy_generic_to_user +.globl csum_partial_copy_generic_from_user + #ifndef CONFIG_X86_USE_PPRO_CHECKSUM #define ARGBASE 16 #define FP 12 - + +csum_partial_copy_generic_to_user: + pushl $(__USER_DS) + popl %es + jmp csum_partial_copy_generic + +csum_partial_copy_generic_from_user: + pushl $(__USER_DS) + popl %ds + csum_partial_copy_generic: subl $4,%esp pushl %edi @@ -305,7 +317,7 @@ csum_partial_copy_generic: jmp 4f SRC(1: movw (%esi), %bx ) addl $2, %esi -DST( movw %bx, (%edi) ) +DST( movw %bx, %es:(%edi) ) addl $2, %edi addw %bx, %ax adcl $0, %eax @@ -317,30 +329,30 @@ DST( movw %bx, (%edi) ) SRC(1: movl (%esi), %ebx ) SRC( movl 4(%esi), %edx ) adcl %ebx, %eax -DST( movl %ebx, (%edi) ) +DST( movl %ebx, %es:(%edi) ) adcl %edx, %eax -DST( movl %edx, 4(%edi) ) +DST( movl %edx, %es:4(%edi) ) SRC( movl 8(%esi), %ebx ) SRC( movl 12(%esi), %edx ) adcl %ebx, %eax -DST( movl %ebx, 8(%edi) ) +DST( movl %ebx, %es:8(%edi) ) adcl %edx, %eax -DST( movl %edx, 12(%edi) ) +DST( movl %edx, %es:12(%edi) ) SRC( movl 16(%esi), %ebx ) SRC( movl 20(%esi), %edx ) adcl %ebx, %eax -DST( movl %ebx, 16(%edi) ) +DST( movl %ebx, %es:16(%edi) ) adcl %edx, %eax -DST( movl %edx, 20(%edi) ) +DST( movl %edx, %es:20(%edi) ) SRC( movl 24(%esi), %ebx ) SRC( movl 28(%esi), %edx ) adcl %ebx, %eax -DST( movl %ebx, 24(%edi) ) +DST( movl %ebx, %es:24(%edi) ) adcl %edx, %eax -DST( movl %edx, 28(%edi) ) +DST( movl %edx, %es:28(%edi) ) lea 32(%esi), %esi lea 32(%edi), %edi @@ -354,7 +366,7 @@ DST( movl %edx, 28(%edi) ) shrl $2, %edx # This clears CF SRC(3: movl (%esi), %ebx ) adcl %ebx, %eax -DST( movl %ebx, (%edi) ) +DST( movl %ebx, %es:(%edi) ) lea 4(%esi), %esi lea 4(%edi), %edi dec %edx @@ -366,12 +378,12 @@ DST( movl %ebx, (%edi) ) jb 5f SRC( movw (%esi), %cx ) leal 2(%esi), %esi -DST( movw %cx, (%edi) ) +DST( movw %cx, %es:(%edi) ) leal 2(%edi), %edi je 6f shll $16,%ecx SRC(5: movb (%esi), %cl ) -DST( movb %cl, (%edi) ) +DST( movb %cl, %es:(%edi) ) 6: addl %ecx, %eax adcl $0, %eax 7: @@ -382,7 +394,7 @@ DST( movb %cl, (%edi) ) 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr - movl $-EFAULT, (%ebx) + movl $-EFAULT, %ss:(%ebx) # zero the complete destination - computing the rest # is too much work @@ -395,11 +407,15 @@ DST( movb %cl, (%edi) ) 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr - movl $-EFAULT,(%ebx) + movl $-EFAULT,%ss:(%ebx) jmp 5000b .previous + pushl %ss + popl %ds + pushl %ss + popl %es popl %ebx popl %esi popl %edi @@ -411,17 +427,28 @@ DST( movb %cl, (%edi) ) /* Version for PentiumII/PPro */ #define ROUND1(x) \ + nop; nop; nop; \ SRC(movl x(%esi), %ebx ) ; \ addl %ebx, %eax ; \ - DST(movl %ebx, x(%edi) ) ; + DST(movl %ebx, %es:x(%edi)); #define ROUND(x) \ + nop; nop; nop; \ SRC(movl x(%esi), %ebx ) ; \ adcl %ebx, %eax ; \ - DST(movl %ebx, x(%edi) ) ; + DST(movl %ebx, %es:x(%edi)); #define ARGBASE 12 - + +csum_partial_copy_generic_to_user: + pushl $(__USER_DS) + popl %es + jmp csum_partial_copy_generic + +csum_partial_copy_generic_from_user: + pushl $(__USER_DS) + popl %ds + csum_partial_copy_generic: pushl %ebx pushl %edi @@ -440,7 +467,7 @@ csum_partial_copy_generic: subl %ebx, %edi lea -1(%esi),%edx andl $-32,%edx - lea 3f(%ebx,%ebx), %ebx + lea 3f(%ebx,%ebx,2), %ebx testl %esi, %esi jmp *%ebx 1: addl $64,%esi @@ -461,19 +488,19 @@ csum_partial_copy_generic: jb 5f SRC( movw (%esi), %dx ) leal 2(%esi), %esi -DST( movw %dx, (%edi) ) +DST( movw %dx, %es:(%edi) ) leal 2(%edi), %edi je 6f shll $16,%edx 5: SRC( movb (%esi), %dl ) -DST( movb %dl, (%edi) ) +DST( movb %dl, %es:(%edi) ) 6: addl %edx, %eax adcl $0, %eax 7: .section .fixup, "ax" 6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr - movl $-EFAULT, (%ebx) + movl $-EFAULT, %ss:(%ebx) # zero the complete destination (computing the rest is too much work) movl ARGBASE+8(%esp),%edi # dst movl ARGBASE+12(%esp),%ecx # len @@ -481,10 +508,14 @@ DST( movb %dl, (%edi) ) rep; stosb jmp 7b 6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr - movl $-EFAULT, (%ebx) + movl $-EFAULT, %ss:(%ebx) jmp 7b .previous + pushl %ss + popl %ds + pushl %ss + popl %es popl %esi popl %edi popl %ebx diff -urNp linux-2.4.37.7/arch/i386/lib/getuser.S linux-2.4.37.7/arch/i386/lib/getuser.S --- linux-2.4.37.7/arch/i386/lib/getuser.S 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/lib/getuser.S 2009-11-10 19:30:27.000000000 -0500 @@ -9,6 +9,8 @@ * return value. */ +#include + /* * __get_user_X * @@ -31,7 +33,11 @@ __get_user_1: andl $0xffffe000,%edx cmpl addr_limit(%edx),%eax jae bad_get_user + pushl $(__USER_DS) + popl %ds 1: movzbl (%eax),%edx + pushl %ss + pop %ds xorl %eax,%eax ret @@ -44,7 +50,11 @@ __get_user_2: andl $0xffffe000,%edx cmpl addr_limit(%edx),%eax jae bad_get_user + pushl $(__USER_DS) + popl %ds 2: movzwl -1(%eax),%edx + pushl %ss + pop %ds xorl %eax,%eax ret @@ -57,11 +67,17 @@ __get_user_4: andl $0xffffe000,%edx cmpl addr_limit(%edx),%eax jae bad_get_user + pushl $(__USER_DS) + popl %ds 3: movl -3(%eax),%edx + pushl %ss + pop %ds xorl %eax,%eax ret bad_get_user: + pushl %ss + pop %ds xorl %edx,%edx movl $-14,%eax ret diff -urNp linux-2.4.37.7/arch/i386/lib/mmx.c linux-2.4.37.7/arch/i386/lib/mmx.c --- linux-2.4.37.7/arch/i386/lib/mmx.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/lib/mmx.c 2009-11-10 19:30:27.000000000 -0500 @@ -30,6 +30,7 @@ void *_mmx_memcpy(void *to, const void * { void *p; int i; + unsigned long cr0; if (in_interrupt()) return __memcpy(to, from, len); @@ -40,52 +41,80 @@ void *_mmx_memcpy(void *to, const void * kernel_fpu_begin(); __asm__ __volatile__ ( - "1: prefetch (%0)\n" /* This set is 28 bytes */ - " prefetch 64(%0)\n" - " prefetch 128(%0)\n" - " prefetch 192(%0)\n" - " prefetch 256(%0)\n" + "1: prefetch (%1)\n" /* This set is 28 bytes */ + " prefetch 64(%1)\n" + " prefetch 128(%1)\n" + " prefetch 192(%1)\n" + " prefetch 256(%1)\n" "2: \n" ".section .fixup, \"ax\"\n" - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ + "3: \n" + +#ifdef CONFIG_PAX_KERNEXEC + " movl %%cr0, %0\n" + " movl %0, %%eax\n" + " andl $0xFFFEFFFF, %%eax\n" + " movl %%eax, %%cr0\n" +#endif + + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ + +#ifdef CONFIG_PAX_KERNEXEC + " movl %0, %%cr0\n" +#endif + " jmp 2b\n" ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b, 3b\n" ".previous" - : : "r" (from) ); + : "=&r" (cr0) : "r" (from) : "ax"); for(; i>5; i--) { __asm__ __volatile__ ( - "1: prefetch 320(%0)\n" - "2: movq (%0), %%mm0\n" - " movq 8(%0), %%mm1\n" - " movq 16(%0), %%mm2\n" - " movq 24(%0), %%mm3\n" - " movq %%mm0, (%1)\n" - " movq %%mm1, 8(%1)\n" - " movq %%mm2, 16(%1)\n" - " movq %%mm3, 24(%1)\n" - " movq 32(%0), %%mm0\n" - " movq 40(%0), %%mm1\n" - " movq 48(%0), %%mm2\n" - " movq 56(%0), %%mm3\n" - " movq %%mm0, 32(%1)\n" - " movq %%mm1, 40(%1)\n" - " movq %%mm2, 48(%1)\n" - " movq %%mm3, 56(%1)\n" + "1: prefetch 320(%1)\n" + "2: movq (%1), %%mm0\n" + " movq 8(%1), %%mm1\n" + " movq 16(%1), %%mm2\n" + " movq 24(%1), %%mm3\n" + " movq %%mm0, (%2)\n" + " movq %%mm1, 8(%2)\n" + " movq %%mm2, 16(%2)\n" + " movq %%mm3, 24(%2)\n" + " movq 32(%1), %%mm0\n" + " movq 40(%1), %%mm1\n" + " movq 48(%1), %%mm2\n" + " movq 56(%1), %%mm3\n" + " movq %%mm0, 32(%2)\n" + " movq %%mm1, 40(%2)\n" + " movq %%mm2, 48(%2)\n" + " movq %%mm3, 56(%2)\n" ".section .fixup, \"ax\"\n" - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */ + "3:\n" + +#ifdef CONFIG_PAX_KERNEXEC + " movl %%cr0, %0\n" + " movl %0, %%eax\n" + " andl $0xFFFEFFFF, %%eax\n" + " movl %%eax, %%cr0\n" +#endif + + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */ + +#ifdef CONFIG_PAX_KERNEXEC + " movl %0, %%cr0\n" +#endif + " jmp 2b\n" ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b, 3b\n" ".previous" - : : "r" (from), "r" (to) : "memory"); + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax"); from+=64; to+=64; } @@ -164,6 +193,7 @@ static void fast_clear_page(void *page) static void fast_copy_page(void *to, void *from) { int i; + unsigned long cr0; kernel_fpu_begin(); @@ -171,51 +201,79 @@ static void fast_copy_page(void *to, voi * but that is for later. -AV */ __asm__ __volatile__ ( - "1: prefetch (%0)\n" - " prefetch 64(%0)\n" - " prefetch 128(%0)\n" - " prefetch 192(%0)\n" - " prefetch 256(%0)\n" + "1: prefetch (%1)\n" + " prefetch 64(%1)\n" + " prefetch 128(%1)\n" + " prefetch 192(%1)\n" + " prefetch 256(%1)\n" "2: \n" ".section .fixup, \"ax\"\n" - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ + "3: \n" + +#ifdef CONFIG_PAX_KERNEXEC + " movl %%cr0, %0\n" + " movl %0, %%eax\n" + " andl $0xFFFEFFFF, %%eax\n" + " movl %%eax, %%cr0\n" +#endif + + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ + +#ifdef CONFIG_PAX_KERNEXEC + " movl %0, %%cr0\n" +#endif + " jmp 2b\n" ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b, 3b\n" ".previous" - : : "r" (from) ); + : "=&r" (cr0) : "r" (from) : "ax"); for(i=0; i<(4096-320)/64; i++) { __asm__ __volatile__ ( - "1: prefetch 320(%0)\n" - "2: movq (%0), %%mm0\n" - " movntq %%mm0, (%1)\n" - " movq 8(%0), %%mm1\n" - " movntq %%mm1, 8(%1)\n" - " movq 16(%0), %%mm2\n" - " movntq %%mm2, 16(%1)\n" - " movq 24(%0), %%mm3\n" - " movntq %%mm3, 24(%1)\n" - " movq 32(%0), %%mm4\n" - " movntq %%mm4, 32(%1)\n" - " movq 40(%0), %%mm5\n" - " movntq %%mm5, 40(%1)\n" - " movq 48(%0), %%mm6\n" - " movntq %%mm6, 48(%1)\n" - " movq 56(%0), %%mm7\n" - " movntq %%mm7, 56(%1)\n" + "1: prefetch 320(%1)\n" + "2: movq (%1), %%mm0\n" + " movntq %%mm0, (%2)\n" + " movq 8(%1), %%mm1\n" + " movntq %%mm1, 8(%2)\n" + " movq 16(%1), %%mm2\n" + " movntq %%mm2, 16(%2)\n" + " movq 24(%1), %%mm3\n" + " movntq %%mm3, 24(%2)\n" + " movq 32(%1), %%mm4\n" + " movntq %%mm4, 32(%2)\n" + " movq 40(%1), %%mm5\n" + " movntq %%mm5, 40(%2)\n" + " movq 48(%1), %%mm6\n" + " movntq %%mm6, 48(%2)\n" + " movq 56(%1), %%mm7\n" + " movntq %%mm7, 56(%2)\n" ".section .fixup, \"ax\"\n" - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */ + "3:\n" + +#ifdef CONFIG_PAX_KERNEXEC + " movl %%cr0, %0\n" + " movl %0, %%eax\n" + " andl $0xFFFEFFFF, %%eax\n" + " movl %%eax, %%cr0\n" +#endif + + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */ + +#ifdef CONFIG_PAX_KERNEXEC + " movl %0, %%cr0\n" +#endif + " jmp 2b\n" ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b, 3b\n" ".previous" - : : "r" (from), "r" (to) : "memory"); + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax"); from+=64; to+=64; } @@ -296,56 +354,84 @@ static void fast_clear_page(void *page) static void fast_copy_page(void *to, void *from) { int i; - - + unsigned long cr0; + kernel_fpu_begin(); __asm__ __volatile__ ( - "1: prefetch (%0)\n" - " prefetch 64(%0)\n" - " prefetch 128(%0)\n" - " prefetch 192(%0)\n" - " prefetch 256(%0)\n" + "1: prefetch (%1)\n" + " prefetch 64(%1)\n" + " prefetch 128(%1)\n" + " prefetch 192(%1)\n" + " prefetch 256(%1)\n" "2: \n" ".section .fixup, \"ax\"\n" - "3: movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ + "3: \n" + +#ifdef CONFIG_PAX_KERNEXEC + " movl %%cr0, %0\n" + " movl %0, %%eax\n" + " andl $0xFFFEFFFF, %%eax\n" + " movl %%eax, %%cr0\n" +#endif + + " movw $0x1AEB, 1b\n" /* jmp on 26 bytes */ + +#ifdef CONFIG_PAX_KERNEXEC + " movl %0, %%cr0\n" +#endif + " jmp 2b\n" ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b, 3b\n" ".previous" - : : "r" (from) ); + : "=&r" (cr0) : "r" (from) : "ax"); for(i=0; i<4096/64; i++) { __asm__ __volatile__ ( - "1: prefetch 320(%0)\n" - "2: movq (%0), %%mm0\n" - " movq 8(%0), %%mm1\n" - " movq 16(%0), %%mm2\n" - " movq 24(%0), %%mm3\n" - " movq %%mm0, (%1)\n" - " movq %%mm1, 8(%1)\n" - " movq %%mm2, 16(%1)\n" - " movq %%mm3, 24(%1)\n" - " movq 32(%0), %%mm0\n" - " movq 40(%0), %%mm1\n" - " movq 48(%0), %%mm2\n" - " movq 56(%0), %%mm3\n" - " movq %%mm0, 32(%1)\n" - " movq %%mm1, 40(%1)\n" - " movq %%mm2, 48(%1)\n" - " movq %%mm3, 56(%1)\n" + "1: prefetch 320(%1)\n" + "2: movq (%1), %%mm0\n" + " movq 8(%1), %%mm1\n" + " movq 16(%1), %%mm2\n" + " movq 24(%1), %%mm3\n" + " movq %%mm0, (%2)\n" + " movq %%mm1, 8(%2)\n" + " movq %%mm2, 16(%2)\n" + " movq %%mm3, 24(%2)\n" + " movq 32(%1), %%mm0\n" + " movq 40(%1), %%mm1\n" + " movq 48(%1), %%mm2\n" + " movq 56(%1), %%mm3\n" + " movq %%mm0, 32(%2)\n" + " movq %%mm1, 40(%2)\n" + " movq %%mm2, 48(%2)\n" + " movq %%mm3, 56(%2)\n" ".section .fixup, \"ax\"\n" - "3: movw $0x05EB, 1b\n" /* jmp on 5 bytes */ + "3:\n" + +#ifdef CONFIG_PAX_KERNEXEC + " movl %%cr0, %0\n" + " movl %0, %%eax\n" + " andl $0xFFFEFFFF, %%eax\n" + " movl %%eax, %%cr0\n" +#endif + + " movw $0x05EB, 1b\n" /* jmp on 5 bytes */ + +#ifdef CONFIG_PAX_KERNEXEC + " movl %0, %%cr0\n" +#endif + " jmp 2b\n" ".previous\n" ".section __ex_table,\"a\"\n" " .align 4\n" " .long 1b, 3b\n" ".previous" - : : "r" (from), "r" (to) : "memory"); + : "=&r" (cr0) : "r" (from), "r" (to) : "memory", "ax"); from+=64; to+=64; } diff -urNp linux-2.4.37.7/arch/i386/lib/usercopy.c linux-2.4.37.7/arch/i386/lib/usercopy.c --- linux-2.4.37.7/arch/i386/lib/usercopy.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/lib/usercopy.c 2009-11-10 19:30:27.000000000 -0500 @@ -8,6 +8,7 @@ #include #include #include +#include #ifdef CONFIG_X86_USE_3DNOW_AND_WORKS @@ -75,6 +76,11 @@ __generic_copy_from_user(void *to, const do { \ int __d0, __d1, __d2; \ __asm__ __volatile__( \ + " movw %w0,%%ds\n" \ + : \ + : "r"(__USER_DS) \ + : "memory"); \ + __asm__ __volatile__( \ " testl %1,%1\n" \ " jz 2f\n" \ "0: lodsb\n" \ @@ -85,6 +91,8 @@ do { \ " jnz 0b\n" \ "1: subl %1,%0\n" \ "2:\n" \ + " pushl %%ss\n" \ + " popl %%ds\n" \ ".section .fixup,\"ax\"\n" \ "3: movl %5,%0\n" \ " jmp 2b\n" \ @@ -163,10 +171,13 @@ strncpy_from_user(char *dst, const char do { \ int __d0; \ __asm__ __volatile__( \ + " movw %w6,%%es\n" \ "0: rep; stosl\n" \ " movl %2,%0\n" \ "1: rep; stosb\n" \ "2:\n" \ + " pushl %%ss\n" \ + " popl %%es\n" \ ".section .fixup,\"ax\"\n" \ "3: lea 0(%2,%0,4),%0\n" \ " jmp 2b\n" \ @@ -177,7 +188,8 @@ do { \ " .long 1b,2b\n" \ ".previous" \ : "=&c"(size), "=&D" (__d0) \ - : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \ + : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0), \ + "r"(__USER_DS)); \ } while (0) /** @@ -233,6 +245,7 @@ long strnlen_user(const char *s, long n) unsigned long res, tmp; __asm__ __volatile__( + " movw %w8,%%es\n" " testl %0, %0\n" " jz 3f\n" " andl %0,%%ecx\n" @@ -241,6 +254,8 @@ long strnlen_user(const char *s, long n) " subl %%ecx,%0\n" " addl %0,%%eax\n" "1:\n" + " pushl %%ss\n" + " popl %%es\n" ".section .fixup,\"ax\"\n" "2: xorl %%eax,%%eax\n" " jmp 1b\n" @@ -252,7 +267,7 @@ long strnlen_user(const char *s, long n) " .long 0b,2b\n" ".previous" :"=r" (n), "=D" (s), "=a" (res), "=c" (tmp) - :"0" (n), "1" (s), "2" (0), "3" (mask) + :"0" (n), "1" (s), "2" (0), "3" (mask), "r" (__USER_DS) :"cc"); return res & mask; } diff -urNp linux-2.4.37.7/arch/i386/Makefile linux-2.4.37.7/arch/i386/Makefile --- linux-2.4.37.7/arch/i386/Makefile 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/Makefile 2009-11-10 19:30:27.000000000 -0500 @@ -123,6 +123,9 @@ arch/i386/mm: dummy MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot +arch/i386/vmlinux.lds: arch/i386/vmlinux.lds.S FORCE + $(CPP) -C -P -I$(HPATH) -D__KERNEL__ -imacros $(HPATH)/linux/config.h -imacros $(HPATH)/asm-i386/segment.h -imacros $(HPATH)/asm-i386/page.h -Ui386 arch/i386/vmlinux.lds.S >arch/i386/vmlinux.lds + vmlinux: arch/i386/vmlinux.lds FORCE: ; @@ -159,6 +162,7 @@ archclean: @$(MAKEBOOT) clean archmrproper: + rm -f arch/i386/vmlinux.lds archdep: @$(MAKEBOOT) dep diff -urNp linux-2.4.37.7/arch/i386/mm/fault.c linux-2.4.37.7/arch/i386/mm/fault.c --- linux-2.4.37.7/arch/i386/mm/fault.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/mm/fault.c 2009-11-10 19:30:27.000000000 -0500 @@ -19,6 +19,8 @@ #include #include #include /* For unblank_screen() */ +#include +#include #include #include @@ -78,6 +80,12 @@ good_area: check_stack: if (!(vma->vm_flags & VM_GROWSDOWN)) goto bad_area; + +#ifdef CONFIG_PAX_SEGMEXEC + if ((vma->vm_mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < start - SEGMEXEC_TASK_SIZE - 1) + goto bad_area; +#endif + if (expand_stack(vma, start) == 0) goto good_area; @@ -125,7 +133,10 @@ void bust_spinlocks(int yes) } asmlinkage void do_invalid_op(struct pt_regs *, unsigned long); -extern unsigned long idt; + +#ifdef CONFIG_PAX_EMUTRAMP +static int pax_handle_fetch_fault(struct pt_regs *regs); +#endif /* * This routine handles page faults. It determines the address, @@ -137,23 +148,31 @@ extern unsigned long idt; * bit 1 == 0 means read, 1 means write * bit 2 == 0 means kernel, 1 means user-mode */ -asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) + +#ifdef CONFIG_PAX_PAGEEXEC +static int do_page_fault(struct pt_regs *regs, unsigned long error_code, unsigned long address) +#else +asmlinkage int do_page_fault(struct pt_regs *regs, unsigned long error_code) +#endif { struct task_struct *tsk; struct mm_struct *mm; struct vm_area_struct * vma; +#ifndef CONFIG_PAX_PAGEEXEC unsigned long address; - unsigned long page; +#endif unsigned long fixup; int write; siginfo_t info; +#ifndef CONFIG_PAX_PAGEEXEC /* get the address */ __asm__("movl %%cr2,%0":"=r" (address)); /* It's safe to allow irq's after cr2 has been saved */ if (regs->eflags & X86_EFLAGS_IF) local_irq_enable(); +#endif tsk = current; @@ -202,6 +221,12 @@ asmlinkage void do_page_fault(struct pt_ if (address + 32 < regs->esp) goto bad_area; } + +#ifdef CONFIG_PAX_SEGMEXEC + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && vma->vm_end - SEGMEXEC_TASK_SIZE - 1 < address - SEGMEXEC_TASK_SIZE - 1) + goto bad_area; +#endif + if (expand_stack(vma, address)) goto bad_area; /* @@ -258,7 +283,7 @@ good_area: tsk->thread.screen_bitmap |= 1 << bit; } up_read(&mm->mmap_sem); - return; + return 0; /* * Something tried to access memory that isn't in our memory map.. @@ -267,6 +292,38 @@ good_area: bad_area: up_read(&mm->mmap_sem); +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) + if ((error_code & 4) && !(regs->eflags & X86_EFLAGS_VM)) { + +#ifdef CONFIG_PAX_PAGEEXEC + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && !(error_code & 3) && (regs->eip == address)) { + pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp); + do_exit(SIGKILL); + } +#endif + +#ifdef CONFIG_PAX_SEGMEXEC + if ((mm->pax_flags & MF_PAX_SEGMEXEC) && !(error_code & 3) && (regs->eip + SEGMEXEC_TASK_SIZE == address)) { + +#ifdef CONFIG_PAX_EMUTRAMP + switch (pax_handle_fetch_fault(regs)) { + case 4: + return 0; + + case 3: + case 2: + return 1; + } +#endif + + pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp); + do_exit(SIGKILL); + } +#endif + + } +#endif + /* User mode accesses just cause a SIGSEGV */ if (error_code & 4) { tsk->thread.cr2 = address; @@ -278,7 +335,7 @@ bad_area: /* info.si_code has been set above */ info.si_addr = (void *)address; force_sig_info(SIGSEGV, &info, tsk); - return; + return 0; } /* @@ -287,11 +344,11 @@ bad_area: if (boot_cpu_data.f00f_bug) { unsigned long nr; - nr = (address - idt) >> 3; + nr = (address - (unsigned long)idt) >> 3; if (nr == 6) { do_invalid_op(regs, 0); - return; + return 0; } } @@ -299,7 +356,7 @@ no_context: /* Are we prepared to handle this kernel fault? */ if ((fixup = search_exception_table(regs->eip)) != 0) { regs->eip = fixup; - return; + return 0; } /* @@ -311,19 +368,41 @@ no_context: if (address < PAGE_SIZE) printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); + +#ifdef CONFIG_PAX_KERNEXEC + else if (init_mm.start_code <= address && address < init_mm.end_code) { + if (tsk->curr_ip) + printk(KERN_ERR "PAX: From %u.%u.%u.%u: %s:%d, uid/euid: %u/%u, attempted to modify kernel code", + NIPQUAD(tsk->curr_ip), tsk->comm, tsk->pid, tsk->uid, tsk->euid); + else + printk(KERN_ERR "PAX: %s:%d, uid/euid: %u/%u, attempted to modify kernel code", + tsk->comm, tsk->pid, tsk->uid, tsk->euid); + } +#endif + else printk(KERN_ALERT "Unable to handle kernel paging request"); printk(" at virtual address %08lx\n",address); printk(" printing eip:\n"); printk("%08lx\n", regs->eip); - asm("movl %%cr3,%0":"=r" (page)); - page = ((unsigned long *) __va(page))[address >> 22]; - printk(KERN_ALERT "*pde = %08lx\n", page); - if (page & 1) { - page &= PAGE_MASK; - address &= 0x003ff000; - page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT]; - printk(KERN_ALERT "*pte = %08lx\n", page); + { + unsigned long index = pgd_index(address); + unsigned long pgd_paddr; + pgd_t *pgd; + pmd_t *pmd; + pte_t *pte; + + asm("movl %%cr3,%0":"=r" (pgd_paddr)); + pgd = index + (pgd_t *)__va(pgd_paddr); + printk(KERN_ALERT "*pgd = %*llx\n", sizeof(*pgd), (unsigned long long)pgd_val(*pgd)); + if (pgd_present(*pgd)) { + pmd = pmd_offset(pgd, address); + printk(KERN_ALERT "*pmd = %*llx\n", sizeof(*pmd), (unsigned long long)pmd_val(*pmd)); + if (pmd_present(*pmd) && !(pmd_val(*pmd) & _PAGE_PSE)) { + pte = pte_offset(pmd, address); + printk(KERN_ALERT "*pte = %*llx\n", sizeof(*pte), (unsigned long long)pte_val(*pte)); + } + } } die("Oops", regs, error_code); bust_spinlocks(0); @@ -363,7 +442,7 @@ do_sigbus: /* Kernel mode? Handle exceptions or die */ if (!(error_code & 4)) goto no_context; - return; + return 0; vmalloc_fault: { @@ -396,6 +475,333 @@ vmalloc_fault: pte_k = pte_offset(pmd_k, address); if (!pte_present(*pte_k)) goto no_context; - return; + return 0; } } + +#ifdef CONFIG_PAX_PAGEEXEC +/* PaX: called with the page_table_lock spinlock held */ +static inline pte_t * pax_get_pte(struct mm_struct *mm, unsigned long address) +{ + pgd_t *pgd; + pmd_t *pmd; + + pgd = pgd_offset(mm, address); + if (!pgd_present(*pgd)) + return NULL; + pmd = pmd_offset(pgd, address); + if (!pmd_present(*pmd)) + return NULL; + return pte_offset(pmd, address); +} +#endif + +#ifdef CONFIG_PAX_EMUTRAMP +/* + * PaX: decide what to do with offenders (regs->eip = fault address) + * + * returns 1 when task should be killed + * 2 when sigreturn trampoline was detected + * 3 when rt_sigreturn trampoline was detected + * 4 when gcc trampoline was detected + */ +static int pax_handle_fetch_fault(struct pt_regs *regs) +{ + static const unsigned char trans[8] = { + offsetof(struct pt_regs, eax) / 4, + offsetof(struct pt_regs, ecx) / 4, + offsetof(struct pt_regs, edx) / 4, + offsetof(struct pt_regs, ebx) / 4, + offsetof(struct pt_regs, esp) / 4, + offsetof(struct pt_regs, ebp) / 4, + offsetof(struct pt_regs, esi) / 4, + offsetof(struct pt_regs, edi) / 4, + }; + int err; + + if (regs->eflags & X86_EFLAGS_VM) + return 1; + +#ifndef CONFIG_PAX_EMUSIGRT + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP)) + return 1; +#endif + + do { /* PaX: sigreturn emulation */ + unsigned char pop, mov; + unsigned short sys; + unsigned long nr; + + err = get_user(pop, (unsigned char *)(regs->eip)); + err |= get_user(mov, (unsigned char *)(regs->eip + 1)); + err |= get_user(nr, (unsigned long *)(regs->eip + 2)); + err |= get_user(sys, (unsigned short *)(regs->eip + 6)); + + if (err) + break; + + if (pop == 0x58 && + mov == 0xb8 && + nr == __NR_sigreturn && + sys == 0x80cd) + { + +#ifdef CONFIG_PAX_EMUSIGRT + int sig; + struct k_sigaction *ka; + __sighandler_t handler; + + if (get_user(sig, (int *)regs->esp)) + return 1; + if (sig < 1 || sig > _NSIG || sig == SIGKILL || sig == SIGSTOP) + return 1; + spin_lock_irq(¤t->sigmask_lock); + ka = ¤t->sig->action[sig-1]; + handler = ka->sa.sa_handler; + if (handler == SIG_DFL || handler == SIG_IGN) { + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP)) + err = 1; + } else if (ka->sa.sa_flags & SA_SIGINFO) + err = 1; + spin_unlock_irq(¤t->sigmask_lock); + if (err) + return 1; +#endif + + regs->esp += 4; + regs->eax = nr; + regs->eip += 8; + return 2; + } + } while (0); + + do { /* PaX: rt_sigreturn emulation */ + unsigned char mov; + unsigned short sys; + unsigned long nr; + + err = get_user(mov, (unsigned char *)(regs->eip)); + err |= get_user(nr, (unsigned long *)(regs->eip + 1)); + err |= get_user(sys, (unsigned short *)(regs->eip + 5)); + + if (err) + break; + + if (mov == 0xb8 && + nr == __NR_rt_sigreturn && + sys == 0x80cd) + { + +#ifdef CONFIG_PAX_EMUSIGRT + int sig; + struct k_sigaction *ka; + __sighandler_t handler; + + if (get_user(sig, (int *)regs->esp)) + return 1; + if (sig < 1 || sig > _NSIG || sig == SIGKILL || sig == SIGSTOP) + return 1; + spin_lock_irq(¤t->sigmask_lock); + ka = ¤t->sig->action[sig-1]; + handler = ka->sa.sa_handler; + if (handler == SIG_DFL || handler == SIG_IGN) { + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP)) + err = 1; + } else if (!(ka->sa.sa_flags & SA_SIGINFO)) + err = 1; + spin_unlock_irq(¤t->sigmask_lock); + if (err) + return 1; +#endif + + regs->eax = nr; + regs->eip += 7; + return 3; + } + } while (0); + +#ifdef CONFIG_PAX_EMUSIGRT + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP)) + return 1; +#endif + + do { /* PaX: gcc trampoline emulation #1 */ + unsigned char mov1, mov2; + unsigned short jmp; + unsigned long addr1, addr2; + + err = get_user(mov1, (unsigned char *)regs->eip); + err |= get_user(addr1, (unsigned long *)(regs->eip + 1)); + err |= get_user(mov2, (unsigned char *)(regs->eip + 5)); + err |= get_user(addr2, (unsigned long *)(regs->eip + 6)); + err |= get_user(jmp, (unsigned short *)(regs->eip + 10)); + + if (err) + break; + + if ((mov1 & 0xF8) == 0xB8 && + (mov2 & 0xF8) == 0xB8 && + (mov1 & 0x07) != (mov2 & 0x07) && + (jmp & 0xF8FF) == 0xE0FF && + (mov2 & 0x07) == ((jmp>>8) & 0x07)) + { + ((unsigned long *)regs)[trans[mov1 & 0x07]] = addr1; + ((unsigned long *)regs)[trans[mov2 & 0x07]] = addr2; + regs->eip = addr2; + return 4; + } + } while (0); + + do { /* PaX: gcc trampoline emulation #2 */ + unsigned char mov, jmp; + unsigned long addr1, addr2; + + err = get_user(mov, (unsigned char *)regs->eip); + err |= get_user(addr1, (unsigned long *)(regs->eip + 1)); + err |= get_user(jmp, (unsigned char *)(regs->eip + 5)); + err |= get_user(addr2, (unsigned long *)(regs->eip + 6)); + + if (err) + break; + + if ((mov & 0xF8) == 0xB8 && + jmp == 0xE9) + { + ((unsigned long *)regs)[trans[mov & 0x07]] = addr1; + regs->eip += addr2 + 10; + return 4; + } + } while (0); + + return 1; /* PaX in action */ +} +#endif + +#if defined(CONFIG_PAX_PAGEEXEC) || defined(CONFIG_PAX_SEGMEXEC) +void pax_report_insns(void *pc, void *sp) +{ + long i; + + printk(KERN_ERR "PAX: bytes at PC: "); + for (i = 0; i < 20; i++) { + unsigned char c; + if (get_user(c, (unsigned char*)pc+i)) + printk("?? "); + else + printk("%02x ", c); + } + printk("\n"); + + printk(KERN_ERR "PAX: bytes at SP-4: "); + for (i = -1; i < 20; i++) { + unsigned long c; + if (get_user(c, (unsigned long*)sp+i)) + printk("???????? "); + else + printk("%08lx ", c); + } + printk("\n"); +} +#endif + +#ifdef CONFIG_PAX_PAGEEXEC +/* + * PaX: handle the extra page faults or pass it down to the original handler + * + * returns 0 when nothing special was detected + * 1 when sigreturn trampoline (syscall) has to be emulated + */ +asmlinkage int pax_do_page_fault(struct pt_regs *regs, unsigned long error_code) +{ + struct mm_struct *mm = current->mm; + unsigned long address; + pte_t *pte; + unsigned char pte_mask; + + __asm__("movl %%cr2,%0":"=r" (address)); + + /* It's safe to allow irq's after cr2 has been saved */ + if (likely(regs->eflags & X86_EFLAGS_IF)) + local_irq_enable(); + + if (unlikely((error_code & 5) != 5 || + address >= TASK_SIZE || + (regs->eflags & X86_EFLAGS_VM) || + !mm || !(mm->pax_flags & MF_PAX_PAGEEXEC))) + return do_page_fault(regs, error_code, address); + + /* PaX: it's our fault, let's handle it if we can */ + + /* PaX: take a look at read faults before acquiring any locks */ + if (unlikely(!(error_code & 2) && (regs->eip == address))) { + /* instruction fetch attempt from a protected page in user mode */ + +#ifdef CONFIG_PAX_EMUTRAMP + switch (pax_handle_fetch_fault(regs)) { + case 4: + return 0; + + case 3: + case 2: + return 1; + } +#endif + + pax_report_fault(regs, (void*)regs->eip, (void*)regs->esp); + do_exit(SIGKILL); + } + + pte_mask = _PAGE_ACCESSED | _PAGE_USER | ((error_code & 2) << (_PAGE_BIT_DIRTY-1)); + + spin_lock(&mm->page_table_lock); + pte = pax_get_pte(mm, address); + if (unlikely(!pte || !(pte_val(*pte) & _PAGE_PRESENT) || pte_exec(*pte))) { + spin_unlock(&mm->page_table_lock); + do_page_fault(regs, error_code, address); + return 0; + } + + if (unlikely((error_code & 2) && !pte_write(*pte))) { + /* write attempt to a protected page in user mode */ + spin_unlock(&mm->page_table_lock); + do_page_fault(regs, error_code, address); + return 0; + } + + /* + * PaX: fill DTLB with user rights and retry + */ + __asm__ __volatile__ ( +#ifdef CONFIG_PAX_MEMORY_UDEREF + "movw %w4,%%es\n" +#endif + "orb %2,(%1)\n" +#if defined(CONFIG_M586) || defined(CONFIG_M586TSC) +/* + * PaX: let this uncommented 'invlpg' remind us on the behaviour of Intel's + * (and AMD's) TLBs. namely, they do not cache PTEs that would raise *any* + * page fault when examined during a TLB load attempt. this is true not only + * for PTEs holding a non-present entry but also present entries that will + * raise a page fault (such as those set up by PaX, or the copy-on-write + * mechanism). in effect it means that we do *not* need to flush the TLBs + * for our target pages since their PTEs are simply not in the TLBs at all. + + * the best thing in omitting it is that we gain around 15-20% speed in the + * fast path of the page fault handler and can get rid of tracing since we + * can no longer flush unintended entries. + */ + "invlpg (%0)\n" +#endif + "testb $0,%%es:(%0)\n" + "xorb %3,(%1)\n" +#ifdef CONFIG_PAX_MEMORY_UDEREF + "pushl %%ss\n" + "popl %%es\n" +#endif + : + : "q" (address), "r" (pte), "q" (pte_mask), "i" (_PAGE_USER), "r" (__USER_DS) + : "memory", "cc"); + spin_unlock(&mm->page_table_lock); + return 0; +} +#endif diff -urNp linux-2.4.37.7/arch/i386/mm/init.c linux-2.4.37.7/arch/i386/mm/init.c --- linux-2.4.37.7/arch/i386/mm/init.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/mm/init.c 2009-11-10 19:30:27.000000000 -0500 @@ -37,6 +37,7 @@ #include #include #include +#include mmu_gather_t mmu_gathers[NR_CPUS]; unsigned long highstart_pfn, highend_pfn; @@ -122,7 +123,7 @@ void show_mem(void) /* References to section boundaries */ -extern char _text, _etext, _edata, __bss_start, _end; +extern char _text, _etext, _data, _edata, __bss_start, _end; extern char __init_begin, __init_end; static inline void set_pte_phys (unsigned long vaddr, @@ -178,17 +179,7 @@ static void __init fixrange_init (unsign pgd = pgd_base + i; for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) { -#if CONFIG_X86_PAE - if (pgd_none(*pgd)) { - pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); - set_pgd(pgd, __pgd(__pa(pmd) + 0x1)); - if (pmd != pmd_offset(pgd, 0)) - printk("PAE BUG #02!\n"); - } pmd = pmd_offset(pgd, vaddr); -#else - pmd = (pmd_t *)pgd; -#endif for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { if (pmd_none(*pmd)) { pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); @@ -217,25 +208,22 @@ static void __init pagetable_init (void) end = (unsigned long)__va(max_low_pfn*PAGE_SIZE); pgd_base = swapper_pg_dir; -#if CONFIG_X86_PAE - for (i = 0; i < PTRS_PER_PGD; i++) - set_pgd(pgd_base + i, __pgd(1 + __pa(empty_zero_page))); -#endif i = __pgd_offset(PAGE_OFFSET); pgd = pgd_base + i; + if (cpu_has_pse) { + set_in_cr4(X86_CR4_PSE); + boot_cpu_data.wp_works_ok = 1; + + if (cpu_has_pge) + set_in_cr4(X86_CR4_PGE); + } + for (; i < PTRS_PER_PGD; pgd++, i++) { vaddr = i*PGDIR_SIZE; if (end && (vaddr >= end)) break; -#if CONFIG_X86_PAE - pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); - set_pgd(pgd, __pgd(__pa(pmd) + 0x1)); -#else - pmd = (pmd_t *)pgd; -#endif - if (pmd != pmd_offset(pgd, 0)) - BUG(); + pmd = pmd_offset(pgd, PAGE_OFFSET); for (j = 0; j < PTRS_PER_PMD; pmd++, j++) { vaddr = i*PGDIR_SIZE + j*PMD_SIZE; if (end && (vaddr >= end)) @@ -243,14 +231,16 @@ static void __init pagetable_init (void) if (cpu_has_pse) { unsigned long __pe; - set_in_cr4(X86_CR4_PSE); - boot_cpu_data.wp_works_ok = 1; __pe = _KERNPG_TABLE + _PAGE_PSE + __pa(vaddr); /* Make it "global" too if supported */ - if (cpu_has_pge) { - set_in_cr4(X86_CR4_PGE); + if (cpu_has_pge) __pe += _PAGE_GLOBAL; - } + +#ifdef CONFIG_PAX_KERNEXEC + if (__KERNEL_TEXT_OFFSET <= vaddr && vaddr < (unsigned long)&_data) + __pe &= ~_PAGE_RW; +#endif + set_pmd(pmd, __pmd(__pe)); continue; } @@ -263,6 +253,13 @@ static void __init pagetable_init (void) break; *pte = mk_pte_phys(__pa(vaddr), PAGE_KERNEL); } + +#ifdef CONFIG_PAX_KERNEXEC + if (__KERNEL_TEXT_OFFSET <= vaddr && vaddr < (unsigned long)&_data) + set_pmd(pmd, __pmd((_KERNPG_TABLE & ~_PAGE_RW) + __pa(pte_base))); + else +#endif + set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte_base))); if (pte_base != pte_offset(pmd, 0)) BUG(); @@ -289,17 +286,6 @@ static void __init pagetable_init (void) pte = pte_offset(pmd, vaddr); pkmap_page_table = pte; #endif - -#if CONFIG_X86_PAE - /* - * Add low memory identity-mappings - SMP needs it when - * starting up on an AP from real-mode. In the non-PAE - * case we already have these mappings through head.S. - * All user-space mappings are explicitly cleared after - * SMP startup. - */ - pgd_base[0] = pgd_base[USER_PTRS_PER_PGD]; -#endif } void __init zap_low_mappings (void) @@ -312,7 +298,7 @@ void __init zap_low_mappings (void) * us, because pgd_clear() is a no-op on i386. */ for (i = 0; i < USER_PTRS_PER_PGD; i++) -#if CONFIG_X86_PAE +#ifdef CONFIG_X86_PAE set_pgd(swapper_pg_dir+i, __pgd(1 + __pa(empty_zero_page))); #else set_pgd(swapper_pg_dir+i, __pgd(0)); @@ -353,16 +339,6 @@ void __init paging_init(void) pagetable_init(); load_cr3(swapper_pg_dir); - -#if CONFIG_X86_PAE - /* - * We will bail out later - printk doesn't work right now so - * the user would just see a hanging kernel. - */ - if (cpu_has_pae) - set_in_cr4(X86_CR4_PAE); -#endif - __flush_tlb_all(); #ifdef CONFIG_HIGHMEM @@ -508,6 +484,10 @@ void __init mem_init(void) { int codesize, reservedpages, datasize, initsize; +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; +#endif + if (!mem_map) BUG(); #ifdef CONFIG_HIGHMEM @@ -524,12 +504,21 @@ void __init mem_init(void) high_memory = (void *) __va(max_low_pfn * PAGE_SIZE); /* clear the zero-page */ + +#ifdef CONFIG_PAX_KERNEXEC + pax_open_kernel(cr0); +#endif + memset(empty_zero_page, 0, PAGE_SIZE); +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + reservedpages = free_pages_init(); codesize = (unsigned long) &_etext - (unsigned long) &_text; - datasize = (unsigned long) &_edata - (unsigned long) &_etext; + datasize = (unsigned long) &_edata - (unsigned long) &_data; initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin; printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n", @@ -542,10 +531,6 @@ void __init mem_init(void) (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)) ); -#if CONFIG_X86_PAE - if (!cpu_has_pae) - panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!"); -#endif if (boot_cpu_data.wp_works_ok < 0) test_wp_bit(); @@ -589,6 +574,26 @@ void free_initmem(void) { unsigned long addr; +#ifdef CONFIG_PAX_KERNEXEC + /* PaX: limit KERNEL_CS to actual size */ + unsigned long limit, cr0; + + limit = (unsigned long)&_etext >> PAGE_SHIFT; + + pax_open_kernel(cr0); + + gdt_table[2].a = (gdt_table[2].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL); + gdt_table[2].b = (gdt_table[2].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL); + +#ifdef CONFIG_PAX_SEGMEXEC + gdt_table2[2].a = (gdt_table2[2].a & 0xFFFF0000UL) | (limit & 0x0FFFFUL); + gdt_table2[2].b = (gdt_table2[2].b & 0xFFF0FFFFUL) | (limit & 0xF0000UL); +#endif + + pax_close_kernel(cr0); +#endif + + memset(&__init_begin, 0, &__init_end - &__init_begin); addr = (unsigned long)(&__init_begin); for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { ClearPageReserved(virt_to_page(addr)); diff -urNp linux-2.4.37.7/arch/i386/mm/ioremap.c linux-2.4.37.7/arch/i386/mm/ioremap.c --- linux-2.4.37.7/arch/i386/mm/ioremap.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/mm/ioremap.c 2009-11-10 19:30:27.000000000 -0500 @@ -49,7 +49,7 @@ static inline int remap_area_pmd(pmd_t * if (address >= end) BUG(); do { - pte_t * pte = pte_alloc(&init_mm, pmd, address); + pte_t * pte = pte_alloc_kernel(&init_mm, pmd, address); if (!pte) return -ENOMEM; remap_area_pte(pte, address, end - address, address + phys_addr, flags); diff -urNp linux-2.4.37.7/arch/i386/mm/pageattr.c linux-2.4.37.7/arch/i386/mm/pageattr.c --- linux-2.4.37.7/arch/i386/mm/pageattr.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/mm/pageattr.c 2009-11-10 19:30:27.000000000 -0500 @@ -10,6 +10,7 @@ #include #include #include +#include /* Should move most of this stuff into the appropiate includes */ #define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1)) @@ -63,7 +64,19 @@ static void flush_kernel_map(void * addr static void set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) { + +#ifdef CONFIG_PAX_KERNEXEC + unsigned long cr0; + + pax_open_kernel(cr0); +#endif + set_pte_atomic(kpte, pte); /* change init_mm */ + +#ifdef CONFIG_PAX_KERNEXEC + pax_close_kernel(cr0); +#endif + #ifndef CONFIG_X86_PAE { struct list_head *l; diff -urNp linux-2.4.37.7/arch/i386/vmlinux.lds linux-2.4.37.7/arch/i386/vmlinux.lds --- linux-2.4.37.7/arch/i386/vmlinux.lds 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/i386/vmlinux.lds 1969-12-31 19:00:00.000000000 -0500 @@ -1,82 +0,0 @@ -/* ld script to make i386 Linux kernel - * Written by Martin Mares ; - */ -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") -OUTPUT_ARCH(i386) -ENTRY(_start) -SECTIONS -{ - . = 0xC0000000 + 0x100000; - _text = .; /* Text and read-only data */ - .text : { - *(.text) - *(.fixup) - *(.gnu.warning) - } = 0x9090 - - _etext = .; /* End of text section */ - - .rodata : { *(.rodata) *(.rodata.*) } - .kstrtab : { *(.kstrtab) } - - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; - __ex_table : { *(__ex_table) } - __stop___ex_table = .; - - __start___ksymtab = .; /* Kernel symbol table */ - __ksymtab : { *(__ksymtab) } - __stop___ksymtab = .; - - .data : { /* Data */ - *(.data) - CONSTRUCTORS - } - - _edata = .; /* End of data section */ - - . = ALIGN(8192); /* init_task */ - .data.init_task : { *(.data.init_task) } - - . = ALIGN(4096); /* Init code and data */ - __init_begin = .; - .text.init : { *(.text.init) } - .data.init : { *(.data.init) } - . = ALIGN(16); - __setup_start = .; - .setup.init : { *(.setup.init) } - __setup_end = .; - __initcall_start = .; - .initcall.init : { *(.initcall.init) } - __initcall_end = .; - . = ALIGN(4096); - __init_end = .; - - . = ALIGN(4096); - .data.page_aligned : { *(.data.idt) } - - . = ALIGN(32); - .data.cacheline_aligned : { *(.data.cacheline_aligned) } - - __bss_start = .; /* BSS */ - .bss : { - *(.bss) - } - _end = . ; - - /* Sections to be discarded */ - /DISCARD/ : { - *(.text.exit) - *(.data.exit) - *(.exitcall.exit) - } - - /* Stabs debugging sections. */ - .stab 0 : { *(.stab) } - .stabstr 0 : { *(.stabstr) } - .stab.excl 0 : { *(.stab.excl) } - .stab.exclstr 0 : { *(.stab.exclstr) } - .stab.index 0 : { *(.stab.index) } - .stab.indexstr 0 : { *(.stab.indexstr) } - .comment 0 : { *(.comment) } -} diff -urNp linux-2.4.37.7/arch/i386/vmlinux.lds.S linux-2.4.37.7/arch/i386/vmlinux.lds.S --- linux-2.4.37.7/arch/i386/vmlinux.lds.S 1969-12-31 19:00:00.000000000 -0500 +++ linux-2.4.37.7/arch/i386/vmlinux.lds.S 2009-11-10 19:30:27.000000000 -0500 @@ -0,0 +1,140 @@ +/* ld script to make i386 Linux kernel + * Written by Martin Mares ; + */ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) + +PHDRS { + initdata PT_LOAD FLAGS(6); /* RW_ */ + inittext PT_LOAD FLAGS(5); /* R_E */ + text PT_LOAD FLAGS(5); /* R_E */ + rodata PT_LOAD FLAGS(4); /* R__ */ + data PT_LOAD FLAGS(6); /* RW_ */ +} +SECTIONS +{ + . = __PAGE_OFFSET + 0x100000; + .text.startup : { + BYTE(0xEA) /* jmp far */ + LONG(startup_32 + __KERNEL_TEXT_OFFSET - __PAGE_OFFSET) + SHORT(__KERNEL_CS) + } :initdata + + . = ALIGN(4096); /* Init code and data */ + __init_begin = .; + .data.init : { *(.data.init) } + . = ALIGN(16); + __setup_start = .; + .setup.init : { *(.setup.init) } + __setup_end = .; + __initcall_start = .; + .initcall.init : { *(.initcall.init) } + __initcall_end = .; + + _sinittext = . - __KERNEL_TEXT_OFFSET; + +#ifdef CONFIG_PAX_KERNEXEC + .text.init (. - __KERNEL_TEXT_OFFSET) : AT (_sinittext + __KERNEL_TEXT_OFFSET) { + *(.text.init) + _einittext = .; + . = ALIGN(4*1024*1024) - 1; + BYTE(0) + } :inittext + __init_end = . + __KERNEL_TEXT_OFFSET; + +/* + * PaX: this must be kept in synch with the KERNEL_CS base + * in the GDTs in arch/i386/kernel/head.S + */ + _text = .; /* Text and read-only data */ + .text : AT (. + __KERNEL_TEXT_OFFSET) { +#else + .text.init : { *(.text.init) } :inittext + _einittext = .; + . = ALIGN(4096); + __init_end = .; + _text = .; /* Text and read-only data */ + .text : { +#endif + + *(.text) + *(.fixup) + *(.gnu.warning) + } :text = 0x9090 + + _etext = .; /* End of text section */ + + . = ALIGN(4096); + . += __KERNEL_TEXT_OFFSET; + .rodata.page_aligned : { + *(.empty_zero_page) + *(.pg0) + +#ifdef CONFIG_X86_PAE + *(.swapper_pm_dir) +#endif + + *(.swapper_pg_dir) + *(.idt) + } :rodata + .rodata : { *(.rodata) *(.rodata.*) } + .kstrtab : { *(.kstrtab) } + + . = ALIGN(16); /* Exception table */ + __start___ex_table = .; + __ex_table : { *(__ex_table) } + __stop___ex_table = .; + + __start___ksymtab = .; /* Kernel symbol table */ + __ksymtab : { *(__ksymtab) } + __stop___ksymtab = .; + +#ifdef CONFIG_PAX_KERNEXEC + . = ALIGN(4*1024*1024); +#else + . = ALIGN(32); +#endif + + _data = .; + .data : { /* Data */ + *(.data) + CONSTRUCTORS + } :data + + . = ALIGN(32); + .data.cacheline_aligned : { *(.data.cacheline_aligned) } + + . = ALIGN(8192); + .data.init_task : { *(.data.init_task) } + + . = ALIGN(4096); + .data.page_aligned : { + } + + _edata = .; /* End of data section */ + + __bss_start = .; /* BSS */ + .bss : { + *(.bss) + } + __bss_end = . ; + + _end = . ; + + /* Sections to be discarded */ + /DISCARD/ : { + *(.text.exit) + *(.data.exit) + *(.exitcall.exit) + } + + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +} diff -urNp linux-2.4.37.7/arch/ia64/config.in linux-2.4.37.7/arch/ia64/config.in --- linux-2.4.37.7/arch/ia64/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -319,3 +319,12 @@ fi int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 endmenu + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu + diff -urNp linux-2.4.37.7/arch/ia64/hp/common/sba_iommu.c linux-2.4.37.7/arch/ia64/hp/common/sba_iommu.c --- linux-2.4.37.7/arch/ia64/hp/common/sba_iommu.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/hp/common/sba_iommu.c 2009-11-10 19:30:27.000000000 -0500 @@ -1704,7 +1704,7 @@ ioc_show(struct seq_file *s, void *v) return 0; } -static struct seq_operations ioc_seq_ops = { +static const struct seq_operations ioc_seq_ops = { .start = ioc_start, .next = ioc_next, .stop = ioc_stop, @@ -1717,7 +1717,7 @@ ioc_open(struct inode *inode, struct fil return seq_open(file, &ioc_seq_ops); } -static struct file_operations ioc_fops = { +static const struct file_operations ioc_fops = { .open = ioc_open, .read = seq_read, .llseek = seq_lseek, diff -urNp linux-2.4.37.7/arch/ia64/ia32/binfmt_elf32.c linux-2.4.37.7/arch/ia64/ia32/binfmt_elf32.c --- linux-2.4.37.7/arch/ia64/ia32/binfmt_elf32.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/ia32/binfmt_elf32.c 2009-11-10 19:30:27.000000000 -0500 @@ -53,6 +53,13 @@ static void elf32_set_personality (void) #undef SET_PERSONALITY #define SET_PERSONALITY(ex, ibcs2) elf32_set_personality() +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE (current->personality == PER_LINUX32 ? 0x08048000UL : 0x4000000000000000UL) + +#define PAX_DELTA_MMAP_LEN (current->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT) +#define PAX_DELTA_STACK_LEN (current->personality == PER_LINUX32 ? 16 : 43 - IA32_PAGE_SHIFT) +#endif + /* Ugly but avoids duplication */ #include "../../../fs/binfmt_elf.c" @@ -68,7 +75,7 @@ ia32_install_shared_page (struct vm_area return pg; } -static struct vm_operations_struct ia32_shared_page_vm_ops = { +static const struct vm_operations_struct ia32_shared_page_vm_ops = { .nopage =ia32_install_shared_page }; @@ -190,8 +197,15 @@ ia32_setup_arg_pages (struct linux_binpr mpnt->vm_mm = current->mm; mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p; mpnt->vm_end = IA32_STACK_TOP; - mpnt->vm_page_prot = PAGE_COPY; mpnt->vm_flags = VM_STACK_FLAGS; + +#ifdef CONFIG_PAX_PAGEEXEC + if (!(current->mm->pax_flags & MF_PAX_PAGEEXEC)) + mpnt->vm_page_prot = protection_map[(VM_STACK_FLAGS | VM_EXEC) & 0x7]; + else +#endif + + mpnt->vm_page_prot = protection_map[VM_STACK_FLAGS & 0x7]; mpnt->vm_ops = NULL; mpnt->vm_pgoff = 0; mpnt->vm_file = NULL; diff -urNp linux-2.4.37.7/arch/ia64/ia32/sys_ia32.c linux-2.4.37.7/arch/ia64/ia32/sys_ia32.c --- linux-2.4.37.7/arch/ia64/ia32/sys_ia32.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/ia32/sys_ia32.c 2009-11-10 19:30:27.000000000 -0500 @@ -538,7 +538,6 @@ sys32_mmap (struct mmap_arg_struct *arg) return -EINVAL; flags = a.flags; - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); if (!(flags & MAP_ANONYMOUS)) { file = fget(a.fd); diff -urNp linux-2.4.37.7/arch/ia64/kernel/efivars.c linux-2.4.37.7/arch/ia64/kernel/efivars.c --- linux-2.4.37.7/arch/ia64/kernel/efivars.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/kernel/efivars.c 2009-11-10 19:30:27.000000000 -0500 @@ -412,7 +412,7 @@ out: } static struct proc_dir_entry *efi_systab_entry; -static struct file_operations efi_systab_fops = { +static const struct file_operations efi_systab_fops = { .read = efi_systab_read, }; diff -urNp linux-2.4.37.7/arch/ia64/kernel/perfmon.c linux-2.4.37.7/arch/ia64/kernel/perfmon.c --- linux-2.4.37.7/arch/ia64/kernel/perfmon.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/kernel/perfmon.c 2009-11-10 19:30:27.000000000 -0500 @@ -3261,7 +3261,7 @@ pfm_proc_show(struct seq_file *m, void * return 0; } -struct seq_operations pfm_seq_ops = { +const struct seq_operations pfm_seq_ops = { .start = pfm_proc_start, .next = pfm_proc_next, .stop = pfm_proc_stop, @@ -4500,7 +4500,7 @@ pfm_remove_alternate_syswide_subsystem(p return 0; } -static struct file_operations pfm_proc_fops = { +static const struct file_operations pfm_proc_fops = { .open = pfm_proc_open, .read = seq_read, .llseek = seq_lseek, diff -urNp linux-2.4.37.7/arch/ia64/kernel/ptrace.c linux-2.4.37.7/arch/ia64/kernel/ptrace.c --- linux-2.4.37.7/arch/ia64/kernel/ptrace.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/kernel/ptrace.c 2009-11-10 19:30:27.000000000 -0500 @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -1299,6 +1300,9 @@ sys_ptrace (long request, pid_t pid, uns if (pid == 1) /* no messing around with init! */ goto out_tsk; + if (gr_handle_ptrace(child, request)) + goto out_tsk; + if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); goto out_tsk; diff -urNp linux-2.4.37.7/arch/ia64/kernel/salinfo.c linux-2.4.37.7/arch/ia64/kernel/salinfo.c --- linux-2.4.37.7/arch/ia64/kernel/salinfo.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/kernel/salinfo.c 2009-11-10 19:30:27.000000000 -0500 @@ -338,7 +338,7 @@ retry: return size; } -static struct file_operations salinfo_event_fops = { +static const struct file_operations salinfo_event_fops = { .open = salinfo_event_open, .read = salinfo_event_read, }; @@ -558,7 +558,7 @@ salinfo_log_write(struct file *file, con return count; } -static struct file_operations salinfo_data_fops = { +static const struct file_operations salinfo_data_fops = { .open = salinfo_log_open, .release = salinfo_log_release, .read = salinfo_log_read, diff -urNp linux-2.4.37.7/arch/ia64/kernel/setup.c linux-2.4.37.7/arch/ia64/kernel/setup.c --- linux-2.4.37.7/arch/ia64/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -566,7 +566,7 @@ c_stop (struct seq_file *m, void *v) { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { .start =c_start, .next = c_next, .stop = c_stop, diff -urNp linux-2.4.37.7/arch/ia64/kernel/sys_ia64.c linux-2.4.37.7/arch/ia64/kernel/sys_ia64.c --- linux-2.4.37.7/arch/ia64/kernel/sys_ia64.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/kernel/sys_ia64.c 2009-11-10 19:30:27.000000000 -0500 @@ -34,6 +34,13 @@ arch_get_unmapped_area (struct file *fil if (rgn_index(addr)==REGION_HPAGE) addr = 0; #endif + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; + else +#endif + if (!addr) addr = TASK_UNMAPPED_BASE; diff -urNp linux-2.4.37.7/arch/ia64/mm/fault.c linux-2.4.37.7/arch/ia64/mm/fault.c --- linux-2.4.37.7/arch/ia64/mm/fault.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/mm/fault.c 2009-11-10 19:30:27.000000000 -0500 @@ -36,6 +36,10 @@ expand_backing_store (struct vm_area_str if (address - vma->vm_start > current->rlim[RLIMIT_STACK].rlim_cur || (((vma->vm_mm->total_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_AS].rlim_cur)) return -ENOMEM; + if ((vma->vm_flags & VM_LOCKED) && + ((vma->vm_mm->locked_vm + grow) << PAGE_SHIFT) > current->rlim[RLIMIT_MEMLOCK].rlim_cur && + !capable(CAP_IPC_LOCK)) + return -ENOMEM; vma->vm_end += PAGE_SIZE; vma->vm_mm->total_vm += grow; if (vma->vm_flags & VM_LOCKED) @@ -70,6 +74,23 @@ mapped_kernel_page_is_present (unsigned return pte_present(pte); } +#ifdef CONFIG_PAX_PAGEEXEC +void pax_report_insns(void *pc, void *sp) +{ + unsigned long i; + + printk(KERN_ERR "PAX: bytes at PC: "); + for (i = 0; i < 8; i++) { + unsigned int c; + if (get_user(c, (unsigned int*)pc+i)) + printk("???????? "); + else + printk("%08x ", c); + } + printk("\n"); +} +#endif + void ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs) { @@ -122,9 +143,23 @@ ia64_do_page_fault (unsigned long addres | (((isr >> IA64_ISR_W_BIT) & 1UL) << VM_WRITE_BIT) | (((isr >> IA64_ISR_R_BIT) & 1UL) << VM_READ_BIT)); - if ((vma->vm_flags & mask) != mask) + if ((vma->vm_flags & mask) != mask) { + +#ifdef CONFIG_PAX_PAGEEXEC + if (!(vma->vm_flags & VM_EXEC) && (mask & VM_EXEC)) { + if (!(mm->pax_flags & MF_PAX_PAGEEXEC) || address != regs->cr_iip) + goto bad_area; + + up_read(&mm->mmap_sem); + pax_report_fault(regs, (void*)regs->cr_iip, (void*)regs->r12); + do_exit(SIGKILL); + } +#endif + goto bad_area; + } + survive: /* * If for any reason at all we couldn't handle the fault, make diff -urNp linux-2.4.37.7/arch/ia64/mm/hugetlbpage.c linux-2.4.37.7/arch/ia64/mm/hugetlbpage.c --- linux-2.4.37.7/arch/ia64/mm/hugetlbpage.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/mm/hugetlbpage.c 2009-11-10 19:30:27.000000000 -0500 @@ -24,7 +24,7 @@ static long htlbpagemem; int htlbpage_max; static long htlbzone_pages; -struct vm_operations_struct hugetlb_vm_ops; +const struct vm_operations_struct hugetlb_vm_ops; static LIST_HEAD(htlbpage_freelist); static spinlock_t htlbpage_lock = SPIN_LOCK_UNLOCKED; @@ -512,6 +512,6 @@ static struct page *hugetlb_nopage(struc return NULL; } -struct vm_operations_struct hugetlb_vm_ops = { +const struct vm_operations_struct hugetlb_vm_ops = { .nopage = hugetlb_nopage, }; diff -urNp linux-2.4.37.7/arch/ia64/mm/init.c linux-2.4.37.7/arch/ia64/mm/init.c --- linux-2.4.37.7/arch/ia64/mm/init.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/mm/init.c 2009-11-10 19:30:27.000000000 -0500 @@ -73,7 +73,7 @@ ia64_set_rbs_bot (void) if (stack_size > MAX_USER_STACK_SIZE) stack_size = MAX_USER_STACK_SIZE; - current->thread.rbs_bot = STACK_TOP - stack_size; + current->thread.rbs_bot = PAGE_ALIGN(current->mm->start_stack - stack_size); } /* @@ -105,6 +105,7 @@ ia64_init_addr_space (void) vma->vm_pgoff = 0; vma->vm_file = NULL; vma->vm_private_data = NULL; + vma->vm_mirror = 0; down_write(¤t->mm->mmap_sem); if (insert_vm_struct(current->mm, vma)) { up_write(¤t->mm->mmap_sem); diff -urNp linux-2.4.37.7/arch/ia64/sn/io/drivers/ifconfig_net.c linux-2.4.37.7/arch/ia64/sn/io/drivers/ifconfig_net.c --- linux-2.4.37.7/arch/ia64/sn/io/drivers/ifconfig_net.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/sn/io/drivers/ifconfig_net.c 2009-11-10 19:30:27.000000000 -0500 @@ -277,7 +277,7 @@ static int ifconfig_net_ioctl(struct ino } -struct file_operations ifconfig_net_fops = { +const struct file_operations ifconfig_net_fops = { ioctl:ifconfig_net_ioctl, /* ioctl */ open:ifconfig_net_open, /* open */ release:ifconfig_net_close /* release */ diff -urNp linux-2.4.37.7/arch/ia64/sn/io/drivers/ioconfig_bus.c linux-2.4.37.7/arch/ia64/sn/io/drivers/ioconfig_bus.c --- linux-2.4.37.7/arch/ia64/sn/io/drivers/ioconfig_bus.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/sn/io/drivers/ioconfig_bus.c 2009-11-10 19:30:27.000000000 -0500 @@ -359,7 +359,7 @@ static int ioconfig_bus_close(struct ino return(0); } -struct file_operations ioconfig_bus_fops = { +const struct file_operations ioconfig_bus_fops = { ioctl:ioconfig_bus_ioctl, open:ioconfig_bus_open, /* open */ release:ioconfig_bus_close /* release */ diff -urNp linux-2.4.37.7/arch/ia64/sn/io/drivers/pciba.c linux-2.4.37.7/arch/ia64/sn/io/drivers/pciba.c --- linux-2.4.37.7/arch/ia64/sn/io/drivers/pciba.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/sn/io/drivers/pciba.c 2009-11-10 19:30:27.000000000 -0500 @@ -211,7 +211,7 @@ static void dump_allocations(struct list #endif /* file operations for each type of node */ -static struct file_operations rom_fops = { +static const struct file_operations rom_fops = { owner: THIS_MODULE, mmap: rom_mmap, open: generic_open, @@ -219,20 +219,20 @@ static struct file_operations rom_fops = }; -static struct file_operations base_fops = { +static const struct file_operations base_fops = { owner: THIS_MODULE, mmap: base_mmap, open: generic_open }; -static struct file_operations config_fops = { +static const struct file_operations config_fops = { owner: THIS_MODULE, ioctl: config_ioctl, open: generic_open }; -static struct file_operations dma_fops = { +static const struct file_operations dma_fops = { owner: THIS_MODULE, ioctl: dma_ioctl, mmap: dma_mmap, diff -urNp linux-2.4.37.7/arch/ia64/sn/io/hwgdfs/hcl.c linux-2.4.37.7/arch/ia64/sn/io/hwgdfs/hcl.c --- linux-2.4.37.7/arch/ia64/sn/io/hwgdfs/hcl.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/sn/io/hwgdfs/hcl.c 2009-11-10 19:30:27.000000000 -0500 @@ -106,7 +106,7 @@ static int hcl_ioctl(struct inode * inod } -struct file_operations hcl_fops = { +const struct file_operations hcl_fops = { (struct module *)0, NULL, /* lseek - default */ NULL, /* read - general block-dev read */ diff -urNp linux-2.4.37.7/arch/ia64/sn/io/hwgfs/hcl.c linux-2.4.37.7/arch/ia64/sn/io/hwgfs/hcl.c --- linux-2.4.37.7/arch/ia64/sn/io/hwgfs/hcl.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/sn/io/hwgfs/hcl.c 2009-11-10 19:30:27.000000000 -0500 @@ -108,7 +108,7 @@ static int hcl_ioctl(struct inode * inod } -struct file_operations hcl_fops = { +const struct file_operations hcl_fops = { (struct module *)0, NULL, /* lseek - default */ NULL, /* read - general block-dev read */ diff -urNp linux-2.4.37.7/arch/ia64/sn/io/hwgfs/ramfs.c linux-2.4.37.7/arch/ia64/sn/io/hwgfs/ramfs.c --- linux-2.4.37.7/arch/ia64/sn/io/hwgfs/ramfs.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/sn/io/hwgfs/ramfs.c 2009-11-10 19:30:27.000000000 -0500 @@ -18,10 +18,10 @@ /* some random number */ #define HWGFS_MAGIC 0x12061983 -static struct super_operations hwgfs_ops; -static struct address_space_operations hwgfs_aops; -static struct file_operations hwgfs_file_operations; -static struct inode_operations hwgfs_dir_inode_operations; +static const struct super_operations hwgfs_ops; +static const struct address_space_operations hwgfs_aops; +static const struct file_operations hwgfs_file_operations; +static const struct inode_operations hwgfs_dir_inode_operations; static int hwgfs_statfs(struct super_block *sb, struct statfs *buf) { @@ -247,21 +247,21 @@ static int hwgfs_sync_file(struct file * return 0; } -static struct address_space_operations hwgfs_aops = { +static const struct address_space_operations hwgfs_aops = { .readpage = hwgfs_readpage, .writepage = fail_writepage, .prepare_write = hwgfs_prepare_write, .commit_write = hwgfs_commit_write }; -static struct file_operations hwgfs_file_operations = { +static const struct file_operations hwgfs_file_operations = { .read = generic_file_read, .write = generic_file_write, .mmap = generic_file_mmap, .fsync = hwgfs_sync_file, }; -static struct inode_operations hwgfs_dir_inode_operations = { +static const struct inode_operations hwgfs_dir_inode_operations = { .create = hwgfs_create, .lookup = hwgfs_lookup, .link = hwgfs_link, @@ -273,7 +273,7 @@ static struct inode_operations hwgfs_dir .rename = hwgfs_rename, }; -static struct super_operations hwgfs_ops = { +static const struct super_operations hwgfs_ops = { .statfs = hwgfs_statfs, .put_inode = force_delete, }; diff -urNp linux-2.4.37.7/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c linux-2.4.37.7/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c --- linux-2.4.37.7/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c 2009-11-10 19:30:27.000000000 -0500 @@ -577,7 +577,7 @@ pcibr_mmap(struct file * file, struct vm * appropriate function name below. */ static int pcibr_mmap(struct file * file, struct vm_area_struct * vma); -struct file_operations pcibr_fops = { +const struct file_operations pcibr_fops = { .owner = THIS_MODULE, .mmap = pcibr_mmap, }; diff -urNp linux-2.4.37.7/arch/ia64/sn/io/sn2/shub.c linux-2.4.37.7/arch/ia64/sn/io/sn2/shub.c --- linux-2.4.37.7/arch/ia64/sn/io/sn2/shub.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/sn/io/sn2/shub.c 2009-11-10 19:30:27.000000000 -0500 @@ -223,7 +223,7 @@ shubstats_ioctl(struct inode *inode, str return 0; } -struct file_operations shub_mon_fops = { +const struct file_operations shub_mon_fops = { ioctl: shubstats_ioctl, }; diff -urNp linux-2.4.37.7/arch/ia64/sn/io/sn2/xbow.c linux-2.4.37.7/arch/ia64/sn/io/sn2/xbow.c --- linux-2.4.37.7/arch/ia64/sn/io/sn2/xbow.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ia64/sn/io/sn2/xbow.c 2009-11-10 19:30:27.000000000 -0500 @@ -141,7 +141,7 @@ xbow_mmap(struct file * file, struct vm_ * As each of the functions are implemented, put the * appropriate function name below. */ -struct file_operations xbow_fops = { +const struct file_operations xbow_fops = { .owner = THIS_MODULE, .mmap = xbow_mmap, }; diff -urNp linux-2.4.37.7/arch/m68k/atari/joystick.c linux-2.4.37.7/arch/m68k/atari/joystick.c --- linux-2.4.37.7/arch/m68k/atari/joystick.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/m68k/atari/joystick.c 2009-11-10 19:30:27.000000000 -0500 @@ -121,7 +121,7 @@ static unsigned int joystick_poll(struct return 0; } -struct file_operations atari_joystick_fops = { +const struct file_operations atari_joystick_fops = { read: read_joystick, write: write_joystick, poll: joystick_poll, diff -urNp linux-2.4.37.7/arch/m68k/bvme6000/rtc.c linux-2.4.37.7/arch/m68k/bvme6000/rtc.c --- linux-2.4.37.7/arch/m68k/bvme6000/rtc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/m68k/bvme6000/rtc.c 2009-11-10 19:30:27.000000000 -0500 @@ -161,7 +161,7 @@ static int rtc_release(struct inode *ino * The various file operations we support. */ -static struct file_operations rtc_fops = { +static const struct file_operations rtc_fops = { ioctl: rtc_ioctl, open: rtc_open, release: rtc_release, diff -urNp linux-2.4.37.7/arch/m68k/config.in linux-2.4.37.7/arch/m68k/config.in --- linux-2.4.37.7/arch/m68k/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/m68k/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -558,3 +558,11 @@ endmenu source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urNp linux-2.4.37.7/arch/m68k/kernel/setup.c linux-2.4.37.7/arch/m68k/kernel/setup.c --- linux-2.4.37.7/arch/m68k/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/m68k/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -531,7 +531,7 @@ static void *c_next(struct seq_file *m, static void c_stop(struct seq_file *m, void *v) { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { start: c_start, next: c_next, stop: c_stop, diff -urNp linux-2.4.37.7/arch/m68k/mvme16x/rtc.c linux-2.4.37.7/arch/m68k/mvme16x/rtc.c --- linux-2.4.37.7/arch/m68k/mvme16x/rtc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/m68k/mvme16x/rtc.c 2009-11-10 19:30:27.000000000 -0500 @@ -150,7 +150,7 @@ static int rtc_release(struct inode *ino * The various file operations we support. */ -static struct file_operations rtc_fops = { +static const struct file_operations rtc_fops = { ioctl: rtc_ioctl, open: rtc_open, release: rtc_release, diff -urNp linux-2.4.37.7/arch/mips/config.in linux-2.4.37.7/arch/mips/config.in --- linux-2.4.37.7/arch/mips/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/mips/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -7,3 +7,11 @@ define_bool CONFIG_MIPS32 y define_bool CONFIG_MIPS64 n source arch/mips/config-shared.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urNp linux-2.4.37.7/arch/mips/kernel/proc.c linux-2.4.37.7/arch/mips/kernel/proc.c --- linux-2.4.37.7/arch/mips/kernel/proc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/mips/kernel/proc.c 2009-11-10 19:30:27.000000000 -0500 @@ -143,7 +143,7 @@ static void c_stop(struct seq_file *m, v { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { .start = c_start, .next = c_next, .stop = c_stop, diff -urNp linux-2.4.37.7/arch/mips/kernel/syscall.c linux-2.4.37.7/arch/mips/kernel/syscall.c --- linux-2.4.37.7/arch/mips/kernel/syscall.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/mips/kernel/syscall.c 2009-11-10 19:30:27.000000000 -0500 @@ -82,6 +82,11 @@ unsigned long arch_get_unmapped_area(str do_color_align = 0; if (filp || (flags & MAP_SHARED)) do_color_align = 1; + +#ifdef CONFIG_PAX_RANDMMAP + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp) +#endif + if (addr) { if (do_color_align) addr = COLOUR_ALIGN(addr, pgoff); @@ -92,6 +97,13 @@ unsigned long arch_get_unmapped_area(str (!vmm || addr + len <= vmm->vm_start)) return addr; } + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; + else +#endif + addr = TASK_UNMAPPED_BASE; if (do_color_align) addr = COLOUR_ALIGN(addr, pgoff); diff -urNp linux-2.4.37.7/arch/mips/mm/fault.c linux-2.4.37.7/arch/mips/mm/fault.c --- linux-2.4.37.7/arch/mips/mm/fault.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/mips/mm/fault.c 2009-11-10 19:30:27.000000000 -0500 @@ -69,6 +69,23 @@ void bust_spinlocks(int yes) } } +#ifdef CONFIG_PAX_PAGEEXEC +void pax_report_insns(void *pc, void *sp) +{ + unsigned long i; + + printk(KERN_ERR "PAX: bytes at PC: "); + for (i = 0; i < 5; i++) { + unsigned int c; + if (get_user(c, (unsigned int*)pc+i)) + printk("???????? "); + else + printk("%08x ", c); + } + printk("\n"); +} +#endif + /* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate diff -urNp linux-2.4.37.7/arch/mips/sibyte/sb1250/bcm1250_tbprof.c linux-2.4.37.7/arch/mips/sibyte/sb1250/bcm1250_tbprof.c --- linux-2.4.37.7/arch/mips/sibyte/sb1250/bcm1250_tbprof.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/mips/sibyte/sb1250/bcm1250_tbprof.c 2009-11-10 19:30:27.000000000 -0500 @@ -356,7 +356,7 @@ static int sbprof_tb_ioctl(struct inode return error; } -static struct file_operations sbprof_tb_fops = { +static const struct file_operations sbprof_tb_fops = { .owner = THIS_MODULE, .open = sbprof_tb_open, .release = sbprof_tb_release, diff -urNp linux-2.4.37.7/arch/mips64/config.in linux-2.4.37.7/arch/mips64/config.in --- linux-2.4.37.7/arch/mips64/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/mips64/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -7,3 +7,11 @@ define_bool CONFIG_MIPS32 n define_bool CONFIG_MIPS64 y source arch/mips/config-shared.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urNp linux-2.4.37.7/arch/mips64/kernel/binfmt_elfn32.c linux-2.4.37.7/arch/mips64/kernel/binfmt_elfn32.c --- linux-2.4.37.7/arch/mips64/kernel/binfmt_elfn32.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/mips64/kernel/binfmt_elfn32.c 2009-11-10 19:30:27.000000000 -0500 @@ -50,6 +50,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N #undef ELF_ET_DYN_BASE #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL) + +#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) +#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) +#endif + #include #include #include diff -urNp linux-2.4.37.7/arch/mips64/kernel/binfmt_elfo32.c linux-2.4.37.7/arch/mips64/kernel/binfmt_elfo32.c --- linux-2.4.37.7/arch/mips64/kernel/binfmt_elfo32.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/mips64/kernel/binfmt_elfo32.c 2009-11-10 19:30:27.000000000 -0500 @@ -52,6 +52,13 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_N #undef ELF_ET_DYN_BASE #define ELF_ET_DYN_BASE (TASK32_SIZE / 3 * 2) +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE ((current->thread.mflags & MF_32BIT_ADDR) ? 0x00400000UL : 0x00400000UL) + +#define PAX_DELTA_MMAP_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) +#define PAX_DELTA_STACK_LEN ((current->thread.mflags & MF_32BIT_ADDR) ? 27-PAGE_SHIFT : 36-PAGE_SHIFT) +#endif + #include #include #include diff -urNp linux-2.4.37.7/arch/mips64/kernel/proc.c linux-2.4.37.7/arch/mips64/kernel/proc.c --- linux-2.4.37.7/arch/mips64/kernel/proc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/mips64/kernel/proc.c 2009-11-10 19:30:27.000000000 -0500 @@ -143,7 +143,7 @@ static void c_stop(struct seq_file *m, v { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { .start = c_start, .next = c_next, .stop = c_stop, diff -urNp linux-2.4.37.7/arch/mips64/kernel/syscall.c linux-2.4.37.7/arch/mips64/kernel/syscall.c --- linux-2.4.37.7/arch/mips64/kernel/syscall.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/mips64/kernel/syscall.c 2009-11-10 19:30:27.000000000 -0500 @@ -80,6 +80,11 @@ unsigned long arch_get_unmapped_area(str do_color_align = 0; if (filp || (flags & MAP_SHARED)) do_color_align = 1; + +#ifdef CONFIG_PAX_RANDMMAP + if (!(current->mm->pax_flags & MF_PAX_RANDMMAP) || !filp) +#endif + if (addr) { if (do_color_align) addr = COLOUR_ALIGN(addr, pgoff); @@ -90,6 +95,13 @@ unsigned long arch_get_unmapped_area(str (!vmm || addr + len <= vmm->vm_start)) return addr; } + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; + else +#endif + addr = TASK_UNMAPPED_BASE; if (do_color_align) addr = COLOUR_ALIGN(addr, pgoff); diff -urNp linux-2.4.37.7/arch/mips64/mm/fault.c linux-2.4.37.7/arch/mips64/mm/fault.c --- linux-2.4.37.7/arch/mips64/mm/fault.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/mips64/mm/fault.c 2009-11-10 19:30:27.000000000 -0500 @@ -90,6 +90,24 @@ void bust_spinlocks(int yes) } } +#ifdef CONFIG_PAX_PAGEEXEC +void pax_report_insns(void *pc, void *sp) +{ + unsigned long i; + + printk(KERN_ERR "PAX: bytes at PC: "); + for (i = 0; i < 5; i++) { + unsigned int c; + if (get_user(c, (unsigned int*)pc+i)) { + printk("."); + break; + } + printk("%08x ", c); + } + printk("\n"); +} +#endif + /* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate diff -urNp linux-2.4.37.7/arch/parisc/config.in linux-2.4.37.7/arch/parisc/config.in --- linux-2.4.37.7/arch/parisc/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/parisc/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -204,3 +204,11 @@ endmenu source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urNp linux-2.4.37.7/arch/parisc/kernel/ioctl32.c linux-2.4.37.7/arch/parisc/kernel/ioctl32.c --- linux-2.4.37.7/arch/parisc/kernel/ioctl32.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/parisc/kernel/ioctl32.c 2009-11-10 19:30:27.000000000 -0500 @@ -1435,7 +1435,11 @@ static int vt_check(struct file *file) * To have permissions to do most of the vt ioctls, we either have * to be the owner of the tty, or super-user. */ +#ifdef CONFIG_GRKERNSEC + if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG)) +#else if (current->tty == tty || suser()) +#endif return 1; return 0; } diff -urNp linux-2.4.37.7/arch/parisc/kernel/perf.c linux-2.4.37.7/arch/parisc/kernel/perf.c --- linux-2.4.37.7/arch/parisc/kernel/perf.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/parisc/kernel/perf.c 2009-11-10 19:30:27.000000000 -0500 @@ -479,7 +479,7 @@ static int perf_ioctl(struct inode *inod return -ENOTTY; } -static struct file_operations perf_fops = { +static const struct file_operations perf_fops = { llseek: no_llseek, read: perf_read, write: perf_write, diff -urNp linux-2.4.37.7/arch/parisc/kernel/ptrace.c linux-2.4.37.7/arch/parisc/kernel/ptrace.c --- linux-2.4.37.7/arch/parisc/kernel/ptrace.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/parisc/kernel/ptrace.c 2009-11-10 19:30:27.000000000 -0500 @@ -15,7 +15,7 @@ #include #include #include - +#include #include #include #include @@ -119,6 +119,9 @@ long sys_ptrace(long request, pid_t pid, if (pid == 1) /* no messing around with init! */ goto out_tsk; + if (gr_handle_ptrace(child, request)) + goto out_tsk; + if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); goto out_tsk; diff -urNp linux-2.4.37.7/arch/parisc/kernel/setup.c linux-2.4.37.7/arch/parisc/kernel/setup.c --- linux-2.4.37.7/arch/parisc/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/parisc/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -180,7 +180,7 @@ c_stop (struct seq_file *m, void *v) { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { start: c_start, next: c_next, stop: c_stop, diff -urNp linux-2.4.37.7/arch/parisc/kernel/sys_parisc32.c linux-2.4.37.7/arch/parisc/kernel/sys_parisc32.c --- linux-2.4.37.7/arch/parisc/kernel/sys_parisc32.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/parisc/kernel/sys_parisc32.c 2009-11-10 19:30:27.000000000 -0500 @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -177,6 +178,11 @@ do_execve32(char * filename, u32 * argv, struct file *file; int retval; int i; +#ifdef CONFIG_GRKERNSEC + struct file *old_exec_file; + struct acl_subject_label *old_acl; + struct rlimit old_rlim[RLIM_NLIMITS]; +#endif file = open_exec(filename); @@ -184,7 +190,26 @@ do_execve32(char * filename, u32 * argv, if (IS_ERR(file)) return retval; + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1); + + if (gr_handle_nproc()) { + allow_write_access(file); + fput(file); + return -EAGAIN; + } + + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) { + allow_write_access(file); + fput(file); + return -EACCES; + } + bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); + +#ifdef CONFIG_PAX_RANDUSTACK + bprm.p -= (net_random() & ~(sizeof(void *)-1)) & ~PAGE_MASK; +#endif + memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); DBG(("do_execve32(%s, %p, %p, %p)\n", filename, argv, envp, regs)); @@ -209,11 +234,24 @@ do_execve32(char * filename, u32 * argv, if (retval < 0) goto out; + if (!gr_tpe_allow(file)) { + retval = -EACCES; + goto out; + } + + if (gr_check_crash_exec(file)) { + retval = -EACCES; + goto out; + } + retval = copy_strings_kernel(1, &bprm.filename, &bprm); if (retval < 0) goto out; bprm.exec = bprm.p; + + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt); + retval = copy_strings32(bprm.envc, envp, &bprm); if (retval < 0) goto out; @@ -222,11 +260,32 @@ do_execve32(char * filename, u32 * argv, if (retval < 0) goto out; +#ifdef CONFIG_GRKERNSEC + old_acl = current->acl; + memcpy(old_rlim, current->rlim, sizeof(old_rlim)); + old_exec_file = current->exec_file; + get_file(file); + current->exec_file = file; +#endif + + gr_set_proc_label(file->f_dentry, file->f_vfsmnt); + retval = search_binary_handler(&bprm,regs); - if (retval >= 0) + if (retval >= 0) { +#ifdef CONFIG_GRKERNSEC + if (old_exec_file) + fput(old_exec_file); +#endif /* execve success */ return retval; + } +#ifdef CONFIG_GRKERNSEC + current->acl = old_acl; + memcpy(current->rlim, old_rlim, sizeof(old_rlim)); + fput(current->exec_file); + current->exec_file = old_exec_file; +#endif out: /* Something went wrong, return the inode and free the argument pages*/ allow_write_access(bprm.file); diff -urNp linux-2.4.37.7/arch/parisc/kernel/sys_parisc.c linux-2.4.37.7/arch/parisc/kernel/sys_parisc.c --- linux-2.4.37.7/arch/parisc/kernel/sys_parisc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/parisc/kernel/sys_parisc.c 2009-11-10 19:30:27.000000000 -0500 @@ -90,6 +90,11 @@ unsigned long arch_get_unmapped_area(str inode = filp->f_dentry->d_inode; } +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; +#endif + if (inode && (flags & MAP_SHARED) && (inode->i_mapping->i_mmap_shared)) { addr = get_shared_area(inode, addr, len, pgoff); } else { @@ -104,6 +109,7 @@ static unsigned long do_mmap2(unsigned l { struct file * file = NULL; unsigned long error = -EBADF; + if (!(flags & MAP_ANONYMOUS)) { file = fget(fd); if (!file) diff -urNp linux-2.4.37.7/arch/parisc/kernel/traps.c linux-2.4.37.7/arch/parisc/kernel/traps.c --- linux-2.4.37.7/arch/parisc/kernel/traps.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/parisc/kernel/traps.c 2009-11-10 19:30:27.000000000 -0500 @@ -637,9 +637,7 @@ void handle_interruption(int code, struc down_read(¤t->mm->mmap_sem); vma = find_vma(current->mm,regs->iaoq[0]); - if (vma && (regs->iaoq[0] >= vma->vm_start) - && (vma->vm_flags & VM_EXEC)) { - + if (vma && (regs->iaoq[0] >= vma->vm_start)) { fault_address = regs->iaoq[0]; fault_space = regs->iasq[0]; diff -urNp linux-2.4.37.7/arch/parisc/mm/fault.c linux-2.4.37.7/arch/parisc/mm/fault.c --- linux-2.4.37.7/arch/parisc/mm/fault.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/parisc/mm/fault.c 2009-11-10 19:30:27.000000000 -0500 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -53,7 +54,7 @@ static unsigned long parisc_acctyp(unsigned long code, unsigned int inst) { - if (code == 6 || code == 16) + if (code == 6 || code == 7 || code == 16) return VM_EXEC; switch (inst & 0xf0000000) { @@ -139,6 +140,115 @@ parisc_acctyp(unsigned long code, unsign } #endif +#ifdef CONFIG_PAX_PAGEEXEC +/* + * PaX: decide what to do with offenders (instruction_pointer(regs) = fault address) + * + * returns 1 when task should be killed + * 2 when rt_sigreturn trampoline was detected + * 3 when unpatched PLT trampoline was detected + */ +static int pax_handle_fetch_fault(struct pt_regs *regs) +{ + int err; + +#ifdef CONFIG_PAX_EMUPLT + do { /* PaX: unpatched PLT emulation */ + unsigned int bl, depwi; + + err = get_user(bl, (unsigned int*)instruction_pointer(regs)); + err |= get_user(depwi, (unsigned int*)(instruction_pointer(regs)+4)); + + if (err) + break; + + if (bl == 0xEA9F1FDDU && depwi == 0xD6801C1EU) { + unsigned int ldw, bv, ldw2, addr = instruction_pointer(regs)-12; + + err = get_user(ldw, (unsigned int*)addr); + err |= get_user(bv, (unsigned int*)(addr+4)); + err |= get_user(ldw2, (unsigned int*)(addr+8)); + + if (err) + break; + + if (ldw == 0x0E801096U && + bv == 0xEAC0C000U && + ldw2 == 0x0E881095U) + { + unsigned int resolver, map; + + err = get_user(resolver, (unsigned int*)(instruction_pointer(regs)+8)); + err |= get_user(map, (unsigned int*)(instruction_pointer(regs)+12)); + if (err) + break; + + regs->gr[20] = instruction_pointer(regs)+8; + regs->gr[21] = map; + regs->gr[22] = resolver; + regs->iaoq[0] = resolver | 3UL; + regs->iaoq[1] = regs->iaoq[0] + 4; + return 3; + } + } + } while (0); +#endif + +#ifdef CONFIG_PAX_EMUTRAMP + +#ifndef CONFIG_PAX_EMUSIGRT + if (!(current->mm->pax_flags & MF_PAX_EMUTRAMP)) + return 1; +#endif + + do { /* PaX: rt_sigreturn emulation */ + unsigned int ldi1, ldi2, bel, nop; + + err = get_user(ldi1, (unsigned int *)instruction_pointer(regs)); + err |= get_user(ldi2, (unsigned int *)(instruction_pointer(regs)+4)); + err |= get_user(bel, (unsigned int *)(instruction_pointer(regs)+8)); + err |= get_user(nop, (unsigned int *)(instruction_pointer(regs)+12)); + + if (err) + break; + + if ((ldi1 == 0x34190000U || ldi1 == 0x34190002U) && + ldi2 == 0x3414015AU && + bel == 0xE4008200U && + nop == 0x08000240U) + { + regs->gr[25] = (ldi1 & 2) >> 1; + regs->gr[20] = __NR_rt_sigreturn; + regs->gr[31] = regs->iaoq[1] + 16; + regs->sr[0] = regs->iasq[1]; + regs->iaoq[0] = 0x100UL; + regs->iaoq[1] = regs->iaoq[0] + 4; + regs->iasq[0] = regs->sr[2]; + regs->iasq[1] = regs->sr[2]; + return 2; + } + } while (0); +#endif + + return 1; +} + +void pax_report_insns(void *pc, void *sp) +{ + unsigned long i; + + printk(KERN_ERR "PAX: bytes at PC: "); + for (i = 0; i < 5; i++) { + unsigned int c; + if (get_user(c, (unsigned int*)pc+i)) + printk("???????? "); + else + printk("%08x ", c); + } + printk("\n"); +} +#endif + void do_page_fault(struct pt_regs *regs, unsigned long code, unsigned long address) { @@ -164,8 +274,33 @@ good_area: acc_type = parisc_acctyp(code,regs->iir); - if ((vma->vm_flags & acc_type) != acc_type) + if ((vma->vm_flags & acc_type) != acc_type) { + +#ifdef CONFIG_PAX_PAGEEXEC + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (acc_type & VM_EXEC) && + (address & ~3UL) == instruction_pointer(regs)) + { + up_read(&mm->mmap_sem); + switch(pax_handle_fetch_fault(regs)) { + +#ifdef CONFIG_PAX_EMUPLT + case 3: + return; +#endif + +#ifdef CONFIG_PAX_EMUTRAMP + case 2: + return; +#endif + + } + pax_report_fault(regs, (void*)instruction_pointer(regs), (void*)regs->gr[30]); + do_exit(SIGKILL); + } +#endif + goto bad_area; + } /* * If for any reason at all we couldn't handle the fault, make diff -urNp linux-2.4.37.7/arch/ppc/config.in linux-2.4.37.7/arch/ppc/config.in --- linux-2.4.37.7/arch/ppc/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -666,3 +666,12 @@ fi int 'Kernel messages buffer length shift (0 = default)' CONFIG_LOG_BUF_SHIFT 0 endmenu + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu + diff -urNp linux-2.4.37.7/arch/ppc/kernel/head_4xx.S linux-2.4.37.7/arch/ppc/kernel/head_4xx.S --- linux-2.4.37.7/arch/ppc/kernel/head_4xx.S 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc/kernel/head_4xx.S 2009-11-10 19:30:27.000000000 -0500 @@ -296,15 +296,12 @@ label: /* Most of the Linux PTE is ready to load into the TLB LO. * We set ZSEL, where only the LS-bit determines user access. - * We set execute, because we don't have the granularity to - * properly set this at the page level (Linux problem). * If shared is set, we cause a zero PID->TID load. * Many of these bits are software only. Bits we don't set * here we (properly should) assume have the appropriate value. */ li r22, 0x0ce2 andc r21, r21, r22 /* Make sure 20, 21 are zero */ - ori r21, r21, _PAGE_HWEXEC /* make it executable */ /* find the TLB index that caused the fault. It has to be here. */ @@ -783,7 +780,6 @@ finish_tlb_load: stw r23, tlb_4xx_index@l(0) 6: - ori r21, r21, _PAGE_HWEXEC /* make it executable */ tlbwe r21, r23, TLB_DATA /* Load TLB LO */ /* Create EPN. This is the faulting address plus a static diff -urNp linux-2.4.37.7/arch/ppc/kernel/ppc_htab.c linux-2.4.37.7/arch/ppc/kernel/ppc_htab.c --- linux-2.4.37.7/arch/ppc/kernel/ppc_htab.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc/kernel/ppc_htab.c 2009-11-10 19:30:27.000000000 -0500 @@ -61,7 +61,7 @@ extern unsigned int htab_hash_searches; #define PMC1 953 #define PMC2 954 -struct file_operations ppc_htab_operations = { +const struct file_operations ppc_htab_operations = { llseek: ppc_htab_lseek, read: ppc_htab_read, write: ppc_htab_write, diff -urNp linux-2.4.37.7/arch/ppc/kernel/ptrace.c linux-2.4.37.7/arch/ppc/kernel/ptrace.c --- linux-2.4.37.7/arch/ppc/kernel/ptrace.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc/kernel/ptrace.c 2009-11-10 19:30:27.000000000 -0500 @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -195,6 +196,9 @@ int sys_ptrace(long request, long pid, l if (pid == 1) /* you may not mess with init */ goto out_tsk; + if (gr_handle_ptrace(child, request)) + goto out_tsk; + if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); goto out_tsk; diff -urNp linux-2.4.37.7/arch/ppc/kernel/setup.c linux-2.4.37.7/arch/ppc/kernel/setup.c --- linux-2.4.37.7/arch/ppc/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -238,7 +238,7 @@ static void c_stop(struct seq_file *m, v { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { start: c_start, next: c_next, stop: c_stop, diff -urNp linux-2.4.37.7/arch/ppc/mm/fault.c linux-2.4.37.7/arch/ppc/mm/fault.c --- linux-2.4.37.7/arch/ppc/mm/fault.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc/mm/fault.c 2009-11-10 19:30:27.000000000 -0500 @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include #include @@ -52,6 +55,359 @@ extern void die_if_kernel(char *, struct void bad_page_fault(struct pt_regs *, unsigned long, int sig); void do_page_fault(struct pt_regs *, unsigned long, unsigned long); +#ifdef CONFIG_PAX_EMUSIGRT +void pax_syscall_close(struct vm_area_struct * vma) +{ + vma->vm_mm->call_syscall = 0UL; +} + +static struct page* pax_syscall_nopage(struct vm_area_struct *vma, unsigned long address, int write_access) +{ + struct page* page; + unsigned int *kaddr; + + page = alloc_page(GFP_HIGHUSER); + if (!page) + return page; + + kaddr = kmap(page); + memset(kaddr, 0, PAGE_SIZE); + kaddr[0] = 0x44000002U; /* sc */ + __flush_dcache_icache(kaddr); + kunmap(page); + return page; +} + +static const struct vm_operations_struct pax_vm_ops = { + .close = pax_syscall_close, + .nopage = pax_syscall_nopage, +}; + +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) +{ + int ret; + + memset(vma, 0, sizeof(*vma)); + vma->vm_mm = current->mm; + vma->vm_start = addr; + vma->vm_end = addr + PAGE_SIZE; + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; + vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f]; + vma->vm_ops = &pax_vm_ops; + + ret = insert_vm_struct(current->mm, vma); + if (ret) + return ret; + + ++current->mm->total_vm; + return 0; +} +#endif + +#ifdef CONFIG_PAX_PAGEEXEC +/* + * PaX: decide what to do with offenders (regs->nip = fault address) + * + * returns 1 when task should be killed + * 2 when patched GOT trampoline was detected + * 3 when patched PLT trampoline was detected + * 4 when unpatched PLT trampoline was detected + * 5 when sigreturn trampoline was detected + * 6 when rt_sigreturn trampoline was detected + */ +static int pax_handle_fetch_fault(struct pt_regs *regs) +{ + int err; + +#ifdef CONFIG_PAX_EMUPLT + do { /* PaX: patched GOT emulation */ + unsigned int blrl; + + err = get_user(blrl, (unsigned int*)regs->nip); + + if (!err && blrl == 0x4E800021U) { + unsigned long temp = regs->nip; + + regs->nip = regs->link & 0xFFFFFFFCUL; + regs->link = temp + 4UL; + return 2; + } + } while (0); + + do { /* PaX: patched PLT emulation #1 */ + unsigned int b; + + err = get_user(b, (unsigned int *)regs->nip); + + if (!err && (b & 0xFC000003U) == 0x48000000U) { + regs->nip += (((b | 0xFC000000UL) ^ 0x02000000UL) + 0x02000000UL); + return 3; + } + } while (0); + + do { /* PaX: unpatched PLT emulation #1 */ + unsigned int li, b; + + err = get_user(li, (unsigned int *)regs->nip); + err |= get_user(b, (unsigned int *)(regs->nip+4)); + + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) { + unsigned int rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr; + unsigned long addr = b | 0xFC000000UL; + + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL); + err = get_user(rlwinm, (unsigned int*)addr); + err |= get_user(add, (unsigned int*)(addr+4)); + err |= get_user(li2, (unsigned int*)(addr+8)); + err |= get_user(addis2, (unsigned int*)(addr+12)); + err |= get_user(mtctr, (unsigned int*)(addr+16)); + err |= get_user(li3, (unsigned int*)(addr+20)); + err |= get_user(addis3, (unsigned int*)(addr+24)); + err |= get_user(bctr, (unsigned int*)(addr+28)); + + if (err) + break; + + if (rlwinm == 0x556C083CU && + add == 0x7D6C5A14U && + (li2 & 0xFFFF0000U) == 0x39800000U && + (addis2 & 0xFFFF0000U) == 0x3D8C0000U && + mtctr == 0x7D8903A6U && + (li3 & 0xFFFF0000U) == 0x39800000U && + (addis3 & 0xFFFF0000U) == 0x3D8C0000U && + bctr == 0x4E800420U) + { + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16; + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); + regs->ctr += (addis2 & 0xFFFFU) << 16; + regs->nip = regs->ctr; + return 4; + } + } + } while (0); + +#if 0 + do { /* PaX: unpatched PLT emulation #2 */ + unsigned int lis, lwzu, b, bctr; + + err = get_user(lis, (unsigned int *)regs->nip); + err |= get_user(lwzu, (unsigned int *)(regs->nip+4)); + err |= get_user(b, (unsigned int *)(regs->nip+8)); + err |= get_user(bctr, (unsigned int *)(regs->nip+12)); + + if (err) + break; + + if ((lis & 0xFFFF0000U) == 0x39600000U && + (lwzu & 0xU) == 0xU && + (b & 0xFC000003U) == 0x48000000U && + bctr == 0x4E800420U) + { + unsigned int addis, addi, rlwinm, add, li2, addis2, mtctr, li3, addis3, bctr; + unsigned long addr = b | 0xFC000000UL; + + addr = regs->nip + 12 + ((addr ^ 0x02000000UL) + 0x02000000UL); + err = get_user(addis, (unsigned int*)addr); + err |= get_user(addi, (unsigned int*)(addr+4)); + err |= get_user(rlwinm, (unsigned int*)(addr+8)); + err |= get_user(add, (unsigned int*)(addr+12)); + err |= get_user(li2, (unsigned int*)(addr+16)); + err |= get_user(addis2, (unsigned int*)(addr+20)); + err |= get_user(mtctr, (unsigned int*)(addr+24)); + err |= get_user(li3, (unsigned int*)(addr+28)); + err |= get_user(addis3, (unsigned int*)(addr+32)); + err |= get_user(bctr, (unsigned int*)(addr+36)); + + if (err) + break; + + if ((addis & 0xFFFF0000U) == 0x3D6B0000U && + (addi & 0xFFFF0000U) == 0x396B0000U && + rlwinm == 0x556C083CU && + add == 0x7D6C5A14U && + (li2 & 0xFFFF0000U) == 0x39800000U && + (addis2 & 0xFFFF0000U) == 0x3D8C0000U && + mtctr == 0x7D8903A6U && + (li3 & 0xFFFF0000U) == 0x39800000U && + (addis3 & 0xFFFF0000U) == 0x3D8C0000U && + bctr == 0x4E800420U) + { + regs->gpr[PT_R11] = + regs->gpr[PT_R11] = 3 * (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); + regs->gpr[PT_R12] = (((li3 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); + regs->gpr[PT_R12] += (addis3 & 0xFFFFU) << 16; + regs->ctr = (((li2 | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); + regs->ctr += (addis2 & 0xFFFFU) << 16; + regs->nip = regs->ctr; + return 4; + } + } + } while (0); +#endif + + do { /* PaX: unpatched PLT emulation #3 */ + unsigned int li, b; + + err = get_user(li, (unsigned int *)regs->nip); + err |= get_user(b, (unsigned int *)(regs->nip+4)); + + if (!err && (li & 0xFFFF0000U) == 0x39600000U && (b & 0xFC000003U) == 0x48000000U) { + unsigned int addis, lwz, mtctr, bctr; + unsigned long addr = b | 0xFC000000UL; + + addr = regs->nip + 4 + ((addr ^ 0x02000000UL) + 0x02000000UL); + err = get_user(addis, (unsigned int*)addr); + err |= get_user(lwz, (unsigned int*)(addr+4)); + err |= get_user(mtctr, (unsigned int*)(addr+8)); + err |= get_user(bctr, (unsigned int*)(addr+12)); + + if (err) + break; + + if ((addis & 0xFFFF0000U) == 0x3D6B0000U && + (lwz & 0xFFFF0000U) == 0x816B0000U && + mtctr == 0x7D6903A6U && + bctr == 0x4E800420U) + { + unsigned int r11; + + addr = (addis << 16) + (((li | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); + addr += (((lwz | 0xFFFF0000UL) ^ 0x00008000UL) + 0x00008000UL); + + err = get_user(r11, (unsigned int*)addr); + if (err) + break; + + regs->gpr[PT_R11] = r11; + regs->ctr = r11; + regs->nip = r11; + return 4; + } + } + } while (0); +#endif + +#ifdef CONFIG_PAX_EMUSIGRT + do { /* PaX: sigreturn emulation */ + unsigned int li, sc; + + err = get_user(li, (unsigned int *)regs->nip); + err |= get_user(sc, (unsigned int *)(regs->nip+4)); + + if (!err && li == 0x38007777U && sc == 0x44000002U) { + struct vm_area_struct *vma; + unsigned long call_syscall; + + down_read(¤t->mm->mmap_sem); + call_syscall = current->mm->call_syscall; + up_read(¤t->mm->mmap_sem); + if (likely(call_syscall)) + goto emulate; + + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + + down_write(¤t->mm->mmap_sem); + if (current->mm->call_syscall) { + call_syscall = current->mm->call_syscall; + up_write(¤t->mm->mmap_sem); + if (vma) kmem_cache_free(vm_area_cachep, vma); + goto emulate; + } + + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); + if (!vma || (call_syscall & ~PAGE_MASK)) { + up_write(¤t->mm->mmap_sem); + if (vma) kmem_cache_free(vm_area_cachep, vma); + return 1; + } + + if (pax_insert_vma(vma, call_syscall)) { + up_write(¤t->mm->mmap_sem); + kmem_cache_free(vm_area_cachep, vma); + return 1; + } + + current->mm->call_syscall = call_syscall; + up_write(¤t->mm->mmap_sem); + +emulate: + regs->gpr[PT_R0] = 0x7777UL; + regs->nip = call_syscall; + return 5; + } + } while (0); + + do { /* PaX: rt_sigreturn emulation */ + unsigned int li, sc; + + err = get_user(li, (unsigned int *)regs->nip); + err |= get_user(sc, (unsigned int *)(regs->nip+4)); + + if (!err && li == 0x38006666U && sc == 0x44000002U) { + struct vm_area_struct *vma; + unsigned int call_syscall; + + down_read(¤t->mm->mmap_sem); + call_syscall = current->mm->call_syscall; + up_read(¤t->mm->mmap_sem); + if (likely(call_syscall)) + goto rt_emulate; + + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + + down_write(¤t->mm->mmap_sem); + if (current->mm->call_syscall) { + call_syscall = current->mm->call_syscall; + up_write(¤t->mm->mmap_sem); + if (vma) kmem_cache_free(vm_area_cachep, vma); + goto rt_emulate; + } + + call_syscall = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); + if (!vma || (call_syscall & ~PAGE_MASK)) { + up_write(¤t->mm->mmap_sem); + if (vma) kmem_cache_free(vm_area_cachep, vma); + return 1; + } + + if (pax_insert_vma(vma, call_syscall)) { + up_write(¤t->mm->mmap_sem); + kmem_cache_free(vm_area_cachep, vma); + return 1; + } + + current->mm->call_syscall = call_syscall; + up_write(¤t->mm->mmap_sem); + +rt_emulate: + regs->gpr[PT_R0] = 0x6666UL; + regs->nip = call_syscall; + return 6; + } + } while (0); +#endif + + return 1; +} + +void pax_report_insns(void *pc, void *sp) +{ + unsigned long i; + + printk(KERN_ERR "PAX: bytes at PC: "); + for (i = 0; i < 5; i++) { + unsigned int c; + if (get_user(c, (unsigned int*)pc+i)) + printk("???????? "); + else + printk("%08x ", c); + } + printk("\n"); +} +#endif + /* * Check whether the instruction at regs->nip is a store using * an update addressing form which will update r1. @@ -112,7 +468,7 @@ void do_page_fault(struct pt_regs *regs, * indicate errors in DSISR but can validly be set in SRR1. */ if (regs->trap == 0x400) - error_code &= 0x48200000; + error_code &= 0x58200000; else is_write = error_code & 0x02000000; #endif /* CONFIG_4xx || CONFIG_BOOKE */ @@ -245,6 +601,33 @@ bad_area: /* User mode accesses cause a SIGSEGV */ if (user_mode(regs)) { + +#ifdef CONFIG_PAX_PAGEEXEC + if (current->mm->pax_flags & MF_PAX_PAGEEXEC) { + if ((regs->trap == 0x400) && (regs->nip == address)) { + switch (pax_handle_fetch_fault(regs)) { + +#ifdef CONFIG_PAX_EMUPLT + case 2: + case 3: + case 4: + return; +#endif + +#ifdef CONFIG_PAX_EMUSIGRT + case 5: + case 6: + return; +#endif + + } + + pax_report_fault(regs, (void*)regs->nip, (void*)regs->gpr[1]); + do_exit(SIGKILL); + } + } +#endif + info.si_signo = SIGSEGV; info.si_errno = 0; info.si_code = code; diff -urNp linux-2.4.37.7/arch/ppc64/kernel/ioctl32.c linux-2.4.37.7/arch/ppc64/kernel/ioctl32.c --- linux-2.4.37.7/arch/ppc64/kernel/ioctl32.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc64/kernel/ioctl32.c 2009-11-10 19:30:27.000000000 -0500 @@ -1827,7 +1827,11 @@ static int vt_check(struct file *file) * To have permissions to do most of the vt ioctls, we either have * to be the owner of the tty, or super-user. */ +#ifdef CONFIG_GRKERNSEC + if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG)) +#else if (current->tty == tty || suser()) +#endif return 1; return 0; } diff -urNp linux-2.4.37.7/arch/ppc64/kernel/lparcfg.c linux-2.4.37.7/arch/ppc64/kernel/lparcfg.c --- linux-2.4.37.7/arch/ppc64/kernel/lparcfg.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc64/kernel/lparcfg.c 2009-11-10 19:30:27.000000000 -0500 @@ -432,7 +432,7 @@ static int lparcfg_open(struct inode * i return 0; } -struct file_operations lparcfg_fops = { +const struct file_operations lparcfg_fops = { owner: THIS_MODULE, read: lparcfg_read, open: lparcfg_open, diff -urNp linux-2.4.37.7/arch/ppc64/kernel/nvram.c linux-2.4.37.7/arch/ppc64/kernel/nvram.c --- linux-2.4.37.7/arch/ppc64/kernel/nvram.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc64/kernel/nvram.c 2009-11-10 19:30:27.000000000 -0500 @@ -149,7 +149,7 @@ static int dev_ppc64_nvram_ioctl(struct return -EINVAL; } -struct file_operations nvram_fops = { +const struct file_operations nvram_fops = { .owner = THIS_MODULE, .llseek = dev_ppc64_nvram_llseek, .read = dev_ppc64_read_nvram, diff -urNp linux-2.4.37.7/arch/ppc64/kernel/proc_pmc.c linux-2.4.37.7/arch/ppc64/kernel/proc_pmc.c --- linux-2.4.37.7/arch/ppc64/kernel/proc_pmc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc64/kernel/proc_pmc.c 2009-11-10 19:30:27.000000000 -0500 @@ -100,7 +100,7 @@ static loff_t nacamap_seek( struct file static ssize_t nacamap_read( struct file *file, char *buf, size_t nbytes, loff_t *ppos); static int nacamap_mmap( struct file *file, struct vm_area_struct *vma ); -static struct file_operations nacamap_fops = { +static const struct file_operations nacamap_fops = { llseek: nacamap_seek, read: nacamap_read, mmap: nacamap_mmap @@ -116,17 +116,17 @@ static ssize_t read_timeslice(struct fil static ssize_t write_timeslice(struct file * file, const char * buf, size_t count, loff_t *ppos); -static struct file_operations proc_profile_operations = { +static const struct file_operations proc_profile_operations = { read: read_profile, write: write_profile, }; -static struct file_operations proc_trace_operations = { +static const struct file_operations proc_trace_operations = { read: read_trace, write: write_trace, }; -static struct file_operations proc_timeslice_operations = { +static const struct file_operations proc_timeslice_operations = { read: read_timeslice, write: write_timeslice, }; diff -urNp linux-2.4.37.7/arch/ppc64/kernel/rtasd.c linux-2.4.37.7/arch/ppc64/kernel/rtasd.c --- linux-2.4.37.7/arch/ppc64/kernel/rtasd.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc64/kernel/rtasd.c 2009-11-10 19:30:27.000000000 -0500 @@ -276,7 +276,7 @@ static unsigned int rtas_log_poll(struct return 0; } -struct file_operations proc_rtas_log_operations = { +const struct file_operations proc_rtas_log_operations = { .read = rtas_log_read, .poll = rtas_log_poll, .open = rtas_log_open, diff -urNp linux-2.4.37.7/arch/ppc64/kernel/rtas_flash.c linux-2.4.37.7/arch/ppc64/kernel/rtas_flash.c --- linux-2.4.37.7/arch/ppc64/kernel/rtas_flash.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc64/kernel/rtas_flash.c 2009-11-10 19:30:27.000000000 -0500 @@ -618,21 +618,21 @@ static inline struct proc_dir_entry * cr return ent; } -static struct file_operations rtas_flash_operations = { +static const struct file_operations rtas_flash_operations = { read: rtas_flash_read, write: rtas_flash_write, open: rtas_excl_open, release: rtas_flash_release, }; -static struct file_operations manage_flash_operations = { +static const struct file_operations manage_flash_operations = { read: manage_flash_read, write: manage_flash_write, open: rtas_excl_open, release: rtas_excl_release, }; -static struct file_operations validate_flash_operations = { +static const struct file_operations validate_flash_operations = { read: validate_flash_read, write: validate_flash_write, open: rtas_excl_open, diff -urNp linux-2.4.37.7/arch/ppc64/kernel/rtas-proc.c linux-2.4.37.7/arch/ppc64/kernel/rtas-proc.c --- linux-2.4.37.7/arch/ppc64/kernel/rtas-proc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc64/kernel/rtas-proc.c 2009-11-10 19:30:27.000000000 -0500 @@ -176,30 +176,30 @@ static ssize_t ppc_rtas_errinjct_write(s static ssize_t ppc_rtas_errinjct_read(struct file *file, char *buf, size_t count, loff_t *ppos); -struct file_operations ppc_rtas_poweron_operations = { +const struct file_operations ppc_rtas_poweron_operations = { .read = ppc_rtas_poweron_read, .write = ppc_rtas_poweron_write }; -struct file_operations ppc_rtas_progress_operations = { +const struct file_operations ppc_rtas_progress_operations = { .read = ppc_rtas_progress_read, .write = ppc_rtas_progress_write }; -struct file_operations ppc_rtas_clock_operations = { +const struct file_operations ppc_rtas_clock_operations = { .read = ppc_rtas_clock_read, .write = ppc_rtas_clock_write }; -struct file_operations ppc_rtas_tone_freq_operations = { +const struct file_operations ppc_rtas_tone_freq_operations = { .read = ppc_rtas_tone_freq_read, .write = ppc_rtas_tone_freq_write }; -struct file_operations ppc_rtas_tone_volume_operations = { +const struct file_operations ppc_rtas_tone_volume_operations = { .read = ppc_rtas_tone_volume_read, .write = ppc_rtas_tone_volume_write }; -struct file_operations ppc_rtas_errinjct_operations = { +const struct file_operations ppc_rtas_errinjct_operations = { .open = ppc_rtas_errinjct_open, .read = ppc_rtas_errinjct_read, .write = ppc_rtas_errinjct_write, diff -urNp linux-2.4.37.7/arch/ppc64/kernel/rtc.c linux-2.4.37.7/arch/ppc64/kernel/rtc.c --- linux-2.4.37.7/arch/ppc64/kernel/rtc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc64/kernel/rtc.c 2009-11-10 19:30:27.000000000 -0500 @@ -179,7 +179,7 @@ static int rtc_release(struct inode *ino /* * The various file operations we support. */ -static struct file_operations rtc_fops = { +static const struct file_operations rtc_fops = { .owner = THIS_MODULE, .llseek = rtc_llseek, .read = rtc_read, diff -urNp linux-2.4.37.7/arch/ppc64/kernel/scanlog.c linux-2.4.37.7/arch/ppc64/kernel/scanlog.c --- linux-2.4.37.7/arch/ppc64/kernel/scanlog.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc64/kernel/scanlog.c 2009-11-10 19:30:27.000000000 -0500 @@ -190,7 +190,7 @@ static int scanlog_release(struct inode return 0; } -struct file_operations scanlog_fops = { +const struct file_operations scanlog_fops = { owner: THIS_MODULE, read: scanlog_read, write: scanlog_write, diff -urNp linux-2.4.37.7/arch/ppc64/kernel/setup.c linux-2.4.37.7/arch/ppc64/kernel/setup.c --- linux-2.4.37.7/arch/ppc64/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/ppc64/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -306,7 +306,7 @@ static void *c_next(struct seq_file *m, static void c_stop(struct seq_file *m, void *v) { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { .start =c_start, .next = c_next, .stop = c_stop, diff -urNp linux-2.4.37.7/arch/s390/config.in linux-2.4.37.7/arch/s390/config.in --- linux-2.4.37.7/arch/s390/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/s390/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -87,3 +87,11 @@ endmenu source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urNp linux-2.4.37.7/arch/s390/kernel/debug.c linux-2.4.37.7/arch/s390/kernel/debug.c --- linux-2.4.37.7/arch/s390/kernel/debug.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/s390/kernel/debug.c 2009-11-10 19:30:27.000000000 -0500 @@ -159,14 +159,14 @@ DECLARE_MUTEX(debug_lock); static int initialized = 0; -static struct file_operations debug_file_ops = { +static const struct file_operations debug_file_ops = { read: debug_output, write: debug_input, open: debug_open, release: debug_close, }; -static struct inode_operations debug_inode_ops = { +static const struct inode_operations debug_inode_ops = { #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98)) default_file_ops: &debug_file_ops, /* file ops */ #endif diff -urNp linux-2.4.37.7/arch/s390/kernel/setup.c linux-2.4.37.7/arch/s390/kernel/setup.c --- linux-2.4.37.7/arch/s390/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/s390/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -686,7 +686,7 @@ static void *c_next(struct seq_file *m, static void c_stop(struct seq_file *m, void *v) { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { start: c_start, next: c_next, stop: c_stop, diff -urNp linux-2.4.37.7/arch/s390x/config.in linux-2.4.37.7/arch/s390x/config.in --- linux-2.4.37.7/arch/s390x/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/s390x/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -91,3 +91,11 @@ endmenu source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urNp linux-2.4.37.7/arch/s390x/kernel/debug.c linux-2.4.37.7/arch/s390x/kernel/debug.c --- linux-2.4.37.7/arch/s390x/kernel/debug.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/s390x/kernel/debug.c 2009-11-10 19:30:27.000000000 -0500 @@ -159,14 +159,14 @@ DECLARE_MUTEX(debug_lock); static int initialized = 0; -static struct file_operations debug_file_ops = { +static const struct file_operations debug_file_ops = { read: debug_output, write: debug_input, open: debug_open, release: debug_close, }; -static struct inode_operations debug_inode_ops = { +static const struct inode_operations debug_inode_ops = { #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98)) default_file_ops: &debug_file_ops, /* file ops */ #endif diff -urNp linux-2.4.37.7/arch/s390x/kernel/setup.c linux-2.4.37.7/arch/s390x/kernel/setup.c --- linux-2.4.37.7/arch/s390x/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/s390x/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -545,7 +545,7 @@ static void *c_next(struct seq_file *m, static void c_stop(struct seq_file *m, void *v) { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { start: c_start, next: c_next, stop: c_stop, diff -urNp linux-2.4.37.7/arch/sh/config.in linux-2.4.37.7/arch/sh/config.in --- linux-2.4.37.7/arch/sh/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sh/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -493,3 +493,11 @@ endmenu source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urNp linux-2.4.37.7/arch/sh/kernel/setup.c linux-2.4.37.7/arch/sh/kernel/setup.c --- linux-2.4.37.7/arch/sh/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sh/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -566,7 +566,7 @@ static void *c_next(struct seq_file *m, static void c_stop(struct seq_file *m, void *v) { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { start: c_start, next: c_next, stop: c_stop, diff -urNp linux-2.4.37.7/arch/sh64/kernel/setup.c linux-2.4.37.7/arch/sh64/kernel/setup.c --- linux-2.4.37.7/arch/sh64/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sh64/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -353,7 +353,7 @@ static void *c_next(struct seq_file *m, static void c_stop(struct seq_file *m, void *v) { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { start: c_start, next: c_next, stop: c_stop, diff -urNp linux-2.4.37.7/arch/sparc/boot/Makefile linux-2.4.37.7/arch/sparc/boot/Makefile --- linux-2.4.37.7/arch/sparc/boot/Makefile 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc/boot/Makefile 2009-11-10 19:30:27.000000000 -0500 @@ -24,7 +24,7 @@ clean: BTOBJS := $(HEAD) init/main.o init/version.o init/do_mounts.o BTLIBS := $(CORE_FILES_NO_BTFIX) $(FILESYSTEMS) \ - $(DRIVERS) $(NETWORKS) + $(DRIVERS) $(NETWORKS) $(GRSECURITY) GENFILES := include/linux/version.h include/linux/compile.h $(foreach dirname, $(CORE_FILES_NO_BTFIX), _dir_$(dir $(dirname))) .PHONY : $(GENFILES) diff -urNp linux-2.4.37.7/arch/sparc/config.in linux-2.4.37.7/arch/sparc/config.in --- linux-2.4.37.7/arch/sparc/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -282,3 +282,11 @@ endmenu source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urNp linux-2.4.37.7/arch/sparc/kernel/apc.c linux-2.4.37.7/arch/sparc/kernel/apc.c --- linux-2.4.37.7/arch/sparc/kernel/apc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc/kernel/apc.c 2009-11-10 19:30:27.000000000 -0500 @@ -130,7 +130,7 @@ static int apc_ioctl(struct inode *inode return 0; } -static struct file_operations apc_fops = { +static const struct file_operations apc_fops = { ioctl: apc_ioctl, open: apc_open, release: apc_release, diff -urNp linux-2.4.37.7/arch/sparc/kernel/ptrace.c linux-2.4.37.7/arch/sparc/kernel/ptrace.c --- linux-2.4.37.7/arch/sparc/kernel/ptrace.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc/kernel/ptrace.c 2009-11-10 19:30:27.000000000 -0500 @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -310,6 +311,9 @@ asmlinkage void do_ptrace(struct pt_regs goto out; } + if(gr_handle_ptrace(child, request)) + goto out_tsk; + if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH) || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) { if (ptrace_attach(child)) { diff -urNp linux-2.4.37.7/arch/sparc/kernel/setup.c linux-2.4.37.7/arch/sparc/kernel/setup.c --- linux-2.4.37.7/arch/sparc/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -516,7 +516,7 @@ static void c_stop(struct seq_file *m, v { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { start: c_start, next: c_next, stop: c_stop, diff -urNp linux-2.4.37.7/arch/sparc/kernel/sys_sparc.c linux-2.4.37.7/arch/sparc/kernel/sys_sparc.c --- linux-2.4.37.7/arch/sparc/kernel/sys_sparc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc/kernel/sys_sparc.c 2009-11-10 19:30:27.000000000 -0500 @@ -54,6 +54,13 @@ unsigned long arch_get_unmapped_area(str return -ENOMEM; if (ARCH_SUN4C_SUN4 && len > 0x20000000) return -ENOMEM; + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; + else +#endif + if (!addr) addr = TASK_UNMAPPED_BASE; diff -urNp linux-2.4.37.7/arch/sparc/mm/fault.c linux-2.4.37.7/arch/sparc/mm/fault.c --- linux-2.4.37.7/arch/sparc/mm/fault.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc/mm/fault.c 2009-11-10 19:30:27.000000000 -0500 @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include #include @@ -219,6 +222,248 @@ static unsigned long compute_si_addr(str return safe_compute_effective_address(regs, insn); } +#ifdef CONFIG_PAX_PAGEEXEC +void pax_emuplt_close(struct vm_area_struct * vma) +{ + vma->vm_mm->call_dl_resolve = 0UL; +} + +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int write_access) +{ + struct page* page; + unsigned int *kaddr; + + page = alloc_page(GFP_HIGHUSER); + if (!page) + return page; + + kaddr = kmap(page); + memset(kaddr, 0, PAGE_SIZE); + kaddr[0] = 0x9DE3BFA8U; /* save */ + flush_dcache_page(page); + kunmap(page); + return page; +} + +static const struct vm_operations_struct pax_vm_ops = { + .close = pax_emuplt_close, + .nopage = pax_emuplt_nopage, +}; + +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) +{ + int ret; + + memset(vma, 0, sizeof(*vma)); + vma->vm_mm = current->mm; + vma->vm_start = addr; + vma->vm_end = addr + PAGE_SIZE; + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; + vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f]; + vma->vm_ops = &pax_vm_ops; + + ret = insert_vm_struct(current->mm, vma); + if (ret) + return ret; + + ++current->mm->total_vm; + return 0; +} + +/* + * PaX: decide what to do with offenders (regs->pc = fault address) + * + * returns 1 when task should be killed + * 2 when patched PLT trampoline was detected + * 3 when unpatched PLT trampoline was detected + */ +static int pax_handle_fetch_fault(struct pt_regs *regs) +{ + int err; + +#ifdef CONFIG_PAX_EMUPLT + do { /* PaX: patched PLT emulation #1 */ + unsigned int sethi1, sethi2, jmpl; + + err = get_user(sethi1, (unsigned int*)regs->pc); + err |= get_user(sethi2, (unsigned int*)(regs->pc+4)); + err |= get_user(jmpl, (unsigned int*)(regs->pc+8)); + + if (err) + break; + + if ((sethi1 & 0xFFC00000U) == 0x03000000U && + (sethi2 & 0xFFC00000U) == 0x03000000U && + (jmpl & 0xFFFFE000U) == 0x81C06000U) + { + unsigned int addr; + + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10; + addr = regs->u_regs[UREG_G1]; + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U); + regs->pc = addr; + regs->npc = addr+4; + return 2; + } + } while (0); + + { /* PaX: patched PLT emulation #2 */ + unsigned int ba; + + err = get_user(ba, (unsigned int*)regs->pc); + + if (!err && (ba & 0xFFC00000U) == 0x30800000U) { + unsigned int addr; + + addr = regs->pc + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2); + regs->pc = addr; + regs->npc = addr+4; + return 2; + } + } + + do { /* PaX: patched PLT emulation #3 */ + unsigned int sethi, jmpl, nop; + + err = get_user(sethi, (unsigned int*)regs->pc); + err |= get_user(jmpl, (unsigned int*)(regs->pc+4)); + err |= get_user(nop, (unsigned int*)(regs->pc+8)); + + if (err) + break; + + if ((sethi & 0xFFC00000U) == 0x03000000U && + (jmpl & 0xFFFFE000U) == 0x81C06000U && + nop == 0x01000000U) + { + unsigned int addr; + + addr = (sethi & 0x003FFFFFU) << 10; + regs->u_regs[UREG_G1] = addr; + addr += (((jmpl | 0xFFFFE000U) ^ 0x00001000U) + 0x00001000U); + regs->pc = addr; + regs->npc = addr+4; + return 2; + } + } while (0); + + do { /* PaX: unpatched PLT emulation step 1 */ + unsigned int sethi, ba, nop; + + err = get_user(sethi, (unsigned int*)regs->pc); + err |= get_user(ba, (unsigned int*)(regs->pc+4)); + err |= get_user(nop, (unsigned int*)(regs->pc+8)); + + if (err) + break; + + if ((sethi & 0xFFC00000U) == 0x03000000U && + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) && + nop == 0x01000000U) + { + unsigned int addr, save, call; + + if ((ba & 0xFFC00000U) == 0x30800000U) + addr = regs->pc + 4 + ((((ba | 0xFFC00000U) ^ 0x00200000U) + 0x00200000U) << 2); + else + addr = regs->pc + 4 + ((((ba | 0xFFF80000U) ^ 0x00040000U) + 0x00040000U) << 2); + + err = get_user(save, (unsigned int*)addr); + err |= get_user(call, (unsigned int*)(addr+4)); + err |= get_user(nop, (unsigned int*)(addr+8)); + if (err) + break; + + if (save == 0x9DE3BFA8U && + (call & 0xC0000000U) == 0x40000000U && + nop == 0x01000000U) + { + struct vm_area_struct *vma; + unsigned long call_dl_resolve; + + down_read(¤t->mm->mmap_sem); + call_dl_resolve = current->mm->call_dl_resolve; + up_read(¤t->mm->mmap_sem); + if (likely(call_dl_resolve)) + goto emulate; + + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + + down_write(¤t->mm->mmap_sem); + if (current->mm->call_dl_resolve) { + call_dl_resolve = current->mm->call_dl_resolve; + up_write(¤t->mm->mmap_sem); + if (vma) kmem_cache_free(vm_area_cachep, vma); + goto emulate; + } + + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); + if (!vma || (call_dl_resolve & ~PAGE_MASK)) { + up_write(¤t->mm->mmap_sem); + if (vma) kmem_cache_free(vm_area_cachep, vma); + return 1; + } + + if (pax_insert_vma(vma, call_dl_resolve)) { + up_write(¤t->mm->mmap_sem); + kmem_cache_free(vm_area_cachep, vma); + return 1; + } + + current->mm->call_dl_resolve = call_dl_resolve; + up_write(¤t->mm->mmap_sem); + +emulate: + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10; + regs->pc = call_dl_resolve; + regs->npc = addr+4; + return 3; + } + } + } while (0); + + do { /* PaX: unpatched PLT emulation step 2 */ + unsigned int save, call, nop; + + err = get_user(save, (unsigned int*)(regs->pc-4)); + err |= get_user(call, (unsigned int*)regs->pc); + err |= get_user(nop, (unsigned int*)(regs->pc+4)); + if (err) + break; + + if (save == 0x9DE3BFA8U && + (call & 0xC0000000U) == 0x40000000U && + nop == 0x01000000U) + { + unsigned int dl_resolve = regs->pc + ((((call | 0xC0000000U) ^ 0x20000000U) + 0x20000000U) << 2); + + regs->u_regs[UREG_RETPC] = regs->pc; + regs->pc = dl_resolve; + regs->npc = dl_resolve+4; + return 3; + } + } while (0); +#endif + + return 1; +} + +void pax_report_insns(void *pc, void *sp) +{ + unsigned long i; + + printk(KERN_ERR "PAX: bytes at PC: "); + for (i = 0; i < 5; i++) { + unsigned int c; + if (get_user(c, (unsigned int*)pc+i)) + printk("???????? "); + else + printk("%08x ", c); + } + printk("\n"); +} +#endif + asmlinkage void do_sparc_fault(struct pt_regs *regs, int text_fault, int write, unsigned long address) { @@ -282,6 +527,24 @@ good_area: if(!(vma->vm_flags & VM_WRITE)) goto bad_area; } else { + +#ifdef CONFIG_PAX_PAGEEXEC + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && text_fault && !(vma->vm_flags & VM_EXEC)) { + up_read(&mm->mmap_sem); + switch (pax_handle_fetch_fault(regs)) { + +#ifdef CONFIG_PAX_EMUPLT + case 2: + case 3: + return; +#endif + + } + pax_report_fault(regs, (void*)regs->pc, (void*)regs->u_regs[UREG_FP]); + do_exit(SIGKILL); + } +#endif + /* Allow reads even for write-only mappings */ if(!(vma->vm_flags & (VM_READ | VM_EXEC))) goto bad_area; diff -urNp linux-2.4.37.7/arch/sparc/mm/init.c linux-2.4.37.7/arch/sparc/mm/init.c --- linux-2.4.37.7/arch/sparc/mm/init.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc/mm/init.c 2009-11-10 19:30:27.000000000 -0500 @@ -350,17 +350,17 @@ void __init paging_init(void) /* Initialize the protection map with non-constant, MMU dependent values. */ protection_map[0] = PAGE_NONE; - protection_map[1] = PAGE_READONLY; - protection_map[2] = PAGE_COPY; - protection_map[3] = PAGE_COPY; + protection_map[1] = PAGE_READONLY_NOEXEC; + protection_map[2] = PAGE_COPY_NOEXEC; + protection_map[3] = PAGE_COPY_NOEXEC; protection_map[4] = PAGE_READONLY; protection_map[5] = PAGE_READONLY; protection_map[6] = PAGE_COPY; protection_map[7] = PAGE_COPY; protection_map[8] = PAGE_NONE; - protection_map[9] = PAGE_READONLY; - protection_map[10] = PAGE_SHARED; - protection_map[11] = PAGE_SHARED; + protection_map[9] = PAGE_READONLY_NOEXEC; + protection_map[10] = PAGE_SHARED_NOEXEC; + protection_map[11] = PAGE_SHARED_NOEXEC; protection_map[12] = PAGE_READONLY; protection_map[13] = PAGE_READONLY; protection_map[14] = PAGE_SHARED; diff -urNp linux-2.4.37.7/arch/sparc/mm/srmmu.c linux-2.4.37.7/arch/sparc/mm/srmmu.c --- linux-2.4.37.7/arch/sparc/mm/srmmu.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc/mm/srmmu.c 2009-11-10 19:30:27.000000000 -0500 @@ -2047,6 +2047,13 @@ void __init ld_mmu_srmmu(void) BTFIXUPSET_INT(page_shared, pgprot_val(SRMMU_PAGE_SHARED)); BTFIXUPSET_INT(page_copy, pgprot_val(SRMMU_PAGE_COPY)); BTFIXUPSET_INT(page_readonly, pgprot_val(SRMMU_PAGE_RDONLY)); + +#ifdef CONFIG_PAX_PAGEEXEC + BTFIXUPSET_INT(page_shared_noexec, pgprot_val(SRMMU_PAGE_SHARED_NOEXEC)); + BTFIXUPSET_INT(page_copy_noexec, pgprot_val(SRMMU_PAGE_COPY_NOEXEC)); + BTFIXUPSET_INT(page_readonly_noexec, pgprot_val(SRMMU_PAGE_RDONLY_NOEXEC)); +#endif + BTFIXUPSET_INT(page_kernel, pgprot_val(SRMMU_PAGE_KERNEL)); page_kernel = pgprot_val(SRMMU_PAGE_KERNEL); pg_iobits = SRMMU_VALID | SRMMU_WRITE | SRMMU_REF; diff -urNp linux-2.4.37.7/arch/sparc64/config.in linux-2.4.37.7/arch/sparc64/config.in --- linux-2.4.37.7/arch/sparc64/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc64/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -320,3 +320,11 @@ endmenu source crypto/Config.in source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urNp linux-2.4.37.7/arch/sparc64/kernel/ioctl32.c linux-2.4.37.7/arch/sparc64/kernel/ioctl32.c --- linux-2.4.37.7/arch/sparc64/kernel/ioctl32.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc64/kernel/ioctl32.c 2009-11-10 19:30:27.000000000 -0500 @@ -2053,7 +2053,11 @@ static int vt_check(struct file *file) * To have permissions to do most of the vt ioctls, we either have * to be the owner of the tty, or super-user. */ +#ifdef CONFIG_GRKERNSEC + if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG)) +#else if (current->tty == tty || suser()) +#endif return 1; return 0; } diff -urNp linux-2.4.37.7/arch/sparc64/kernel/ptrace.c linux-2.4.37.7/arch/sparc64/kernel/ptrace.c --- linux-2.4.37.7/arch/sparc64/kernel/ptrace.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc64/kernel/ptrace.c 2009-11-10 19:30:27.000000000 -0500 @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -161,6 +162,11 @@ asmlinkage void do_ptrace(struct pt_regs goto out; } + if (gr_handle_ptrace(child, (long)request)) { + pt_error_return(regs, EPERM); + goto out_tsk; + } + if ((current->personality == PER_SUNOS && request == PTRACE_SUNATTACH) || (current->personality != PER_SUNOS && request == PTRACE_ATTACH)) { if (ptrace_attach(child)) { diff -urNp linux-2.4.37.7/arch/sparc64/kernel/setup.c linux-2.4.37.7/arch/sparc64/kernel/setup.c --- linux-2.4.37.7/arch/sparc64/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc64/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -690,7 +690,7 @@ static void c_stop(struct seq_file *m, v { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { start: c_start, next: c_next, stop: c_stop, diff -urNp linux-2.4.37.7/arch/sparc64/kernel/sys_sparc32.c linux-2.4.37.7/arch/sparc64/kernel/sys_sparc32.c --- linux-2.4.37.7/arch/sparc64/kernel/sys_sparc32.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc64/kernel/sys_sparc32.c 2009-11-10 19:30:27.000000000 -0500 @@ -53,6 +53,8 @@ #include #include #include +#include +#include #include #include @@ -3274,8 +3276,18 @@ do_execve32(char * filename, u32 * argv, struct file * file; int retval; int i; +#ifdef CONFIG_GRKERNSEC + struct file *old_exec_file; + struct acl_subject_label *old_acl; + struct rlimit old_rlim[RLIM_NLIMITS]; +#endif bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); + +#ifdef CONFIG_PAX_RANDUSTACK + bprm.p -= (net_random() & ~(sizeof(void *)-1)) & ~PAGE_MASK; +#endif + memset(bprm.page, 0, MAX_ARG_PAGES * sizeof(bprm.page[0])); file = open_exec(filename); @@ -3284,6 +3296,20 @@ do_execve32(char * filename, u32 * argv, if (IS_ERR(file)) return retval; + gr_learn_resource(current, RLIMIT_NPROC, atomic_read(¤t->user->processes), 1); + + if (gr_handle_nproc()) { + allow_write_access(file); + fput(file); + return -EAGAIN; + } + + if (!gr_acl_handle_execve(file->f_dentry, file->f_vfsmnt)) { + allow_write_access(file); + fput(file); + return -EACCES; + } + bprm.file = file; bprm.filename = filename; bprm.sh_bang = 0; @@ -3304,11 +3330,24 @@ do_execve32(char * filename, u32 * argv, if (retval < 0) goto out; + if(!gr_tpe_allow(file)) { + retval = -EACCES; + goto out; + } + + if (gr_check_crash_exec(file)) { + retval = -EACCES; + goto out; + } + retval = copy_strings_kernel(1, &bprm.filename, &bprm); if (retval < 0) goto out; bprm.exec = bprm.p; + + gr_log_chroot_exec(file->f_dentry, file->f_vfsmnt); + retval = copy_strings32(bprm.envc, envp, &bprm); if (retval < 0) goto out; @@ -3317,11 +3356,35 @@ do_execve32(char * filename, u32 * argv, if (retval < 0) goto out; +#ifdef CONFIG_GRKERNSEC + old_acl = current->acl; + memcpy(old_rlim, current->rlim, sizeof(old_rlim)); + old_exec_file = current->exec_file; + get_file(file); + current->exec_file = file; +#endif + + retval = gr_set_proc_label(file->f_dentry, file->f_vfsmnt); + if (retval < 0) + goto out_fail; + retval = search_binary_handler(&bprm, regs); - if (retval >= 0) + if (retval >= 0) { +#ifdef CONFIG_GRKERNSEC + if (old_exec_file) + fput(old_exec_file); +#endif /* execve success */ return retval; + } +out_fail: +#ifdef CONFIG_GRKERNSEC + current->acl = old_acl; + memcpy(current->rlim, old_rlim, sizeof(old_rlim)); + fput(current->exec_file); + current->exec_file = old_exec_file; +#endif out: /* Something went wrong, return the inode and free the argument pages*/ allow_write_access(bprm.file); diff -urNp linux-2.4.37.7/arch/sparc64/kernel/sys_sparc.c linux-2.4.37.7/arch/sparc64/kernel/sys_sparc.c --- linux-2.4.37.7/arch/sparc64/kernel/sys_sparc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc64/kernel/sys_sparc.c 2009-11-10 19:30:27.000000000 -0500 @@ -63,6 +63,13 @@ unsigned long arch_get_unmapped_area(str task_size = 0xf0000000UL; if (len > task_size || len > -PAGE_OFFSET) return -ENOMEM; + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_BASE + current->mm->delta_mmap; + else +#endif + if (!addr) addr = TASK_UNMAPPED_BASE; diff -urNp linux-2.4.37.7/arch/sparc64/mm/fault.c linux-2.4.37.7/arch/sparc64/mm/fault.c --- linux-2.4.37.7/arch/sparc64/mm/fault.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc64/mm/fault.c 2009-11-10 19:30:27.000000000 -0500 @@ -16,6 +16,9 @@ #include #include #include +#include +#include +#include #include #include @@ -306,6 +309,369 @@ cannot_handle: unhandled_fault (address, current, regs); } +#ifdef CONFIG_PAX_PAGEEXEC +#ifdef CONFIG_PAX_EMUPLT +static void pax_emuplt_close(struct vm_area_struct * vma) +{ + vma->vm_mm->call_dl_resolve = 0UL; +} + +static struct page* pax_emuplt_nopage(struct vm_area_struct *vma, unsigned long address, int write_access) +{ + struct page* page; + unsigned int *kaddr; + + page = alloc_page(GFP_HIGHUSER); + if (!page) + return page; + + kaddr = kmap(page); + memset(kaddr, 0, PAGE_SIZE); + kaddr[0] = 0x9DE3BFA8U; /* save */ + flush_dcache_page(page); + kunmap(page); + return page; +} + +static const struct vm_operations_struct pax_vm_ops = { + .close = pax_emuplt_close, + .nopage = pax_emuplt_nopage, +}; + +static int pax_insert_vma(struct vm_area_struct *vma, unsigned long addr) +{ + int ret; + + memset(vma, 0, sizeof(*vma)); + vma->vm_mm = current->mm; + vma->vm_start = addr; + vma->vm_end = addr + PAGE_SIZE; + vma->vm_flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYEXEC; + vma->vm_page_prot = protection_map[vma->vm_flags & 0x0f]; + vma->vm_ops = &pax_vm_ops; + + ret = insert_vm_struct(current->mm, vma); + if (ret) + return ret; + + ++current->mm->total_vm; + return 0; +} +#endif + +/* + * PaX: decide what to do with offenders (regs->tpc = fault address) + * + * returns 1 when task should be killed + * 2 when patched PLT trampoline was detected + * 3 when unpatched PLT trampoline was detected + */ +static int pax_handle_fetch_fault(struct pt_regs *regs) +{ + +#ifdef CONFIG_PAX_EMUPLT + int err; + + do { /* PaX: patched PLT emulation #1 */ + unsigned int sethi1, sethi2, jmpl; + + err = get_user(sethi1, (unsigned int*)regs->tpc); + err |= get_user(sethi2, (unsigned int*)(regs->tpc+4)); + err |= get_user(jmpl, (unsigned int*)(regs->tpc+8)); + + if (err) + break; + + if ((sethi1 & 0xFFC00000U) == 0x03000000U && + (sethi2 & 0xFFC00000U) == 0x03000000U && + (jmpl & 0xFFFFE000U) == 0x81C06000U) + { + unsigned long addr; + + regs->u_regs[UREG_G1] = (sethi2 & 0x003FFFFFU) << 10; + addr = regs->u_regs[UREG_G1]; + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL); + regs->tpc = addr; + regs->tnpc = addr+4; + return 2; + } + } while (0); + + { /* PaX: patched PLT emulation #2 */ + unsigned int ba; + + err = get_user(ba, (unsigned int*)regs->tpc); + + if (!err && (ba & 0xFFC00000U) == 0x30800000U) { + unsigned long addr; + + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2); + regs->tpc = addr; + regs->tnpc = addr+4; + return 2; + } + } + + do { /* PaX: patched PLT emulation #3 */ + unsigned int sethi, jmpl, nop; + + err = get_user(sethi, (unsigned int*)regs->tpc); + err |= get_user(jmpl, (unsigned int*)(regs->tpc+4)); + err |= get_user(nop, (unsigned int*)(regs->tpc+8)); + + if (err) + break; + + if ((sethi & 0xFFC00000U) == 0x03000000U && + (jmpl & 0xFFFFE000U) == 0x81C06000U && + nop == 0x01000000U) + { + unsigned long addr; + + addr = (sethi & 0x003FFFFFU) << 10; + regs->u_regs[UREG_G1] = addr; + addr += (((jmpl | 0xFFFFFFFFFFFFE000UL) ^ 0x00001000UL) + 0x00001000UL); + regs->tpc = addr; + regs->tnpc = addr+4; + return 2; + } + } while (0); + + do { /* PaX: patched PLT emulation #4 */ + unsigned int mov1, call, mov2; + + err = get_user(mov1, (unsigned int*)regs->tpc); + err |= get_user(call, (unsigned int*)(regs->tpc+4)); + err |= get_user(mov2, (unsigned int*)(regs->tpc+8)); + + if (err) + break; + + if (mov1 == 0x8210000FU && + (call & 0xC0000000U) == 0x40000000U && + mov2 == 0x9E100001U) + { + unsigned long addr; + + regs->u_regs[UREG_G1] = regs->u_regs[UREG_RETPC]; + addr = regs->tpc + 4 + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2); + regs->tpc = addr; + regs->tnpc = addr+4; + return 2; + } + } while (0); + + do { /* PaX: patched PLT emulation #5 */ + unsigned int sethi1, sethi2, or1, or2, sllx, jmpl, nop; + + err = get_user(sethi1, (unsigned int*)regs->tpc); + err |= get_user(sethi2, (unsigned int*)(regs->tpc+4)); + err |= get_user(or1, (unsigned int*)(regs->tpc+8)); + err |= get_user(or2, (unsigned int*)(regs->tpc+12)); + err |= get_user(sllx, (unsigned int*)(regs->tpc+16)); + err |= get_user(jmpl, (unsigned int*)(regs->tpc+20)); + err |= get_user(nop, (unsigned int*)(regs->tpc+24)); + + if (err) + break; + + if ((sethi1 & 0xFFC00000U) == 0x03000000U && + (sethi2 & 0xFFC00000U) == 0x0B000000U && + (or1 & 0xFFFFE000U) == 0x82106000U && + (or2 & 0xFFFFE000U) == 0x8A116000U && + sllx == 0x83287020 && + jmpl == 0x81C04005U && + nop == 0x01000000U) + { + unsigned long addr; + + regs->u_regs[UREG_G1] = ((sethi1 & 0x003FFFFFU) << 10) | (or1 & 0x000003FFU); + regs->u_regs[UREG_G1] <<= 32; + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or2 & 0x000003FFU); + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5]; + regs->tpc = addr; + regs->tnpc = addr+4; + return 2; + } + } while (0); + + do { /* PaX: patched PLT emulation #6 */ + unsigned int sethi1, sethi2, sllx, or, jmpl, nop; + + err = get_user(sethi1, (unsigned int*)regs->tpc); + err |= get_user(sethi2, (unsigned int*)(regs->tpc+4)); + err |= get_user(sllx, (unsigned int*)(regs->tpc+8)); + err |= get_user(or, (unsigned int*)(regs->tpc+12)); + err |= get_user(jmpl, (unsigned int*)(regs->tpc+16)); + err |= get_user(nop, (unsigned int*)(regs->tpc+20)); + + if (err) + break; + + if ((sethi1 & 0xFFC00000U) == 0x03000000U && + (sethi2 & 0xFFC00000U) == 0x0B000000U && + sllx == 0x83287020 && + (or & 0xFFFFE000U) == 0x8A116000U && + jmpl == 0x81C04005U && + nop == 0x01000000U) + { + unsigned long addr; + + regs->u_regs[UREG_G1] = (sethi1 & 0x003FFFFFU) << 10; + regs->u_regs[UREG_G1] <<= 32; + regs->u_regs[UREG_G5] = ((sethi2 & 0x003FFFFFU) << 10) | (or & 0x3FFU); + addr = regs->u_regs[UREG_G1] + regs->u_regs[UREG_G5]; + regs->tpc = addr; + regs->tnpc = addr+4; + return 2; + } + } while (0); + + do { /* PaX: patched PLT emulation #7 */ + unsigned int sethi, ba, nop; + + err = get_user(sethi, (unsigned int*)regs->tpc); + err |= get_user(ba, (unsigned int*)(regs->tpc+4)); + err |= get_user(nop, (unsigned int*)(regs->tpc+8)); + + if (err) + break; + + if ((sethi & 0xFFC00000U) == 0x03000000U && + (ba & 0xFFF00000U) == 0x30600000U && + nop == 0x01000000U) + { + unsigned long addr; + + addr = (sethi & 0x003FFFFFU) << 10; + regs->u_regs[UREG_G1] = addr; + addr = regs->tpc + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2); + regs->tpc = addr; + regs->tnpc = addr+4; + return 2; + } + } while (0); + + do { /* PaX: unpatched PLT emulation step 1 */ + unsigned int sethi, ba, nop; + + err = get_user(sethi, (unsigned int*)regs->tpc); + err |= get_user(ba, (unsigned int*)(regs->tpc+4)); + err |= get_user(nop, (unsigned int*)(regs->tpc+8)); + + if (err) + break; + + if ((sethi & 0xFFC00000U) == 0x03000000U && + ((ba & 0xFFC00000U) == 0x30800000U || (ba & 0xFFF80000U) == 0x30680000U) && + nop == 0x01000000U) + { + unsigned long addr; + unsigned int save, call; + + if ((ba & 0xFFC00000U) == 0x30800000U) + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFC00000UL) ^ 0x00200000UL) + 0x00200000UL) << 2); + else + addr = regs->tpc + 4 + ((((ba | 0xFFFFFFFFFFF80000UL) ^ 0x00040000UL) + 0x00040000UL) << 2); + + err = get_user(save, (unsigned int*)addr); + err |= get_user(call, (unsigned int*)(addr+4)); + err |= get_user(nop, (unsigned int*)(addr+8)); + + if (err) + break; + + if (save == 0x9DE3BFA8U && + (call & 0xC0000000U) == 0x40000000U && + nop == 0x01000000U) + { + struct vm_area_struct *vma; + unsigned long call_dl_resolve; + + down_read(¤t->mm->mmap_sem); + call_dl_resolve = current->mm->call_dl_resolve; + up_read(¤t->mm->mmap_sem); + if (likely(call_dl_resolve)) + goto emulate; + + vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL); + + down_write(¤t->mm->mmap_sem); + if (current->mm->call_dl_resolve) { + call_dl_resolve = current->mm->call_dl_resolve; + up_write(¤t->mm->mmap_sem); + if (vma) kmem_cache_free(vm_area_cachep, vma); + goto emulate; + } + + call_dl_resolve = get_unmapped_area(NULL, 0UL, PAGE_SIZE, 0UL, MAP_PRIVATE); + if (!vma || (call_dl_resolve & ~PAGE_MASK)) { + up_write(¤t->mm->mmap_sem); + if (vma) kmem_cache_free(vm_area_cachep, vma); + return 1; + } + + if (pax_insert_vma(vma, call_dl_resolve)) { + up_write(¤t->mm->mmap_sem); + kmem_cache_free(vm_area_cachep, vma); + return 1; + } + + current->mm->call_dl_resolve = call_dl_resolve; + up_write(¤t->mm->mmap_sem); + +emulate: + regs->u_regs[UREG_G1] = (sethi & 0x003FFFFFU) << 10; + regs->tpc = call_dl_resolve; + regs->tnpc = addr+4; + return 3; + } + } + } while (0); + + do { /* PaX: unpatched PLT emulation step 2 */ + unsigned int save, call, nop; + + err = get_user(save, (unsigned int*)(regs->tpc-4)); + err |= get_user(call, (unsigned int*)regs->tpc); + err |= get_user(nop, (unsigned int*)(regs->tpc+4)); + + if (err) + break; + + if (save == 0x9DE3BFA8U && + (call & 0xC0000000U) == 0x40000000U && + nop == 0x01000000U) + { + unsigned long dl_resolve = regs->tpc + ((((call | 0xFFFFFFFFC0000000UL) ^ 0x20000000UL) + 0x20000000UL) << 2); + + regs->u_regs[UREG_RETPC] = regs->tpc; + regs->tpc = dl_resolve; + regs->tnpc = dl_resolve+4; + return 3; + } + } while (0); +#endif + + return 1; +} + +void pax_report_insns(void *pc, void *sp) +{ + unsigned long i; + + printk(KERN_ERR "PAX: bytes at PC: "); + for (i = 0; i < 5; i++) { + unsigned int c; + if (get_user(c, (unsigned int*)pc+i)) + printk("???????? "); + else + printk("%08x ", c); + } + printk("\n"); +} +#endif + asmlinkage void do_sparc64_fault(struct pt_regs *regs) { struct mm_struct *mm = current->mm; @@ -345,6 +711,7 @@ asmlinkage void do_sparc64_fault(struct if ((current->thread.flags & SPARC_FLAG_32BIT) != 0) { regs->tpc &= 0xffffffff; + regs->tnpc &= 0xffffffff; address &= 0xffffffff; } @@ -353,6 +720,29 @@ asmlinkage void do_sparc64_fault(struct if (!vma) goto bad_area; +#ifdef CONFIG_PAX_PAGEEXEC + /* PaX: detect ITLB misses on non-exec pages */ + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && vma->vm_start <= address && + !(vma->vm_flags & VM_EXEC) && (fault_code & FAULT_CODE_ITLB)) + { + if (address != regs->tpc) + goto good_area; + + up_read(&mm->mmap_sem); + switch (pax_handle_fetch_fault(regs)) { + +#ifdef CONFIG_PAX_EMUPLT + case 2: + case 3: + goto fault_done; +#endif + + } + pax_report_fault(regs, (void*)regs->tpc, (void*)(regs->u_regs[UREG_FP] + STACK_BIAS)); + do_exit(SIGKILL); + } +#endif + /* Pure DTLB misses do not tell us whether the fault causing * load/store/atomic was a write or not, it only says that there * was no match. So in such a case we (carefully) read the diff -urNp linux-2.4.37.7/arch/sparc64/solaris/socksys.c linux-2.4.37.7/arch/sparc64/solaris/socksys.c --- linux-2.4.37.7/arch/sparc64/solaris/socksys.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/sparc64/solaris/socksys.c 2009-11-10 19:30:27.000000000 -0500 @@ -49,7 +49,7 @@ extern void mykfree(void *); static unsigned int (*sock_poll)(struct file *, poll_table *); -static struct file_operations socksys_file_ops = { +static const struct file_operations socksys_file_ops = { /* Currently empty */ }; @@ -156,7 +156,7 @@ static unsigned int socksys_poll(struct return mask; } -static struct file_operations socksys_fops = { +static const struct file_operations socksys_fops = { open: socksys_open, release: socksys_release, }; diff -urNp linux-2.4.37.7/arch/x86_64/config.in linux-2.4.37.7/arch/x86_64/config.in --- linux-2.4.37.7/arch/x86_64/config.in 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/x86_64/config.in 2009-11-10 19:30:27.000000000 -0500 @@ -262,3 +262,11 @@ int 'Kernel messages buffer length shift endmenu source lib/Config.in + +mainmenu_option next_comment +comment 'Grsecurity' +bool 'Grsecurity' CONFIG_GRKERNSEC +if [ "$CONFIG_GRKERNSEC" = "y" ]; then + source grsecurity/Config.in +fi +endmenu diff -urNp linux-2.4.37.7/arch/x86_64/ia32/ia32_binfmt.c linux-2.4.37.7/arch/x86_64/ia32/ia32_binfmt.c --- linux-2.4.37.7/arch/x86_64/ia32/ia32_binfmt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/x86_64/ia32/ia32_binfmt.c 2009-11-10 19:30:27.000000000 -0500 @@ -28,7 +28,14 @@ struct elf_phdr; #define ELF_NAME "elf/i386" -#define IA32_STACK_TOP IA32_PAGE_OFFSET +#ifdef CONFIG_PAX_RANDUSTACK +#define __IA32_DELTA_STACK (current->mm->delta_stack) +#else +#define __IA32_DELTA_STACK 0UL +#endif + +#define IA32_STACK_TOP (IA32_PAGE_OFFSET - __IA32_DELTA_STACK) + #define ELF_ET_DYN_BASE (IA32_PAGE_OFFSET/3 + 0x1000000) #undef ELF_ARCH @@ -129,6 +136,13 @@ struct elf_prpsinfo #include #include +#ifdef CONFIG_PAX_ASLR +#define PAX_ELF_ET_DYN_BASE 0x08048000UL + +#define PAX_DELTA_MMAP_LEN 16 +#define PAX_DELTA_STACK_LEN 16 +#endif + typedef struct user_i387_ia32_struct elf_fpregset_t; typedef struct user32_fxsr_struct elf_fpxregset_t; @@ -218,7 +232,7 @@ static void elf32_init(struct pt_regs *r me->thread.flags |= THREAD_IA32; } -extern void put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long address); +extern int put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long address); int ia32_setup_arg_pages(struct linux_binprm *bprm) @@ -243,7 +257,13 @@ int ia32_setup_arg_pages(struct linux_bi mpnt->vm_mm = current->mm; mpnt->vm_start = PAGE_MASK & (unsigned long) bprm->p; mpnt->vm_end = IA32_STACK_TOP; - mpnt->vm_flags = vm_stack_flags32; + +#ifdef CONFIG_PAX_PAGEEXEC + mpnt->vm_flags = VM_STACK_FLAGS; +#else + mpnt->vm_flags = vm_stack_flags32; +#endif + mpnt->vm_page_prot = (mpnt->vm_flags & VM_EXEC) ? PAGE_COPY_EXEC : PAGE_COPY; mpnt->vm_ops = NULL; @@ -260,16 +280,18 @@ int ia32_setup_arg_pages(struct linux_bi for (i = 0 ; i < MAX_ARG_PAGES ; i++) { struct page *page = bprm->page[i]; + int retval; if (page) { bprm->page[i] = NULL; - current->mm->rss++; - put_dirty_page(current,page,stack_base); + retval = put_dirty_page(current,page,stack_base); + if (!ret) + ret = retval; } stack_base += PAGE_SIZE; } up_write(¤t->mm->mmap_sem); - - return 0; + + return ret; } static unsigned long elf32_map (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type) @@ -277,8 +299,10 @@ elf32_map (struct file *filep, unsigned unsigned long map_addr; struct task_struct *me = current; +#ifndef CONFIG_PAX_PAGEEXEC if (prot & PROT_READ) prot |= PROT_EXEC; +#endif down_write(&me->mm->mmap_sem); map_addr = do_mmap(filep, ELF_PAGESTART(addr), diff -urNp linux-2.4.37.7/arch/x86_64/ia32/ia32_ioctl.c linux-2.4.37.7/arch/x86_64/ia32/ia32_ioctl.c --- linux-2.4.37.7/arch/x86_64/ia32/ia32_ioctl.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/x86_64/ia32/ia32_ioctl.c 2009-11-10 19:30:27.000000000 -0500 @@ -1963,7 +1963,11 @@ static int vt_check(struct file *file) * To have permissions to do most of the vt ioctls, we either have * to be the owner of the tty, or super-user. */ +#ifdef CONFIG_GRKERNSEC + if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG)) +#else if (current->tty == tty || suser()) +#endif return 1; return 0; } diff -urNp linux-2.4.37.7/arch/x86_64/ia32/sys_ia32.c linux-2.4.37.7/arch/x86_64/ia32/sys_ia32.c --- linux-2.4.37.7/arch/x86_64/ia32/sys_ia32.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/x86_64/ia32/sys_ia32.c 2009-11-10 19:30:27.000000000 -0500 @@ -333,8 +333,11 @@ sys32_mmap(struct mmap_arg_struct *arg) return -EBADF; } + +#ifndef CONFIG_PAX_PAGEEXEC if (a.prot & PROT_READ) a.prot |= PROT_EXEC; +#endif mm = current->mm; down_write(&mm->mmap_sem); @@ -351,8 +354,12 @@ extern asmlinkage long sys_mprotect(unsi asmlinkage long sys32_mprotect(unsigned long start, size_t len, unsigned long prot) { + +#ifndef CONFIG_PAX_PAGEEXEC if (prot & PROT_READ) prot |= PROT_EXEC; +#endif + return sys_mprotect(start,len,prot); } @@ -2121,8 +2128,10 @@ asmlinkage long sys32_mmap2(unsigned lon return -EBADF; } +#ifndef CONFIG_PAX_PAGEEXEC if (prot & PROT_READ) prot |= PROT_EXEC; +#endif down_write(&mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags|MAP_32BIT, pgoff); diff -urNp linux-2.4.37.7/arch/x86_64/kernel/cpuid.c linux-2.4.37.7/arch/x86_64/kernel/cpuid.c --- linux-2.4.37.7/arch/x86_64/kernel/cpuid.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/x86_64/kernel/cpuid.c 2009-11-10 19:30:27.000000000 -0500 @@ -133,7 +133,7 @@ static int cpuid_open(struct inode *inod /* * File operations we support */ -static struct file_operations cpuid_fops = { +static const struct file_operations cpuid_fops = { owner: THIS_MODULE, llseek: cpuid_seek, read: cpuid_read, diff -urNp linux-2.4.37.7/arch/x86_64/kernel/ioport.c linux-2.4.37.7/arch/x86_64/kernel/ioport.c --- linux-2.4.37.7/arch/x86_64/kernel/ioport.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/x86_64/kernel/ioport.c 2009-11-10 19:30:27.000000000 -0500 @@ -38,8 +38,16 @@ asmlinkage long sys_ioperm(unsigned long if ((from + num <= from) || (from + num > IO_BITMAP_SIZE*32)) return -EINVAL; + +#ifdef CONFIG_GRKERNSEC_IO + if (turn_on) { + gr_handle_ioperm(); + return -EPERM; + } +#else if (turn_on && !capable(CAP_SYS_RAWIO)) return -EPERM; +#endif /* * If it's the first ioperm() call in this thread's lifetime, set the * IO bitmap up. ioperm() is much less timing critical than clone(), @@ -89,8 +97,13 @@ asmlinkage long sys_iopl(unsigned int le return -EINVAL; /* Trying to gain more privileges? */ if (level > old) { +#ifdef CONFIG_GRKERNSEC_IO + gr_handle_iopl(); + return -EPERM; +#else if (!capable(CAP_SYS_RAWIO)) return -EPERM; +#endif } regs->eflags = (regs->eflags &~ 0x3000UL) | (level << 12); return 0; diff -urNp linux-2.4.37.7/arch/x86_64/kernel/msr.c linux-2.4.37.7/arch/x86_64/kernel/msr.c --- linux-2.4.37.7/arch/x86_64/kernel/msr.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/x86_64/kernel/msr.c 2009-11-10 19:30:27.000000000 -0500 @@ -240,7 +240,7 @@ static int msr_open(struct inode *inode, /* * File operations we support */ -static struct file_operations msr_fops = { +static const struct file_operations msr_fops = { owner: THIS_MODULE, llseek: msr_seek, read: msr_read, diff -urNp linux-2.4.37.7/arch/x86_64/kernel/mtrr.c linux-2.4.37.7/arch/x86_64/kernel/mtrr.c --- linux-2.4.37.7/arch/x86_64/kernel/mtrr.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/x86_64/kernel/mtrr.c 2009-11-10 19:30:27.000000000 -0500 @@ -981,6 +981,9 @@ static ssize_t mtrr_write (struct file * char *ptr; char line[LINE_SIZE]; + if (len == 0) + return -EINVAL; + if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1208,7 +1211,7 @@ static int mtrr_close (struct inode *ino } -static struct file_operations mtrr_fops = { +static const struct file_operations mtrr_fops = { owner: THIS_MODULE, read: mtrr_read, write: mtrr_write, diff -urNp linux-2.4.37.7/arch/x86_64/kernel/ptrace.c linux-2.4.37.7/arch/x86_64/kernel/ptrace.c --- linux-2.4.37.7/arch/x86_64/kernel/ptrace.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/x86_64/kernel/ptrace.c 2009-11-10 19:30:27.000000000 -0500 @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -206,6 +207,9 @@ asmlinkage long sys_ptrace(long request, if (pid == 1) /* you may not mess with init */ goto out_tsk; + if (gr_handle_ptrace(child, request)) + goto out_tsk; + if (request == PTRACE_ATTACH) { ret = ptrace_attach(child); goto out_tsk; diff -urNp linux-2.4.37.7/arch/x86_64/kernel/setup64.c linux-2.4.37.7/arch/x86_64/kernel/setup64.c --- linux-2.4.37.7/arch/x86_64/kernel/setup64.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/x86_64/kernel/setup64.c 2009-11-10 19:30:27.000000000 -0500 @@ -36,11 +36,18 @@ struct desc_ptr idt_descr = { 256 * 16, correct flags everywhere. */ unsigned long __supported_pte_mask = ~0UL; static int do_not_nx __initdata = 0; -unsigned long vm_stack_flags = __VM_STACK_FLAGS; -unsigned long vm_stack_flags32 = __VM_STACK_FLAGS; + +#ifdef CONFIG_PAX_PAGEEXEC +unsigned long vm_stack_flags = __VM_DATA_DEFAULT_FLAGS; +unsigned long vm_stack_flags32 = __VM_DATA_DEFAULT_FLAGS; +#else +unsigned long vm_stack_flags = __VM_STACK_FLAGS; +unsigned long vm_stack_flags32 = __VM_STACK_FLAGS; +#endif + unsigned long vm_data_default_flags = __VM_DATA_DEFAULT_FLAGS; unsigned long vm_data_default_flags32 = __VM_DATA_DEFAULT_FLAGS; -unsigned long vm_force_exec32 = PROT_EXEC; +unsigned long vm_force_exec32 = 0; char boot_cpu_stack[IRQSTACKSIZE] __cacheline_aligned; diff -urNp linux-2.4.37.7/arch/x86_64/kernel/setup.c linux-2.4.37.7/arch/x86_64/kernel/setup.c --- linux-2.4.37.7/arch/x86_64/kernel/setup.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/x86_64/kernel/setup.c 2009-11-10 19:30:27.000000000 -0500 @@ -913,7 +913,7 @@ static void c_stop(struct seq_file *m, v { } -struct seq_operations cpuinfo_op = { +const struct seq_operations cpuinfo_op = { start: c_start, next: c_next, stop: c_stop, diff -urNp linux-2.4.37.7/arch/x86_64/kernel/signal.c linux-2.4.37.7/arch/x86_64/kernel/signal.c --- linux-2.4.37.7/arch/x86_64/kernel/signal.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/x86_64/kernel/signal.c 2009-11-10 19:30:27.000000000 -0500 @@ -144,7 +144,7 @@ restore_sigcontext(struct pt_regs *regs, COPY(rdx); COPY(rcx); COPY(rip); if (regs->rip >= TASK_SIZE && regs->rip < VSYSCALL_START) { - regs->rip = 0; + regs->rip = ~0UL; return -EFAULT; } COPY(r8); @@ -361,7 +361,7 @@ static void setup_rt_frame(int sig, stru if (regs->rip >= TASK_SIZE) { if (sig == SIGSEGV) ka->sa.sa_handler = SIG_DFL; - regs->rip = 0; + regs->rip = ~0UL; } regs->cs = __USER_CS; regs->ss = __USER_DS; diff -urNp linux-2.4.37.7/arch/x86_64/kernel/sys_x86_64.c linux-2.4.37.7/arch/x86_64/kernel/sys_x86_64.c --- linux-2.4.37.7/arch/x86_64/kernel/sys_x86_64.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/x86_64/kernel/sys_x86_64.c 2009-11-10 19:30:27.000000000 -0500 @@ -72,6 +72,13 @@ unsigned long arch_get_unmapped_area(str unsigned long end = TASK_SIZE; if (current->thread.flags & THREAD_IA32) { + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_32 + current->mm->delta_mmap; + else +#endif + if (!addr) addr = TASK_UNMAPPED_32; end = 0xffff0000; @@ -82,10 +89,24 @@ unsigned long arch_get_unmapped_area(str base down for this case. This may give conflicts with the heap, but we assume that malloc falls back to mmap. Give it 1GB of playground for now. -AK */ + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = 0x40000000 + (current->mm->delta_mmap & 0x0FFFFFFFU); + else +#endif + if (!addr) addr = 0x40000000; end = 0x80000000; } else { + +#ifdef CONFIG_PAX_RANDMMAP + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && (!addr || filp)) + addr = TASK_UNMAPPED_64 + current->mm->delta_mmap; + else +#endif + if (!addr) addr = TASK_UNMAPPED_64; end = TASK_SIZE; diff -urNp linux-2.4.37.7/arch/x86_64/mm/fault.c linux-2.4.37.7/arch/x86_64/mm/fault.c --- linux-2.4.37.7/arch/x86_64/mm/fault.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/arch/x86_64/mm/fault.c 2009-11-10 19:30:27.000000000 -0500 @@ -173,6 +173,33 @@ static int is_prefetch(struct pt_regs *r return prefetch; } +#ifdef CONFIG_PAX_PAGEEXEC +void pax_report_insns(void *pc, void *sp) +{ + long i; + + printk(KERN_ERR "PAX: bytes at PC: "); + for (i = 0; i < 20; i++) { + unsigned int c; + if (get_user(c, (unsigned char*)pc+i)) + printk("???????? "); + else + printk("%08x ", c); + } + printk("\n"); + + printk(KERN_ERR "PAX: bytes at SP-8: "); + for (i = -1; i < 10; i++) { + unsigned long c; + if (get_user(c, (unsigned long*)sp+i)) + printk("???????????????? "); + else + printk("%16lx ", c); + } + printk("\n"); +} +#endif + int page_fault_trace; int exception_trace = 1; @@ -267,6 +294,15 @@ again: * we can handle it.. */ good_area: + +#ifdef CONFIG_PAX_PAGEEXEC + if ((mm->pax_flags & MF_PAX_PAGEEXEC) && (error_code & 16) && !(vma->vm_flags & VM_EXEC)) { + up_read(&mm->mmap_sem); + pax_report_fault(regs, (void*)regs->rip, (void*)regs->rsp); + do_exit(SIGKILL); + } +#endif + info.si_code = SEGV_ACCERR; write = 0; switch (error_code & 3) { diff -urNp linux-2.4.37.7/crypto/proc.c linux-2.4.37.7/crypto/proc.c --- linux-2.4.37.7/crypto/proc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/crypto/proc.c 2009-11-10 19:30:27.000000000 -0500 @@ -86,7 +86,7 @@ static int c_show(struct seq_file *m, vo return 0; } -static struct seq_operations crypto_seq_ops = { +static const struct seq_operations crypto_seq_ops = { .start = c_start, .next = c_next, .stop = c_stop, @@ -98,7 +98,7 @@ static int crypto_info_open(struct inode return seq_open(file, &crypto_seq_ops); } -static struct file_operations proc_crypto_ops = { +static const struct file_operations proc_crypto_ops = { .open = crypto_info_open, .read = seq_read, .llseek = seq_lseek, diff -urNp linux-2.4.37.7/Documentation/Configure.help linux-2.4.37.7/Documentation/Configure.help --- linux-2.4.37.7/Documentation/Configure.help 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/Documentation/Configure.help 2009-11-10 19:30:27.000000000 -0500 @@ -23530,6 +23530,933 @@ CONFIG_CF_AREA5 "Area6" will work for most boards. For ADX, select "Area5". +Grsecurity +CONFIG_GRKERNSEC + If you say Y here, you will be able to configure many features that + will enhance the security of your system. It is highly recommended + that you say Y here and read through the help for each option so + you fully understand the features and can evaluate their usefulness + for your machine. + +Additional security levels +CONFIG_GRKERNSEC_LOW + + Low additional security + ----------------------------------------------------------------------- + If you choose this option, several of the grsecurity options will + be enabled that will give you greater protection against a number + of attacks, while assuring that none of your software will have any + conflicts with the additional security measures. If you run a lot of + unusual software, or you are having problems with the higher security + levels, you should say Y here. With this option, the following features + are enabled: + + linking restrictions + fifo restrictions + enforcing nproc on execve() + restricted dmesg + enforced chdir("/") on chroot + runtime module disabling + + Medium additional security + ----------------------------------------------------------------------- + If you say Y here, several features in addition to those included in the + low additional security level will be enabled. These features provide + even more security to your system, though in rare cases they may + be incompatible with very old or poorly written software. If you + enable this option, make sure that your auth service (identd) is + running as gid 10 (usually group wheel). With this option the following + features (in addition to those provided in the low additional security + level) will be enabled: + + random tcp source ports + failed fork logging + time change logging + signal logging + deny mounts in chroot + deny double chrooting + deny sysctl writes in chroot + deny mknod in chroot + deny access to abstract AF_UNIX sockets out of chroot + deny pivot_root in chroot + denied writes of /dev/kmem, /dev/mem, and /dev/port + /proc restrictions with special gid set to 10 (usually wheel) + address space layout randomization + removal of addresses from /proc//[maps|stat] + + High additional security + ---------------------------------------------------------------------- + If you say Y here, many of the features of grsecurity will be enabled, + that will protect you against many kinds of attacks against + your system. The heightened security comes at a cost of an + increased chance of incompatibilities with rare software on your + machine. Since this security level enables PaX, you should view + and read about the PaX project. While + you are there, download chpax and run it on binaries that cause + problems with PaX. Also remember that since the /proc restrictions are + enabled, you must run your identd as group wheel (gid 10). + This security level enables the following features in addition to those + listed in the low and medium security levels: + + additional /proc restrictions + chmod restrictions in chroot + no signals, ptrace, or viewing processes outside of chroot + capability restrictions in chroot + deny fchdir out of chroot + priority restrictions in chroot + segmentation-based implementation of PaX + mprotect restrictions + kernel stack randomization + mount/unmount/remount logging + kernel symbol hiding + destroy unused shared memory + +Customized additional security +CONFIG_GRKERNSEC_CUSTOM + If you say Y here, you will be able to configure every grsecurity + option, which allows you to enable many more features that aren't + covered in the basic security levels. These additional features include + TPE, socket restrictions, and the sysctl system for grsecurity. It is + advised that you read through the help for each option to determine its + usefulness in your situation. + +Support soft mode +CONFIG_PAX_SOFTMODE + Enabling this option will allow you to run PaX in soft mode, that + is, PaX features will not be enforced by default, only on executables + marked explicitly. You must also enable PT_PAX_FLAGS support as it + is the only way to mark executables for soft mode use. + + Soft mode can be activated by using the "pax_softmode=1" kernel command + line option on boot. Furthermore you can control various PaX features + at runtime via the entries in /proc/sys/kernel/pax. + +Use legacy ELF header marking +CONFIG_PAX_EI_PAX + Enabling this option will allow you to control PaX features on + a per executable basis via the 'chpax' utility available at + http://pax.grsecurity.net/. The control flags will be read from + an otherwise reserved part of the ELF header. This marking has + numerous drawbacks (no support for soft-mode, toolchain does not + know about the non-standard use of the ELF header) therefore it + has been deprecated in favour of PT_PAX_FLAGS support. + + If you have applications not marked by the PT_PAX_FLAGS ELF + program header then you MUST enable this option otherwise they + will not get any protection. + + Note that if you enable PT_PAX_FLAGS marking support as well, + the PT_PAX_FLAG marks will override the legacy EI_PAX marks. + +Use ELF program header marking +CONFIG_PAX_PT_PAX_FLAGS + Enabling this option will allow you to control PaX features on + a per executable basis via the 'paxctl' utility available at + http://pax.grsecurity.net/. The control flags will be read from + a PaX specific ELF program header (PT_PAX_FLAGS). This marking + has the benefits of supporting both soft mode and being fully + integrated into the toolchain (the binutils patch is available + from http://pax.grsecurity.net). + + If you have applications not marked by the PT_PAX_FLAGS ELF + program header then you MUST enable the EI_PAX marking support + otherwise they will not get any protection. + + Note that if you enable the legacy EI_PAX marking support as well, + the EI_PAX marks will be overridden by the PT_PAX_FLAGS marks. + +MAC system integration +CONFIG_PAX_NO_ACL_FLAGS + Mandatory Access Control systems have the option of controlling + PaX flags on a per executable basis, choose the method supported + by your particular system. + + - "none": if your MAC system does not interact with PaX, + - "direct": if your MAC system defines pax_set_initial_flags() itself, + - "hook": if your MAC system uses the pax_set_initial_flags_func callback. + + NOTE: this option is for developers/integrators only. + +Enforce non-executable pages +CONFIG_PAX_NOEXEC + By design some architectures do not allow for protecting memory + pages against execution or even if they do, Linux does not make + use of this feature. In practice this means that if a page is + readable (such as the stack or heap) it is also executable. + + There is a well known exploit technique that makes use of this + fact and a common programming mistake where an attacker can + introduce code of his choice somewhere in the attacked program's + memory (typically the stack or the heap) and then execute it. + + If the attacked program was running with different (typically + higher) privileges than that of the attacker, then he can elevate + his own privilege level (e.g. get a root shell, write to files for + which he does not have write access to, etc). + + Enabling this option will let you choose from various features + that prevent the injection and execution of 'foreign' code in + a program. + + This will also break programs that rely on the old behaviour and + expect that dynamically allocated memory via the malloc() family + of functions is executable (which it is not). Notable examples + are the XFree86 4.x server, the java runtime and wine. + +Paging based non-executable pages +CONFIG_PAX_PAGEEXEC + This implementation is based on the paging feature of the CPU. + On i386 it has a variable performance impact on applications + depending on their memory usage pattern. You should carefully + test your applications before using this feature in production. + On alpha, parisc, sparc and sparc64 there is no performance + impact. On ppc there is a slight performance impact. + +Segmentation based non-executable pages +CONFIG_PAX_SEGMEXEC + This implementation is based on the segmentation feature of the + CPU and has little performance impact, however applications will + be limited to a 1.5 GB address space instead of the normal 3 GB. + +Emulate trampolines +CONFIG_PAX_EMUTRAMP + There are some programs and libraries that for one reason or + another attempt to execute special small code snippets from + non-executable memory pages. Most notable examples are the + signal handler return code generated by the kernel itself and + the GCC trampolines. + + If you enabled CONFIG_PAX_PAGEEXEC or + CONFIG_PAX_SEGMEXEC then such programs will no longer + work under your kernel. + + As a remedy you can say Y here and use the 'chpax' or 'paxctl' + utilities to enable trampoline emulation for the affected programs + yet still have the protection provided by the non-executable pages. + + On parisc and ppc you MUST enable this option and EMUSIGRT as + well, otherwise your system will not even boot. + + Alternatively you can say N here and use the 'chpax' or 'paxctl' + utilities to disable CONFIG_PAX_PAGEEXEC and + CONFIG_PAX_SEGMEXEC for the affected files. + + NOTE: enabling this feature *may* open up a loophole in the + protection provided by non-executable pages that an attacker + could abuse. Therefore the best solution is to not have any + files on your system that would require this option. This can + be achieved by not using libc5 (which relies on the kernel + signal handler return code) and not using or rewriting programs + that make use of the nested function implementation of GCC. + Skilled users can just fix GCC itself so that it implements + nested function calls in a way that does not interfere with PaX. + +Automatically emulate sigreturn trampolines +CONFIG_PAX_EMUSIGRT + Enabling this option will have the kernel automatically detect + and emulate signal return trampolines executing on the stack + that would otherwise lead to task termination. + + This solution is intended as a temporary one for users with + legacy versions of libc (libc5, glibc 2.0, uClibc before 0.9.17, + Modula-3 runtime, etc) or executables linked to such, basically + everything that does not specify its own SA_RESTORER function in + normal executable memory like glibc 2.1+ does. + + On parisc and ppc you MUST enable this option, otherwise your + system will not even boot. + + NOTE: this feature cannot be disabled on a per executable basis + and since it *does* open up a loophole in the protection provided + by non-executable pages, the best solution is to not have any + files on your system that would require this option. + +Restrict mprotect() +CONFIG_PAX_MPROTECT + Enabling this option will prevent programs from + - changing the executable status of memory pages that were + not originally created as executable, + - making read-only executable pages writable again, + - creating executable pages from anonymous memory. + + You should say Y here to complete the protection provided by + the enforcement of non-executable pages. + + NOTE: you can use the 'chpax' utility to control this + feature on a per file basis. chpax is available at + + +Disallow ELF text relocations +CONFIG_PAX_NOELFRELOCS + Non-executable pages and mprotect() restrictions are effective + in preventing the introduction of new executable code into an + attacked task's address space. There remain only two venues + for this kind of attack: if the attacker can execute already + existing code in the attacked task then he can either have it + create and mmap() a file containing his code or have it mmap() + an already existing ELF library that does not have position + independent code in it and use mprotect() on it to make it + writable and copy his code there. While protecting against + the former approach is beyond PaX, the latter can be prevented + by having only PIC ELF libraries on one's system (which do not + need to relocate their code). If you are sure this is your case, + then enable this option otherwise be careful as you may not even + be able to boot or log on your system (for example, some PAM + modules are erroneously compiled as non-PIC by default). + + NOTE: if you are using dynamic ELF executables (as suggested + when using ASLR) then you must have made sure that you linked + your files using the PIC version of crt1 (the et_dyn.zip package + referenced there has already been updated to support this). + +Enforce non-executable kernel pages +CONFIG_PAX_KERNEXEC + This is the kernel land equivalent of PAGEEXEC and MPROTECT, + that is, enabling this option will make it harder to inject + and execute 'foreign' code in kernel memory itself. + +Address Space Layout Randomization +CONFIG_PAX_ASLR + Many if not most exploit techniques rely on the knowledge of + certain addresses in the attacked program. The following options + will allow the kernel to apply a certain amount of randomization + to specific parts of the program thereby forcing an attacker to + guess them in most cases. Any failed guess will most likely crash + the attacked program which allows the kernel to detect such attempts + and react on them. PaX itself provides no reaction mechanisms, + instead it is strongly encouraged that you make use of grsecurity's + built-in crash detection features or develop one yourself. + + By saying Y here you can choose to randomize the following areas: + - top of the task's kernel stack + - top of the task's userland stack + - base address for mmap() requests that do not specify one + (this includes all libraries) + - base address of the main executable + + It is strongly recommended to say Y here as address space layout + randomization has negligible impact on performance yet it provides + a very effective protection. + + NOTE: you can use the 'chpax' or 'paxctl' utilities to control most + of these features on a per file basis. + +Randomize kernel stack base +CONFIG_PAX_RANDKSTACK + By saying Y here the kernel will randomize every task's kernel + stack on every system call. This will not only force an attacker + to guess it but also prevent him from making use of possible + leaked information about it. + + Since the kernel stack is a rather scarce resource, randomization + may cause unexpected stack overflows, therefore you should very + carefully test your system. Note that once enabled in the kernel + configuration, this feature cannot be disabled on a per file basis. + +Randomize user stack base +CONFIG_PAX_RANDUSTACK + By saying Y here the kernel will randomize every task's userland + stack. The randomization is done in two steps where the second + one may apply a big amount of shift to the top of the stack and + cause problems for programs that want to use lots of memory (more + than 2.5 GB if SEGMEXEC is not active, or 1.25 GB when it is). + For this reason the second step can be controlled by 'chpax' or + 'paxctl' on a per file basis. + +Allow ELF ET_EXEC text relocations +CONFIG_PAX_ETEXECRELOCS + On some architectures like the alpha there are incorrectly + created applications that require text relocations and would + not work without enabling this option. If you are an alpha + user, you should enable this option and disable it once you + have made sure that none of your applications need it. + +Automatically emulate ELF PLT +CONFIG_PAX_EMUPLT + Enabling this option will have the kernel automatically detect + and emulate the Procedure Linkage Table entries in ELF files. + On some architectures such entries are in writable memory, and + become non-executable leading to task termination. Therefore + it is mandatory that you enable this option on alpha, parisc, ppc, + sparc and sparc64, otherwise your system would not even boot. + + NOTE: this feature *does* open up a loophole in the protection + provided by the non-executable pages, therefore the proper + solution is to modify the toolchain to produce a PLT that does + not need to be writable. + +Randomize mmap() base +CONFIG_PAX_RANDMMAP + By saying Y here the kernel will use a randomized base address for + mmap() requests that do not specify one themselves. As a result + all dynamically loaded libraries will appear at random addresses + and therefore be harder to exploit by a technique where an attacker + attempts to execute library code for his purposes (e.g. spawn a + shell from an exploited program that is running at an elevated + privilege level). + + Furthermore, if a program is relinked as a dynamic ELF file, its + base address will be randomized as well, completing the full + randomization of the address space layout. Attacking such programs + becomes a guess game. You can find an example of doing this at + and practical samples at + . + + NOTE: you can use the 'chpax' or 'paxctl' utilities to control this + feature on a per file basis. + +Deny writing to /dev/kmem, /dev/mem, and /dev/port +CONFIG_GRKERNSEC_KMEM + If you say Y here, /dev/kmem and /dev/mem won't be allowed to + be written to via mmap or otherwise to modify the running kernel. + /dev/port will also not be allowed to be opened. If you have module + support disabled, enabling this will close up four ways that are + currently used to insert malicious code into the running kernel. + Even with all these features enabled, we still highly recommend that + you use the RBAC system, as it is still possible for an attacker to + modify the running kernel through privileged I/O granted by ioperm/iopl. + If you are not using XFree86, you may be able to stop this additional + case by enabling the 'Disable privileged I/O' option. Though nothing + legitimately writes to /dev/kmem, XFree86 does need to write to /dev/mem, + but only to video memory, which is the only writing we allow in this + case. If /dev/kmem or /dev/mem are mmaped without PROT_WRITE, they will + not be allowed to mprotect it with PROT_WRITE later. + It is highly recommended that you say Y here if you meet all the + conditions above. + +Disable privileged I/O +CONFIG_GRKERNSEC_IO + If you say Y here, all ioperm and iopl calls will return an error. + Ioperm and iopl can be used to modify the running kernel. + Unfortunately, some programs need this access to operate properly, + the most notable of which are XFree86 and hwclock. hwclock can be + remedied by having RTC support in the kernel, so CONFIG_RTC is + enabled if this option is enabled, to ensure that hwclock operates + correctly. XFree86 still will not operate correctly with this option + enabled, so DO NOT CHOOSE Y IF YOU USE XFree86. If you use XFree86 + and you still want to protect your kernel against modification, + use the RBAC system. + +Runtime module disabling +CONFIG_GRKERNSEC_MODSTOP + If you say Y here, you will be able to disable the ability to (un)load + modules at runtime. This feature is useful if you need the ability + to load kernel modules at boot time, but do not want to allow an + attacker to load a rootkit kernel module into the system, or to remove + a loaded kernel module important to system functioning. You should + enable the /dev/mem protection feature as well, since rootkits can be + inserted into the kernel via other methods than kernel modules. Since + an untrusted module could still be loaded by modifying init scripts and + rebooting the system, it is also recommended that you enable the RBAC + system. If you enable this option, a sysctl option with name + "disable_modules" will be created. Setting this option to "1" disables + module loading. After this option is set, no further writes to it are + allowed until the system is rebooted. + +Hide kernel symbols +CONFIG_GRKERNSEC_HIDESYM + If you say Y here, getting information on loaded modules, and + displaying all kernel symbols through a syscall will be restricted + to users with CAP_SYS_MODULE. This option is only effective + provided the following conditions are met: + 1) The kernel using grsecurity is not precompiled by some distribution + 2) You are using the RBAC system and hiding other files such as your + kernel image and System.map + 3) You have the additional /proc restrictions enabled, which removes + /proc/kcore + If the above conditions are met, this option will aid to provide a + useful protection against local and remote kernel exploitation of + overflows and arbitrary read/write vulnerabilities. + +Deter exploit bruteforcing +CONFIG_GRKERNSEC_BRUTE + If you say Y here, attempts to bruteforce exploits against forking + daemons such as apache or sshd will be deterred. When a child of a + forking daemon is killed by PaX or crashes due to an illegal + instruction, the parent process will be delayed 30 seconds upon every + subsequent fork until the administrator is able to assess the + situation and restart the daemon. It is recommended that you also + enable signal logging in the auditing section so that logs are + generated when a process performs an illegal instruction. + +/proc//ipaddr support +CONFIG_GRKERNSEC_PROC_IPADDR + If you say Y here, a new entry will be added to each /proc/ + directory that contains the IP address of the person using the task. + The IP is carried across local TCP and AF_UNIX stream sockets. + This information can be useful for IDS/IPSes to perform remote response + to a local attack. The entry is readable by only the owner of the + process (and root if he has CAP_DAC_OVERRIDE, which can be removed via + the RBAC system), and thus does not create privacy concerns. + +Proc Restrictions +CONFIG_GRKERNSEC_PROC + If you say Y here, the permissions of the /proc filesystem + will be altered to enhance system security and privacy. You MUST + choose either a user only restriction or a user and group restriction. + Depending upon the option you choose, you can either restrict users to + see only the processes they themselves run, or choose a group that can + view all processes and files normally restricted to root if you choose + the "restrict to user only" option. NOTE: If you're running identd as + a non-root user, you will have to run it as the group you specify here. + +Restrict /proc to user only +CONFIG_GRKERNSEC_PROC_USER + If you say Y here, non-root users will only be able to view their own + processes, and restricts them from viewing network-related information, + and viewing kernel symbol and module information. + +Restrict /proc to user and group +CONFIG_GRKERNSEC_PROC_USERGROUP + If you say Y here, you will be able to select a group that will be + able to view all processes, network-related information, and + kernel and symbol information. This option is useful if you want + to run identd as a non-root user. + +Harden kernel heap management +CONFIG_GRKERNSEC_KHEAP + If you say Y here, the kernel heap management routines will be + modified to provide greater resilience against kernel heap + exploitation. Specifically, this option prevents allocated + shared memory IPC structures from being targeted by the only public + technique for reliable kernel heap exploitation. + +Remove addresses from /proc/pid/[maps|stat] +CONFIG_GRKERNSEC_PROC_MEMMAP + If you say Y here, the /proc//maps and /proc//stat files will + give no information about the addresses of its mappings if + PaX features that rely on random addresses are enabled on the task. + If you use PaX it is greatly recommended that you say Y here as it + closes up a hole that makes the full ASLR useless for suid + binaries. + +Additional proc restrictions +CONFIG_GRKERNSEC_PROC_ADD + If you say Y here, additional restrictions will be placed on + /proc that keep normal users from viewing device information and + slabinfo information that could be useful for exploits. + +Dmesg(8) Restriction +CONFIG_GRKERNSEC_DMESG + If you say Y here, non-root users will not be able to use dmesg(8) + to view up to the last 4kb of messages in the kernel's log buffer. + If the sysctl option is enabled, a sysctl option with name "dmesg" is + created. + +Destroy unused shared memory +CONFIG_GRKERNSEC_SHM + If you say Y here, shared memory will be destroyed when no one is + attached to it. Otherwise, resources involved with the shared + memory can be used up and not be associated with any process (as the + shared memory still exists, and the creating process has exited). If + the sysctl option is enabled, a sysctl option with name + "destroy_unused_shm" is created. + +Linking restrictions +CONFIG_GRKERNSEC_LINK + If you say Y here, /tmp race exploits will be prevented, since users + will no longer be able to follow symlinks owned by other users in + world-writable +t directories (i.e. /tmp), unless the owner of the + symlink is the owner of the directory. users will also not be + able to hardlink to files they do not own. If the sysctl option is + enabled, a sysctl option with name "linking_restrictions" is created. + +FIFO restrictions +CONFIG_GRKERNSEC_FIFO + If you say Y here, users will not be able to write to FIFOs they don't + own in world-writable +t directories (i.e. /tmp), unless the owner of + the FIFO is the same owner of the directory it's held in. If the sysctl + option is enabled, a sysctl option with name "fifo_restrictions" is + created. + +Enforce RLIMIT_NPROC on execs +CONFIG_GRKERNSEC_EXECVE + If you say Y here, users with a resource limit on processes will + have the value checked during execve() calls. The current system + only checks the system limit during fork() calls. If the sysctl option + is enabled, a sysctl option with name "execve_limiting" is created. + +Single group for auditing +CONFIG_GRKERNSEC_AUDIT_GROUP + If you say Y here, the exec, chdir, (un)mount, and ipc logging features + will only operate on a group you specify. This option is recommended + if you only want to watch certain users instead of having a large + amount of logs from the entire system. If the sysctl option is enabled, + a sysctl option with name "audit_group" is created. + +GID for auditing +CONFIG_GRKERNSEC_AUDIT_GID + Here you can choose the GID that will be the target of kernel auditing. + Remember to add the users you want to log to the GID specified here. + If the sysctl option is enabled, a sysctl option with name "audit_gid" + is created. + +Chdir logging +CONFIG_GRKERNSEC_AUDIT_CHDIR + If you say Y here, all chdir() calls will be logged. If the sysctl + option is enabled, a sysctl option with name "audit_chdir" is created. + +(Un)Mount logging +CONFIG_GRKERNSEC_AUDIT_MOUNT + If you say Y here, all mounts and unmounts will be logged. If the + sysctl option is enabled, a sysctl option with name "audit_mount" is + created. + +IPC logging +CONFIG_GRKERNSEC_AUDIT_IPC + If you say Y here, creation and removal of message queues, semaphores, + and shared memory will be logged. If the sysctl option is enabled, a + sysctl option with name "audit_ipc" is created. + +Exec logging +CONFIG_GRKERNSEC_EXECLOG + If you say Y here, all execve() calls will be logged (since the + other exec*() calls are frontends to execve(), all execution + will be logged). Useful for shell-servers that like to keep track + of their users. If the sysctl option is enabled, a sysctl option with + name "exec_logging" is created. + WARNING: This option when enabled will produce a LOT of logs, especially + on an active system. + +Resource logging +CONFIG_GRKERNSEC_RESLOG + If you say Y here, all attempts to overstep resource limits will + be logged with the resource name, the requested size, and the current + limit. It is highly recommended that you say Y here. If the sysctl + option is enabled, a sysctl option with name "resource_logging" is + created. If the RBAC system is enabled, the sysctl value is ignored. + +Signal logging +CONFIG_GRKERNSEC_SIGNAL + If you say Y here, certain important signals will be logged, such as + SIGSEGV, which will as a result inform you of when a error in a program + occurred, which in some cases could mean a possible exploit attempt. + If the sysctl option is enabled, a sysctl option with name + "signal_logging" is created. + +Fork failure logging +CONFIG_GRKERNSEC_FORKFAIL + If you say Y here, all failed fork() attempts will be logged. + This could suggest a fork bomb, or someone attempting to overstep + their process limit. If the sysctl option is enabled, a sysctl option + with name "forkfail_logging" is created. + +Time change logging +CONFIG_GRKERNSEC_TIME + If you say Y here, any changes of the system clock will be logged. + If the sysctl option is enabled, a sysctl option with name + "timechange_logging" is created. + +ELF text relocations logging +CONFIG_GRKERNSEC_AUDIT_TEXTREL + If you say Y here, text relocations will be logged with the filename + of the offending library or binary. The purpose of the feature is + to help Linux distribution developers get rid of libraries and + binaries that need text relocations which hinder the future progress + of PaX. Only Linux distribution developers should say Y here, and + never on a production machine, as this option creates an information + leak that could aid an attacker in defeating the randomization of + a single memory region. If the sysctl option is enabled, a sysctl + option with name "audit_textrel" is created. + +Chroot jail restrictions +CONFIG_GRKERNSEC_CHROOT + If you say Y here, you will be able to choose several options that will + make breaking out of a chrooted jail much more difficult. If you + encounter no software incompatibilities with the following options, it + is recommended that you enable each one. + +Deny access to abstract AF_UNIX sockets out of chroot +CONFIG_GRKERNSEC_CHROOT_UNIX + If you say Y here, processes inside a chroot will not be able to + connect to abstract (meaning not belonging to a filesystem) Unix + domain sockets that were bound outside of a chroot. It is recommended + that you say Y here. If the sysctl option is enabled, a sysctl option + with name "chroot_deny_unix" is created. + +Deny shmat() out of chroot +CONFIG_GRKERNSEC_CHROOT_SHMAT + If you say Y here, processes inside a chroot will not be able to attach + to shared memory segments that were created outside of the chroot jail. + It is recommended that you say Y here. If the sysctl option is enabled, + a sysctl option with name "chroot_deny_shmat" is created. + +Protect outside processes +CONFIG_GRKERNSEC_CHROOT_FINDTASK + If you say Y here, processes inside a chroot will not be able to + kill, send signals with fcntl, ptrace, capget, getpgid, setpgid, getsid, + getsid, or view any process outside of the chroot. If the sysctl option + is enabled, a sysctl option with name "chroot_findtask" is created. + +Deny mounts in chroot +CONFIG_GRKERNSEC_CHROOT_MOUNT + If you say Y here, processes inside a chroot will not be able to + mount or remount filesystems. If the sysctl option is enabled, a + sysctl option with name "chroot_deny_mount" is created. + +Deny pivot_root in chroot +CONFIG_GRKERNSEC_CHROOT_PIVOT + If you say Y here, processes inside a chroot will not be able to use + a function called pivot_root() that was introduced in Linux 2.3.41. It + works similar to chroot in that it changes the root filesystem. This + function could be misused in a chrooted process to attempt to break out + of the chroot, and therefore should not be allowed. If the sysctl + option is enabled, a sysctl option with name "chroot_deny_pivot" is + created. + +Deny double-chroots +CONFIG_GRKERNSEC_CHROOT_DOUBLE + If you say Y here, processes inside a chroot will not be able to chroot + again outside of the chroot. This is a widely used method of breaking + out of a chroot jail and should not be allowed. If the sysctl option + is enabled, a sysctl option with name "chroot_deny_chroot" is created. + +Deny fchdir outside of chroot +CONFIG_GRKERNSEC_CHROOT_FCHDIR + If you say Y here, a well-known method of breaking chroots by fchdir'ing + to a file descriptor of the chrooting process that points to a directory + outside the filesystem will be stopped. If the sysctl option + is enabled, a sysctl option with name "chroot_deny_fchdir" is created. + +Enforce chdir("/") on all chroots +CONFIG_GRKERNSEC_CHROOT_CHDIR + If you say Y here, the current working directory of all newly-chrooted + applications will be set to the the root directory of the chroot. + The man page on chroot(2) states: + Note that this call does not change the current working + directory, so that `.' can be outside the tree rooted at + `/'. In particular, the super-user can escape from a + `chroot jail' by doing `mkdir foo; chroot foo; cd ..'. + + It is recommended that you say Y here, since it's not known to break + any software. If the sysctl option is enabled, a sysctl option with + name "chroot_enforce_chdir" is created. + +Deny (f)chmod +s in chroot +CONFIG_GRKERNSEC_CHROOT_CHMOD + If you say Y here, processes inside a chroot will not be able to chmod + or fchmod files to make them have suid or sgid bits. This protects + against another published method of breaking a chroot. If the sysctl + option is enabled, a sysctl option with name "chroot_deny_chmod" is + created. + +Deny mknod in chroot +CONFIG_GRKERNSEC_CHROOT_MKNOD + If you say Y here, processes inside a chroot will not be allowed to + mknod. The problem with using mknod inside a chroot is that it + would allow an attacker to create a device entry that is the same + as one on the physical root of your system, which could range from + anything from the console device to a device for your harddrive (which + they could then use to wipe the drive or steal data). It is recommended + that you say Y here, unless you run into software incompatibilities. + If the sysctl option is enabled, a sysctl option with name + "chroot_deny_mknod" is created. + +Restrict priority changes in chroot +CONFIG_GRKERNSEC_CHROOT_NICE + If you say Y here, processes inside a chroot will not be able to raise + the priority of processes in the chroot, or alter the priority of + processes outside the chroot. This provides more security than simply + removing CAP_SYS_NICE from the process' capability set. If the + sysctl option is enabled, a sysctl option with name "chroot_restrict_nice" + is created. + +Log all execs within chroot +CONFIG_GRKERNSEC_CHROOT_EXECLOG + If you say Y here, all executions inside a chroot jail will be logged + to syslog. This can cause a large amount of logs if certain + applications (eg. djb's daemontools) are installed on the system, and + is therefore left as an option. If the sysctl option is enabled, a + sysctl option with name "chroot_execlog" is created. + +Deny sysctl writes in chroot +CONFIG_GRKERNSEC_CHROOT_SYSCTL + If you say Y here, an attacker in a chroot will not be able to + write to sysctl entries, either by sysctl(2) or through a /proc + interface. It is strongly recommended that you say Y here. If the + sysctl option is enabled, a sysctl option with name + "chroot_deny_sysctl" is created. + +Chroot jail capability restrictions +CONFIG_GRKERNSEC_CHROOT_CAPS + If you say Y here, the capabilities on all root processes within a + chroot jail will be lowered to stop module insertion, raw i/o, + system and net admin tasks, rebooting the system, modifying immutable + files, modifying IPC owned by another, and changing the system time. + This is left an option because it can break some apps. Disable this + if your chrooted apps are having problems performing those kinds of + tasks. If the sysctl option is enabled, a sysctl option with + name "chroot_caps" is created. + +Trusted path execution +CONFIG_GRKERNSEC_TPE + If you say Y here, you will be able to choose a gid to add to the + supplementary groups of users you want to mark as "untrusted." + These users will not be able to execute any files that are not in + root-owned directories writable only by root. If the sysctl option + is enabled, a sysctl option with name "tpe" is created. + +Invert GID option +CONFIG_GRKERNSEC_TPE_INVERT + If you say Y here, the group you specify in the TPE configuration will + decide what group TPE restrictions will be *disabled* for. This + option is useful if you want TPE restrictions to be applied to most + users on the system. + +Group for trusted path execution +CONFIG_GRKERNSEC_TPE_GID + If you have selected the "Invert GID option" above, setting this + GID determines what group TPE restrictions will be *disabled* for. + If you have not selected the "Invert GID option" above, setting this + GID determines what group TPE restrictions will be *enabled* for. + If the sysctl option is enabled, a sysctl option with name "tpe_gid" + is created. + +Partially restrict non-root users +CONFIG_GRKERNSEC_TPE_ALL + If you say Y here, All non-root users other than the ones in the + group specified in the main TPE option will only be allowed to + execute files in directories they own that are not group or + world-writable, or in directories owned by root and writable only by + root. If the sysctl option is enabled, a sysctl option with name + "tpe_restrict_all" is created. + +Larger entropy pools +CONFIG_GRKERNSEC_RANDNET + If you say Y here, the entropy pools used for many features of Linux + and grsecurity will be doubled in size. Since several grsecurity + features use additional randomness, it is recommended that you say Y + here. Saying Y here has a similar effect as modifying + /proc/sys/kernel/random/poolsize. + +TCP/UDP blackhole +CONFIG_GRKERNSEC_BLACKHOLE + If you say Y here, neither TCP resets nor ICMP + destination-unreachable packets will be sent in response to packets + send to ports for which no associated listening process exists. + This feature supports both IPV4 and IPV6 and exempts the + loopback interface from blackholing. Enabling this feature + makes a host more resilient to DoS attacks and reduces network + visibility against scanners. + +Socket restrictions +CONFIG_GRKERNSEC_SOCKET + If you say Y here, you will be able to choose from several options. + If you assign a GID on your system and add it to the supplementary + groups of users you want to restrict socket access to, this patch + will perform up to three things, based on the option(s) you choose. + +Deny all socket access +CONFIG_GRKERNSEC_SOCKET_ALL + If you say Y here, you will be able to choose a GID of whose users will + be unable to connect to other hosts from your machine or run server + applications from your machine. If the sysctl option is enabled, a + sysctl option with name "socket_all" is created. + +Group for disabled socket access +CONFIG_GRKERNSEC_SOCKET_ALL_GID + Here you can choose the GID to disable socket access for. Remember to + add the users you want socket access disabled for to the GID + specified here. If the sysctl option is enabled, a sysctl option with + name "socket_all_gid" is created. + +Deny all client socket access +CONFIG_GRKERNSEC_SOCKET_CLIENT + If you say Y here, you will be able to choose a GID of whose users will + be unable to connect to other hosts from your machine, but will be + able to run servers. If this option is enabled, all users in the group + you specify will have to use passive mode when initiating ftp transfers + from the shell on your machine. If the sysctl option is enabled, a + sysctl option with name "socket_client" is created. + +Group for disabled client socket access +CONFIG_GRKERNSEC_SOCKET_CLIENT_GID + Here you can choose the GID to disable client socket access for. + Remember to add the users you want client socket access disabled for to + the GID specified here. If the sysctl option is enabled, a sysctl + option with name "socket_client_gid" is created. + +Deny all server socket access +CONFIG_GRKERNSEC_SOCKET_SERVER + If you say Y here, you will be able to choose a GID of whose users will + be unable to run server applications from your machine. If the sysctl + option is enabled, a sysctl option with name "socket_server" is created. + +Group for disabled server socket access +CONFIG_GRKERNSEC_SOCKET_SERVER_GID + Here you can choose the GID to disable server socket access for. + Remember to add the users you want server socket access disabled for to + the GID specified here. If the sysctl option is enabled, a sysctl + option with name "socket_server_gid" is created. + +Sysctl support +CONFIG_GRKERNSEC_SYSCTL + If you say Y here, you will be able to change the options that + grsecurity runs with at bootup, without having to recompile your + kernel. You can echo values to files in /proc/sys/kernel/grsecurity + to enable (1) or disable (0) various features. All the sysctl entries + are mutable until the "grsec_lock" entry is set to a non-zero value. + All features enabled in the kernel configuration are disabled at boot + if you do not say Y to the "Turn on features by default" option. + All options should be set at startup, and the grsec_lock entry should + be set to a non-zero value after all the options are set. + *THIS IS EXTREMELY IMPORTANT* + +Turn on features by default +CONFIG_GRKERNSEC_SYSCTL_ON + If you say Y here, instead of having all features enabled in the + kernel configuration disabled at boot time, the features will be + enabled at boot time. It is recommended you say Y here unless + there is some reason you would want all sysctl-tunable features to + be disabled by default. As mentioned elsewhere, it is important + to enable the grsec_lock entry once you have finished modifying + the sysctl entries. + +Number of burst messages +CONFIG_GRKERNSEC_FLOODBURST + This option allows you to choose the maximum number of messages allowed + within the flood time interval you chose in a separate option. The + default should be suitable for most people, however if you find that + many of your logs are being interpreted as flooding, you may want to + raise this value. + +Seconds in between log messages +CONFIG_GRKERNSEC_FLOODTIME + This option allows you to enforce the number of seconds between + grsecurity log messages. The default should be suitable for most + people, however, if you choose to change it, choose a value small enough + to allow informative logs to be produced, but large enough to + prevent flooding. + +Disable RBAC system +CONFIG_GRKERNSEC_NO_RBAC + If you say Y here, the /dev/grsec device will be removed from the kernel, + preventing the RBAC system from being enabled. You should only say Y + here if you have no intention of using the RBAC system, so as to prevent + an attacker with root access from misusing the RBAC system to hide files + and processes when loadable module support and /dev/[k]mem have been + locked down. + +Hide kernel processes +CONFIG_GRKERNSEC_ACL_HIDEKERN + If you say Y here, all kernel threads will be hidden to all + processes but those whose subject has the "view hidden processes" + flag. + +Maximum tries before password lockout +CONFIG_GRKERNSEC_ACL_MAXTRIES + This option enforces the maximum number of times a user can attempt + to authorize themselves with the grsecurity RBAC system before being + denied the ability to attempt authorization again for a specified time. + The lower the number, the harder it will be to brute-force a password. + +Time to wait after max password tries, in seconds +CONFIG_GRKERNSEC_ACL_TIMEOUT + This option specifies the time the user must wait after attempting to + authorize to the RBAC system with the maximum number of invalid + passwords. The higher the number, the harder it will be to brute-force + a password. + Disable data cache CONFIG_DCACHE_DISABLE This option allows you to run the kernel with data cache disabled. @@ -29158,6 +30085,42 @@ CONFIG_SOUND_WM97XX If unsure, say N. +Sanitize all freed memory +CONFIG_PAX_MEMORY_SANITIZE + By saying Y here the kernel will erase memory pages as soon as they + are freed. This in turn reduces the lifetime of data stored in the + pages, making it less likely that sensitive information such as + passwords, cryptographic secrets, etc stay in memory for too long. + + This is especially useful for programs whose runtime is short, long + lived processes and the kernel itself benefit from this as long as + they operate on whole memory pages and ensure timely freeing of pages + that may hold sensitive information. + + The tradeoff is performance impact, on a single CPU system kernel + compilation sees a 3% slowdown, other systems and workloads may vary + and you are advised to test this feature on your expected workload + before deploying it. + + Note that this feature does not protect data stored in live pages, + e.g., process memory swapped to disk may stay there for a long time. + +Prevent invalid userland pointer dereference +CONFIG_PAX_MEMORY_UDEREF + By saying Y here the kernel will be prevented from dereferencing + userland pointers in contexts where the kernel expects only kernel + pointers. This is both a useful runtime debugging feature and a + security measure that prevents exploiting a class of kernel bugs. + + The tradeoff is that some virtualization solutions may experience + a huge slowdown and therefore you should not enable this feature + for kernels meant to run in such environments. Whether a given VM + solution is affected or not is best determined by simply trying it + out, the performance impact will be obvious right on boot as this + mechanism engages from very early on. A good rule of thumb is that + VMs running on CPUs without hardware virtualization support (i.e., + the majority of IA-32 CPUs) will likely experience the slowdown. + # # A couple of things I keep forgetting: # capitalize: AppleTalk, Ethernet, DOS, DMA, FAT, FTP, Internet, diff -urNp linux-2.4.37.7/Documentation/DocBook/mousedrivers.tmpl linux-2.4.37.7/Documentation/DocBook/mousedrivers.tmpl --- linux-2.4.37.7/Documentation/DocBook/mousedrivers.tmpl 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/Documentation/DocBook/mousedrivers.tmpl 2009-11-10 19:30:27.000000000 -0500 @@ -248,7 +248,7 @@ void cleanup_module(void) -struct file_operations our_mouse_fops = { +const struct file_operations our_mouse_fops = { owner: THIS_MODULE, /* Automatic usage management */ read: read_mouse, /* You can read a mouse */ write: write_mouse, /* This won't do a lot */ @@ -894,7 +894,7 @@ static void ourmouse_interrupt(int irq, -struct file_operations our_mouse_fops = { +const struct file_operations our_mouse_fops = { owner: THIS_MODULE read: read_mouse, /* You can read a mouse */ write: write_mouse, /* This won't do a lot */ diff -urNp linux-2.4.37.7/drivers/acorn/char/i2c.c linux-2.4.37.7/drivers/acorn/char/i2c.c --- linux-2.4.37.7/drivers/acorn/char/i2c.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/acorn/char/i2c.c 2009-11-10 19:30:27.000000000 -0500 @@ -200,7 +200,7 @@ static int rtc_ioctl(struct inode *inode return -EINVAL; } -static struct file_operations rtc_fops = { +static const struct file_operations rtc_fops = { ioctl: rtc_ioctl, }; diff -urNp linux-2.4.37.7/drivers/acorn/char/mouse_ps2.c linux-2.4.37.7/drivers/acorn/char/mouse_ps2.c --- linux-2.4.37.7/drivers/acorn/char/mouse_ps2.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/acorn/char/mouse_ps2.c 2009-11-10 19:30:27.000000000 -0500 @@ -249,7 +249,7 @@ static unsigned int aux_poll(struct file return 0; } -struct file_operations psaux_fops = { +const struct file_operations psaux_fops = { read: read_aux, write: write_aux, poll: aux_poll, diff -urNp linux-2.4.37.7/drivers/acpi/system.c linux-2.4.37.7/drivers/acpi/system.c --- linux-2.4.37.7/drivers/acpi/system.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/acpi/system.c 2009-11-10 19:30:27.000000000 -0500 @@ -423,7 +423,7 @@ static int acpi_system_close_event(struc static unsigned int acpi_system_poll_event(struct file *file, poll_table *wait); -static struct file_operations acpi_system_event_ops = { +static const struct file_operations acpi_system_event_ops = { .open = acpi_system_open_event, .read = acpi_system_read_event, .release = acpi_system_close_event, @@ -519,7 +519,7 @@ acpi_system_poll_event( static ssize_t acpi_system_read_dsdt (struct file*, char*, size_t, loff_t*); -static struct file_operations acpi_system_dsdt_ops = { +static const struct file_operations acpi_system_dsdt_ops = { .read = acpi_system_read_dsdt, }; @@ -562,7 +562,7 @@ acpi_system_read_dsdt ( static ssize_t acpi_system_read_fadt (struct file*, char*, size_t, loff_t*); -static struct file_operations acpi_system_fadt_ops = { +static const struct file_operations acpi_system_fadt_ops = { .read = acpi_system_read_fadt, }; diff -urNp linux-2.4.37.7/drivers/block/acsi_slm.c linux-2.4.37.7/drivers/block/acsi_slm.c --- linux-2.4.37.7/drivers/block/acsi_slm.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/block/acsi_slm.c 2009-11-10 19:30:27.000000000 -0500 @@ -272,7 +272,7 @@ static int slm_get_pagesize( int device, static struct timer_list slm_timer = { function: slm_test_ready }; -static struct file_operations slm_fops = { +static const struct file_operations slm_fops = { owner: THIS_MODULE, read: slm_read, write: slm_write, diff -urNp linux-2.4.37.7/drivers/block/genhd.c linux-2.4.37.7/drivers/block/genhd.c --- linux-2.4.37.7/drivers/block/genhd.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/block/genhd.c 2009-11-10 19:30:27.000000000 -0500 @@ -226,7 +226,7 @@ static int part_show(struct seq_file *s, return 0; } -struct seq_operations partitions_op = { +const struct seq_operations partitions_op = { .start = part_start, .next = part_next, .stop = part_stop, diff -urNp linux-2.4.37.7/drivers/block/loop.c linux-2.4.37.7/drivers/block/loop.c --- linux-2.4.37.7/drivers/block/loop.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/block/loop.c 2009-11-10 19:30:27.000000000 -0500 @@ -176,7 +176,7 @@ static int lo_send(struct loop_device *l { struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ struct address_space *mapping = file->f_dentry->d_inode->i_mapping; - struct address_space_operations *aops = mapping->a_ops; + const struct address_space_operations *aops = mapping->a_ops; struct page *page; char *kaddr, *data; unsigned long index; @@ -650,7 +650,7 @@ static int loop_set_fd(struct loop_devic goto out_putf; } } else if (S_ISREG(inode->i_mode)) { - struct address_space_operations *aops = inode->i_mapping->a_ops; + const struct address_space_operations *aops = inode->i_mapping->a_ops; /* * If we can't read - sorry. If we only can't write - well, * it's going to be read-only. diff -urNp linux-2.4.37.7/drivers/block/paride/pg.c linux-2.4.37.7/drivers/block/paride/pg.c --- linux-2.4.37.7/drivers/block/paride/pg.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/block/paride/pg.c 2009-11-10 19:30:27.000000000 -0500 @@ -261,7 +261,7 @@ static char pg_scratch[512]; /* kernel glue structures */ -static struct file_operations pg_fops = { +static const struct file_operations pg_fops = { owner: THIS_MODULE, read: pg_read, write: pg_write, diff -urNp linux-2.4.37.7/drivers/block/paride/pt.c linux-2.4.37.7/drivers/block/paride/pt.c --- linux-2.4.37.7/drivers/block/paride/pt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/block/paride/pt.c 2009-11-10 19:30:27.000000000 -0500 @@ -263,7 +263,7 @@ static char pt_scratch[512]; /* kernel glue structures */ -static struct file_operations pt_fops = { +static const struct file_operations pt_fops = { owner: THIS_MODULE, read: pt_read, write: pt_write, diff -urNp linux-2.4.37.7/drivers/block/rd.c linux-2.4.37.7/drivers/block/rd.c --- linux-2.4.37.7/drivers/block/rd.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/block/rd.c 2009-11-10 19:30:27.000000000 -0500 @@ -151,7 +151,7 @@ static int ramdisk_commit_write(struct f return 0; } -static struct address_space_operations ramdisk_aops = { +static const struct address_space_operations ramdisk_aops = { readpage: ramdisk_readpage, writepage: fail_writepage, prepare_write: ramdisk_prepare_write, @@ -352,7 +352,7 @@ static int initrd_release(struct inode * } -static struct file_operations initrd_fops = { +static const struct file_operations initrd_fops = { read: initrd_read, release: initrd_release, }; diff -urNp linux-2.4.37.7/drivers/bluetooth/hci_vhci.c linux-2.4.37.7/drivers/bluetooth/hci_vhci.c --- linux-2.4.37.7/drivers/bluetooth/hci_vhci.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/bluetooth/hci_vhci.c 2009-11-10 19:30:27.000000000 -0500 @@ -306,7 +306,7 @@ static int hci_vhci_chr_close(struct ino return 0; } -static struct file_operations hci_vhci_fops = { +static const struct file_operations hci_vhci_fops = { owner: THIS_MODULE, llseek: hci_vhci_chr_lseek, read: hci_vhci_chr_read, diff -urNp linux-2.4.37.7/drivers/char/acquirewdt.c linux-2.4.37.7/drivers/char/acquirewdt.c --- linux-2.4.37.7/drivers/char/acquirewdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/acquirewdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -207,7 +207,7 @@ static int acq_notify_sys(struct notifie */ -static struct file_operations acq_fops = { +static const struct file_operations acq_fops = { owner: THIS_MODULE, read: acq_read, write: acq_write, diff -urNp linux-2.4.37.7/drivers/char/advantechwdt.c linux-2.4.37.7/drivers/char/advantechwdt.c --- linux-2.4.37.7/drivers/char/advantechwdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/advantechwdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -246,7 +246,7 @@ advwdt_notify_sys(struct notifier_block * Kernel Interfaces */ -static struct file_operations advwdt_fops = { +static const struct file_operations advwdt_fops = { owner: THIS_MODULE, llseek: no_llseek, write: advwdt_write, diff -urNp linux-2.4.37.7/drivers/char/agp/agpgart_fe.c linux-2.4.37.7/drivers/char/agp/agpgart_fe.c --- linux-2.4.37.7/drivers/char/agp/agpgart_fe.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/agp/agpgart_fe.c 2009-11-10 19:30:27.000000000 -0500 @@ -1075,8 +1075,7 @@ ioctl_out: return ret_val; } -static struct file_operations agp_fops = -{ +static const struct file_operations agp_fops = { owner: THIS_MODULE, llseek: no_llseek, read: agp_read, diff -urNp linux-2.4.37.7/drivers/char/alim1535d_wdt.c linux-2.4.37.7/drivers/char/alim1535d_wdt.c --- linux-2.4.37.7/drivers/char/alim1535d_wdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/alim1535d_wdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -302,7 +302,7 @@ static int __init ali_find_watchdog(void return 0; } -static struct file_operations ali_fops = { +static const struct file_operations ali_fops = { owner: THIS_MODULE, write: ali_write, ioctl: ali_ioctl, diff -urNp linux-2.4.37.7/drivers/char/alim7101_wdt.c linux-2.4.37.7/drivers/char/alim7101_wdt.c --- linux-2.4.37.7/drivers/char/alim7101_wdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/alim7101_wdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -239,7 +239,7 @@ static int fop_ioctl(struct inode *inode } } -static struct file_operations wdt_fops = { +static const struct file_operations wdt_fops = { owner: THIS_MODULE, llseek: no_llseek, read: fop_read, diff -urNp linux-2.4.37.7/drivers/char/amd768_rng.c linux-2.4.37.7/drivers/char/amd768_rng.c --- linux-2.4.37.7/drivers/char/amd768_rng.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/amd768_rng.c 2009-11-10 19:30:27.000000000 -0500 @@ -167,7 +167,7 @@ static ssize_t rng_dev_read (struct file } -static struct file_operations rng_chrdev_ops = { +static const struct file_operations rng_chrdev_ops = { owner: THIS_MODULE, open: rng_dev_open, release: rng_dev_release, diff -urNp linux-2.4.37.7/drivers/char/applicom.c linux-2.4.37.7/drivers/char/applicom.c --- linux-2.4.37.7/drivers/char/applicom.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/applicom.c 2009-11-10 19:30:27.000000000 -0500 @@ -118,7 +118,7 @@ static int ac_ioctl(struct inode *, stru unsigned long); static void ac_interrupt(int, void *, struct pt_regs *); -static struct file_operations ac_fops = { +static const struct file_operations ac_fops = { owner:THIS_MODULE, llseek:no_llseek, read:ac_read, diff -urNp linux-2.4.37.7/drivers/char/au1000_gpio.c linux-2.4.37.7/drivers/char/au1000_gpio.c --- linux-2.4.37.7/drivers/char/au1000_gpio.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/au1000_gpio.c 2009-11-10 19:30:27.000000000 -0500 @@ -235,8 +235,7 @@ static int au1000gpio_ioctl(struct inode } -static struct file_operations au1000gpio_fops = -{ +static const struct file_operations au1000gpio_fops = { owner: THIS_MODULE, ioctl: au1000gpio_ioctl, open: au1000gpio_open, diff -urNp linux-2.4.37.7/drivers/char/au1000_ts.c linux-2.4.37.7/drivers/char/au1000_ts.c --- linux-2.4.37.7/drivers/char/au1000_ts.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/au1000_ts.c 2009-11-10 19:30:27.000000000 -0500 @@ -587,7 +587,7 @@ au1000_release(struct inode * inode, str } -static struct file_operations ts_fops = { +static const struct file_operations ts_fops = { read: au1000_read, poll: au1000_poll, ioctl: au1000_ioctl, diff -urNp linux-2.4.37.7/drivers/char/au1000_usbraw.c linux-2.4.37.7/drivers/char/au1000_usbraw.c --- linux-2.4.37.7/drivers/char/au1000_usbraw.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/au1000_usbraw.c 2009-11-10 19:30:27.000000000 -0500 @@ -457,7 +457,7 @@ static int usbraw_ioctl(struct inode *in } -static struct file_operations usbraw_fops = { +static const struct file_operations usbraw_fops = { owner: THIS_MODULE, write: usbraw_write, read: usbraw_read, diff -urNp linux-2.4.37.7/drivers/char/briq_panel.c linux-2.4.37.7/drivers/char/briq_panel.c --- linux-2.4.37.7/drivers/char/briq_panel.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/briq_panel.c 2009-11-10 19:30:27.000000000 -0500 @@ -168,7 +168,7 @@ static ssize_t do_write(struct file *fil } -static struct file_operations vfd_fops = { +static const struct file_operations vfd_fops = { read: do_read, /* Read */ write: do_write, /* Write */ open: do_open, /* Open */ diff -urNp linux-2.4.37.7/drivers/char/busmouse.c linux-2.4.37.7/drivers/char/busmouse.c --- linux-2.4.37.7/drivers/char/busmouse.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/busmouse.c 2009-11-10 19:30:27.000000000 -0500 @@ -332,8 +332,7 @@ static unsigned int busmouse_poll(struct return 0; } -struct file_operations busmouse_fops= -{ +const struct file_operations busmouse_fops = { owner: THIS_MODULE, read: busmouse_read, write: busmouse_write, diff -urNp linux-2.4.37.7/drivers/char/defkeymap.c linux-2.4.37.7/drivers/char/defkeymap.c --- linux-2.4.37.7/drivers/char/defkeymap.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/defkeymap.c 2009-11-10 19:30:27.000000000 -0500 @@ -18,47 +18,130 @@ u_short plain_map[NR_KEYS] = { 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a, 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, - 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf210, 0xf211, 0xf20e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, }; u_short shift_map[NR_KEYS] = { 0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e, - 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009, + 0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf809, 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, 0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53, 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a, 0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, 0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c, - 0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e, - 0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307, + 0xf703, 0xf020, 0xf207, 0xf10c, 0xf10d, 0xf10e, 0xf10f, 0xf110, + 0xf111, 0xf112, 0xf113, 0xf11e, 0xf11f, 0xf208, 0xf203, 0xf307, 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, - 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a, - 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf120, + 0xf121, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, 0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf206, 0xf206, 0xf210, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, }; u_short altgr_map[NR_KEYS] = { 0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200, 0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200, - 0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, - 0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73, - 0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200, - 0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76, - 0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, + 0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69, + 0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xfb61, 0xfb73, + 0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xfb63, 0xfb76, + 0xfb62, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, 0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510, - 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911, - 0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b, - 0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, + 0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516, 0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf211, 0xf210, 0xf211, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short shift_altgr_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49, + 0xfb4f, 0xfb50, 0xf200, 0xf200, 0xf201, 0xf702, 0xfb41, 0xfb53, + 0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xfb5a, 0xfb58, 0xfb43, 0xfb56, + 0xfb42, 0xfb4e, 0xfb4d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf20e, 0xf20e, 0xf206, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, }; @@ -70,15 +153,31 @@ u_short ctrl_map[NR_KEYS] = { 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, 0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016, 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c, - 0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104, - 0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307, + 0xf703, 0xf000, 0xf207, 0xf122, 0xf123, 0xf124, 0xf125, 0xf126, + 0xf127, 0xf128, 0xf129, 0xf12a, 0xf12b, 0xf208, 0xf204, 0xf307, 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, - 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a, - 0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf12c, + 0xf12d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603, 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, }; u_short shift_ctrl_map[NR_KEYS] = { @@ -88,6 +187,76 @@ u_short shift_ctrl_map[NR_KEYS] = { 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013, 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, 0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf07f, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf12e, 0xf12f, 0xf130, 0xf131, 0xf132, + 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, 0xf208, 0xf200, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf138, + 0xf139, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short altgr_ctrl_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016, + 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short shift_altgr_ctrl_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009, + 0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013, + 0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016, 0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, @@ -98,6 +267,22 @@ u_short shift_ctrl_map[NR_KEYS] = { 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, }; u_short alt_map[NR_KEYS] = { @@ -117,6 +302,127 @@ u_short alt_map[NR_KEYS] = { 0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short shift_alt_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf821, 0xf840, 0xf823, 0xf824, 0xf825, 0xf85e, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf87b, 0xf87d, 0xf201, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf87c, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf83c, 0xf83e, 0xf200, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short altgr_alt_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869, + 0xf86f, 0xf870, 0xf200, 0xf200, 0xf201, 0xf702, 0xf861, 0xf873, + 0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xf87a, 0xf878, 0xf863, 0xf876, + 0xf862, 0xf86e, 0xf86d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short shift_altgr_alt_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf851, 0xf857, 0xf845, 0xf852, 0xf854, 0xf859, 0xf855, 0xf849, + 0xf84f, 0xf850, 0xf200, 0xf200, 0xf201, 0xf702, 0xf841, 0xf853, + 0xf844, 0xf846, 0xf847, 0xf848, 0xf84a, 0xf84b, 0xf84c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xf85a, 0xf858, 0xf843, 0xf856, + 0xf842, 0xf84e, 0xf84d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, }; u_short ctrl_alt_map[NR_KEYS] = { @@ -136,16 +442,137 @@ u_short ctrl_alt_map[NR_KEYS] = { 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c, 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short shift_ctrl_alt_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short altgr_ctrl_alt_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, +}; + +u_short shift_altgr_ctrl_alt_map[NR_KEYS] = { + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809, + 0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813, + 0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200, + 0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816, + 0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c, + 0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307, + 0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301, + 0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603, + 0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116, + 0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, + 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, }; ushort *key_maps[MAX_NR_KEYMAPS] = { - plain_map, shift_map, altgr_map, 0, - ctrl_map, shift_ctrl_map, 0, 0, - alt_map, 0, 0, 0, - ctrl_alt_map, 0 + plain_map, shift_map, altgr_map, shift_altgr_map, + ctrl_map, shift_ctrl_map, altgr_ctrl_map, shift_altgr_ctrl_map, + alt_map, shift_alt_map, altgr_alt_map, shift_altgr_alt_map, + ctrl_alt_map, shift_ctrl_alt_map, altgr_ctrl_alt_map, shift_altgr_ctrl_alt_map, 0 }; -unsigned int keymap_count = 7; +unsigned int keymap_count = 16; /* * Philosophy: most people do not define more strings, but they who do diff -urNp linux-2.4.37.7/drivers/char/drm/drm_drv.h linux-2.4.37.7/drivers/char/drm/drm_drv.h --- linux-2.4.37.7/drivers/char/drm/drm_drv.h 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm/drm_drv.h 2009-11-10 19:30:27.000000000 -0500 @@ -114,7 +114,7 @@ #endif #ifndef DRIVER_FOPS #define DRIVER_FOPS \ -static struct file_operations DRM(fops) = { \ +static const struct file_operations DRM(fops) = { \ .owner = THIS_MODULE, \ .open = DRM(open), \ .flush = DRM(flush), \ diff -urNp linux-2.4.37.7/drivers/char/drm/drm_stub.h linux-2.4.37.7/drivers/char/drm/drm_stub.h --- linux-2.4.37.7/drivers/char/drm/drm_stub.h 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm/drm_stub.h 2009-11-10 19:30:27.000000000 -0500 @@ -65,7 +65,7 @@ static int DRM(stub_open)(struct inode * return err; } -static struct file_operations DRM(stub_fops) = { +static const struct file_operations DRM(stub_fops) = { .owner = THIS_MODULE, .open = DRM(stub_open) }; diff -urNp linux-2.4.37.7/drivers/char/drm/drm_vm.h linux-2.4.37.7/drivers/char/drm/drm_vm.h --- linux-2.4.37.7/drivers/char/drm/drm_vm.h 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm/drm_vm.h 2009-11-10 19:30:27.000000000 -0500 @@ -31,25 +31,25 @@ #include "drmP.h" -struct vm_operations_struct DRM(vm_ops) = { +const struct vm_operations_struct DRM(vm_ops) = { nopage: DRM(vm_nopage), open: DRM(vm_open), close: DRM(vm_close), }; -struct vm_operations_struct DRM(vm_shm_ops) = { +const struct vm_operations_struct DRM(vm_shm_ops) = { nopage: DRM(vm_shm_nopage), open: DRM(vm_open), close: DRM(vm_shm_close), }; -struct vm_operations_struct DRM(vm_dma_ops) = { +const struct vm_operations_struct DRM(vm_dma_ops) = { nopage: DRM(vm_dma_nopage), open: DRM(vm_open), close: DRM(vm_close), }; -struct vm_operations_struct DRM(vm_sg_ops) = { +const struct vm_operations_struct DRM(vm_sg_ops) = { nopage: DRM(vm_sg_nopage), open: DRM(vm_open), close: DRM(vm_close), diff -urNp linux-2.4.37.7/drivers/char/drm/ffb_drv.c linux-2.4.37.7/drivers/char/drm/ffb_drv.c --- linux-2.4.37.7/drivers/char/drm/ffb_drv.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm/ffb_drv.c 2009-11-10 19:30:27.000000000 -0500 @@ -27,7 +27,7 @@ #define DRIVER_PATCHLEVEL 1 #define DRIVER_FOPS \ -static struct file_operations DRM(fops) = { \ +static const struct file_operations DRM(fops) = { \ owner: THIS_MODULE, \ open: DRM(open), \ flush: DRM(flush), \ diff -urNp linux-2.4.37.7/drivers/char/drm/i810_dma.c linux-2.4.37.7/drivers/char/drm/i810_dma.c --- linux-2.4.37.7/drivers/char/drm/i810_dma.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm/i810_dma.c 2009-11-10 19:30:27.000000000 -0500 @@ -131,7 +131,7 @@ static int i810_freelist_put(drm_device_ return 0; } -static struct file_operations i810_buffer_fops = { +static const struct file_operations i810_buffer_fops = { .open = DRM(open), .flush = DRM(flush), .release = DRM(release), diff -urNp linux-2.4.37.7/drivers/char/drm/i830_dma.c linux-2.4.37.7/drivers/char/drm/i830_dma.c --- linux-2.4.37.7/drivers/char/drm/i830_dma.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm/i830_dma.c 2009-11-10 19:30:27.000000000 -0500 @@ -120,7 +120,7 @@ static int i830_freelist_put(drm_device_ return 0; } -static struct file_operations i830_buffer_fops = { +static const struct file_operations i830_buffer_fops = { .open = DRM(open), .flush = DRM(flush), .release = DRM(release), diff -urNp linux-2.4.37.7/drivers/char/drm-4.0/ffb_drv.c linux-2.4.37.7/drivers/char/drm-4.0/ffb_drv.c --- linux-2.4.37.7/drivers/char/drm-4.0/ffb_drv.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm-4.0/ffb_drv.c 2009-11-10 19:30:27.000000000 -0500 @@ -47,7 +47,7 @@ extern int ffb_newctx(struct inode *, st extern int ffb_rmctx(struct inode *, struct file *, unsigned int, unsigned long); extern int ffb_context_switch(drm_device_t *, int, int); -static struct file_operations ffb_fops = { +static const struct file_operations ffb_fops = { owner: THIS_MODULE, open: ffb_open, flush: drm_flush, diff -urNp linux-2.4.37.7/drivers/char/drm-4.0/gamma_drv.c linux-2.4.37.7/drivers/char/drm-4.0/gamma_drv.c --- linux-2.4.37.7/drivers/char/drm-4.0/gamma_drv.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm-4.0/gamma_drv.c 2009-11-10 19:30:27.000000000 -0500 @@ -49,7 +49,7 @@ static drm_device_t gamma_device; -static struct file_operations gamma_fops = { +static const struct file_operations gamma_fops = { #if LINUX_VERSION_CODE >= 0x020400 /* This started being used during 2.4.0-test */ owner: THIS_MODULE, diff -urNp linux-2.4.37.7/drivers/char/drm-4.0/i810_dma.c linux-2.4.37.7/drivers/char/drm-4.0/i810_dma.c --- linux-2.4.37.7/drivers/char/drm-4.0/i810_dma.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm-4.0/i810_dma.c 2009-11-10 19:30:27.000000000 -0500 @@ -143,7 +143,7 @@ static int i810_freelist_put(drm_device_ return 0; } -static struct file_operations i810_buffer_fops = { +static const struct file_operations i810_buffer_fops = { open: i810_open, flush: drm_flush, release: i810_release, diff -urNp linux-2.4.37.7/drivers/char/drm-4.0/i810_drv.c linux-2.4.37.7/drivers/char/drm-4.0/i810_drv.c --- linux-2.4.37.7/drivers/char/drm-4.0/i810_drv.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm-4.0/i810_drv.c 2009-11-10 19:30:27.000000000 -0500 @@ -43,7 +43,7 @@ static drm_device_t i810_device; drm_ctx_t i810_res_ctx; -static struct file_operations i810_fops = { +static const struct file_operations i810_fops = { #if LINUX_VERSION_CODE >= 0x020400 /* This started being used during 2.4.0-test */ owner: THIS_MODULE, diff -urNp linux-2.4.37.7/drivers/char/drm-4.0/mga_drv.c linux-2.4.37.7/drivers/char/drm-4.0/mga_drv.c --- linux-2.4.37.7/drivers/char/drm-4.0/mga_drv.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm-4.0/mga_drv.c 2009-11-10 19:30:27.000000000 -0500 @@ -44,7 +44,7 @@ static drm_device_t mga_device; drm_ctx_t mga_res_ctx; -static struct file_operations mga_fops = { +static const struct file_operations mga_fops = { #if LINUX_VERSION_CODE >= 0x020400 /* This started being used during 2.4.0-test */ owner: THIS_MODULE, diff -urNp linux-2.4.37.7/drivers/char/drm-4.0/r128_drv.c linux-2.4.37.7/drivers/char/drm-4.0/r128_drv.c --- linux-2.4.37.7/drivers/char/drm-4.0/r128_drv.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm-4.0/r128_drv.c 2009-11-10 19:30:27.000000000 -0500 @@ -45,7 +45,7 @@ static drm_device_t r128_device; drm_ctx_t r128_res_ctx; -static struct file_operations r128_fops = { +static const struct file_operations r128_fops = { #if LINUX_VERSION_CODE >= 0x020400 /* This started being used during 2.4.0-test */ owner: THIS_MODULE, diff -urNp linux-2.4.37.7/drivers/char/drm-4.0/radeon_drv.c linux-2.4.37.7/drivers/char/drm-4.0/radeon_drv.c --- linux-2.4.37.7/drivers/char/drm-4.0/radeon_drv.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm-4.0/radeon_drv.c 2009-11-10 19:30:27.000000000 -0500 @@ -42,7 +42,7 @@ static drm_device_t radeon_device; drm_ctx_t radeon_res_ctx; -static struct file_operations radeon_fops = { +static const struct file_operations radeon_fops = { #if LINUX_VERSION_CODE >= 0x020400 /* This started being used during 2.4.0-test */ owner: THIS_MODULE, diff -urNp linux-2.4.37.7/drivers/char/drm-4.0/tdfx_drv.c linux-2.4.37.7/drivers/char/drm-4.0/tdfx_drv.c --- linux-2.4.37.7/drivers/char/drm-4.0/tdfx_drv.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm-4.0/tdfx_drv.c 2009-11-10 19:30:27.000000000 -0500 @@ -44,7 +44,7 @@ static drm_device_t tdfx_device; drm_ctx_t tdfx_res_ctx; -static struct file_operations tdfx_fops = { +static const struct file_operations tdfx_fops = { #if LINUX_VERSION_CODE >= 0x020400 /* This started being used during 2.4.0-test */ owner: THIS_MODULE, diff -urNp linux-2.4.37.7/drivers/char/drm-4.0/vm.c linux-2.4.37.7/drivers/char/drm-4.0/vm.c --- linux-2.4.37.7/drivers/char/drm-4.0/vm.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/drm-4.0/vm.c 2009-11-10 19:30:27.000000000 -0500 @@ -32,25 +32,25 @@ #define __NO_VERSION__ #include "drmP.h" -struct vm_operations_struct drm_vm_ops = { +const struct vm_operations_struct drm_vm_ops = { nopage: drm_vm_nopage, open: drm_vm_open, close: drm_vm_close, }; -struct vm_operations_struct drm_vm_shm_ops = { +const struct vm_operations_struct drm_vm_shm_ops = { nopage: drm_vm_shm_nopage, open: drm_vm_open, close: drm_vm_close, }; -struct vm_operations_struct drm_vm_shm_lock_ops = { +const struct vm_operations_struct drm_vm_shm_lock_ops = { nopage: drm_vm_shm_nopage_lock, open: drm_vm_open, close: drm_vm_close, }; -struct vm_operations_struct drm_vm_dma_ops = { +const struct vm_operations_struct drm_vm_dma_ops = { nopage: drm_vm_dma_nopage, open: drm_vm_open, close: drm_vm_close, diff -urNp linux-2.4.37.7/drivers/char/ds1286.c linux-2.4.37.7/drivers/char/ds1286.c --- linux-2.4.37.7/drivers/char/ds1286.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/ds1286.c 2009-11-10 19:30:27.000000000 -0500 @@ -280,7 +280,7 @@ static unsigned int ds1286_poll(struct f * The various file operations we support. */ -static struct file_operations ds1286_fops = { +static const struct file_operations ds1286_fops = { .llseek = no_llseek, .read = ds1286_read, .poll = ds1286_poll, diff -urNp linux-2.4.37.7/drivers/char/ds1620.c linux-2.4.37.7/drivers/char/ds1620.c --- linux-2.4.37.7/drivers/char/ds1620.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/ds1620.c 2009-11-10 19:30:27.000000000 -0500 @@ -336,7 +336,7 @@ proc_therm_ds1620_read(char *buf, char * static struct proc_dir_entry *proc_therm_ds1620; #endif -static struct file_operations ds1620_fops = { +static const struct file_operations ds1620_fops = { owner: THIS_MODULE, read: ds1620_read, ioctl: ds1620_ioctl, diff -urNp linux-2.4.37.7/drivers/char/ds1742.c linux-2.4.37.7/drivers/char/ds1742.c --- linux-2.4.37.7/drivers/char/ds1742.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/ds1742.c 2009-11-10 19:30:27.000000000 -0500 @@ -312,7 +312,7 @@ static int ds1742_release(struct inode * return 0; } -static struct file_operations ds1742_fops = { +static const struct file_operations ds1742_fops = { owner:THIS_MODULE, llseek:no_llseek, ioctl:ds1742_ioctl, diff -urNp linux-2.4.37.7/drivers/char/dsp56k.c linux-2.4.37.7/drivers/char/dsp56k.c --- linux-2.4.37.7/drivers/char/dsp56k.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/dsp56k.c 2009-11-10 19:30:27.000000000 -0500 @@ -488,7 +488,7 @@ static int dsp56k_release(struct inode * return 0; } -static struct file_operations dsp56k_fops = { +static const struct file_operations dsp56k_fops = { owner: THIS_MODULE, read: dsp56k_read, write: dsp56k_write, diff -urNp linux-2.4.37.7/drivers/char/dtlk.c linux-2.4.37.7/drivers/char/dtlk.c --- linux-2.4.37.7/drivers/char/dtlk.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/dtlk.c 2009-11-10 19:30:27.000000000 -0500 @@ -97,8 +97,7 @@ static int dtlk_release(struct inode *, static int dtlk_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); -static struct file_operations dtlk_fops = -{ +static const struct file_operations dtlk_fops = { owner: THIS_MODULE, read: dtlk_read, write: dtlk_write, diff -urNp linux-2.4.37.7/drivers/char/efirtc.c linux-2.4.37.7/drivers/char/efirtc.c --- linux-2.4.37.7/drivers/char/efirtc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/efirtc.c 2009-11-10 19:30:27.000000000 -0500 @@ -282,7 +282,7 @@ efi_rtc_close(struct inode *inode, struc * The various file operations we support. */ -static struct file_operations efi_rtc_fops = { +static const struct file_operations efi_rtc_fops = { owner: THIS_MODULE, ioctl: efi_rtc_ioctl, open: efi_rtc_open, diff -urNp linux-2.4.37.7/drivers/char/eurotechwdt.c linux-2.4.37.7/drivers/char/eurotechwdt.c --- linux-2.4.37.7/drivers/char/eurotechwdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/eurotechwdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -386,7 +386,7 @@ static int eurwdt_notify_sys(struct noti */ -static struct file_operations eurwdt_fops = { +static const struct file_operations eurwdt_fops = { owner: THIS_MODULE, llseek: no_llseek, write: eurwdt_write, diff -urNp linux-2.4.37.7/drivers/char/fetchop.c linux-2.4.37.7/drivers/char/fetchop.c --- linux-2.4.37.7/drivers/char/fetchop.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/fetchop.c 2009-11-10 19:30:27.000000000 -0500 @@ -75,7 +75,7 @@ static int fetchop_mmap(struct file *fil static void fetchop_open(struct vm_area_struct *vma); static void fetchop_close(struct vm_area_struct *vma); -static struct file_operations fetchop_fops = { +static const struct file_operations fetchop_fops = { owner: THIS_MODULE, mmap: fetchop_mmap, }; @@ -86,7 +86,7 @@ static struct miscdevice fetchop_miscdev &fetchop_fops }; -static struct vm_operations_struct fetchop_vm_ops = { +static const struct vm_operations_struct fetchop_vm_ops = { open: fetchop_open, close: fetchop_close, }; diff -urNp linux-2.4.37.7/drivers/char/ftape/zftape/zftape-init.c linux-2.4.37.7/drivers/char/ftape/zftape/zftape-init.c --- linux-2.4.37.7/drivers/char/ftape/zftape/zftape-init.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/ftape/zftape/zftape-init.c 2009-11-10 19:30:27.000000000 -0500 @@ -94,8 +94,7 @@ static ssize_t zft_read (struct file *fp static ssize_t zft_write(struct file *fp, const char *buff, size_t req_len, loff_t *ppos); -static struct file_operations zft_cdev = -{ +static const struct file_operations zft_cdev = { owner: THIS_MODULE, read: zft_read, write: zft_write, @@ -205,7 +204,7 @@ static int zft_mmap(struct file *filep, lock_kernel(); if ((result = ftape_mmap(vma)) >= 0) { #ifndef MSYNC_BUG_WAS_FIXED - static struct vm_operations_struct dummy = { NULL, }; + static const struct vm_operations_struct dummy = { NULL, }; vma->vm_ops = &dummy; #endif } diff -urNp linux-2.4.37.7/drivers/char/genrtc.c linux-2.4.37.7/drivers/char/genrtc.c --- linux-2.4.37.7/drivers/char/genrtc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/genrtc.c 2009-11-10 19:30:27.000000000 -0500 @@ -476,7 +476,7 @@ static int gen_rtc_read_proc(char *page, * The various file operations we support. */ -static struct file_operations gen_rtc_fops = { +static const struct file_operations gen_rtc_fops = { .owner = THIS_MODULE, #ifdef CONFIG_GEN_RTC_X .read = gen_rtc_read, diff -urNp linux-2.4.37.7/drivers/char/geodewdt.c linux-2.4.37.7/drivers/char/geodewdt.c --- linux-2.4.37.7/drivers/char/geodewdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/geodewdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -183,7 +183,7 @@ static int geodewdt_notify_sys(struct no return NOTIFY_DONE; } -static struct file_operations geodewdt_fops = { +static const struct file_operations geodewdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .write = geodewdt_write, diff -urNp linux-2.4.37.7/drivers/char/hp_psaux.c linux-2.4.37.7/drivers/char/hp_psaux.c --- linux-2.4.37.7/drivers/char/hp_psaux.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/hp_psaux.c 2009-11-10 19:30:27.000000000 -0500 @@ -414,7 +414,7 @@ static int release_aux(struct inode * in return 0; } -static struct file_operations psaux_fops = { +static const struct file_operations psaux_fops = { read: read_aux, write: write_aux, poll: aux_poll, diff -urNp linux-2.4.37.7/drivers/char/hw_random.c linux-2.4.37.7/drivers/char/hw_random.c --- linux-2.4.37.7/drivers/char/hw_random.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/hw_random.c 2009-11-10 19:30:27.000000000 -0500 @@ -106,7 +106,7 @@ struct rng_operations { }; static struct rng_operations *rng_ops; -static struct file_operations rng_chrdev_ops = { +static const struct file_operations rng_chrdev_ops = { .owner = THIS_MODULE, .open = rng_dev_open, .read = rng_dev_read, diff -urNp linux-2.4.37.7/drivers/char/i810_rng.c linux-2.4.37.7/drivers/char/i810_rng.c --- linux-2.4.37.7/drivers/char/i810_rng.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/i810_rng.c 2009-11-10 19:30:27.000000000 -0500 @@ -260,7 +260,7 @@ static ssize_t rng_dev_read (struct file } -static struct file_operations rng_chrdev_ops = { +static const struct file_operations rng_chrdev_ops = { owner: THIS_MODULE, open: rng_dev_open, release: rng_dev_release, diff -urNp linux-2.4.37.7/drivers/char/i810-tco.c linux-2.4.37.7/drivers/char/i810-tco.c --- linux-2.4.37.7/drivers/char/i810-tco.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/i810-tco.c 2009-11-10 19:30:27.000000000 -0500 @@ -376,7 +376,7 @@ static unsigned char __init i810tco_getd return 0; } -static struct file_operations i810tco_fops = { +static const struct file_operations i810tco_fops = { owner: THIS_MODULE, write: i810tco_write, ioctl: i810tco_ioctl, diff -urNp linux-2.4.37.7/drivers/char/i8k.c linux-2.4.37.7/drivers/char/i8k.c --- linux-2.4.37.7/drivers/char/i8k.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/i8k.c 2009-11-10 19:30:27.000000000 -0500 @@ -112,7 +112,7 @@ static int i8k_ioctl(struct inode *, str unsigned long); static void i8k_keys_set_timer(void); -static struct file_operations i8k_fops = { +static const struct file_operations i8k_fops = { read: i8k_read, ioctl: i8k_ioctl, }; diff -urNp linux-2.4.37.7/drivers/char/ib700wdt.c linux-2.4.37.7/drivers/char/ib700wdt.c --- linux-2.4.37.7/drivers/char/ib700wdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/ib700wdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -280,7 +280,7 @@ ibwdt_notify_sys(struct notifier_block * * Kernel Interfaces */ -static struct file_operations ibwdt_fops = { +static const struct file_operations ibwdt_fops = { owner: THIS_MODULE, read: ibwdt_read, write: ibwdt_write, diff -urNp linux-2.4.37.7/drivers/char/indydog.c linux-2.4.37.7/drivers/char/indydog.c --- linux-2.4.37.7/drivers/char/indydog.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/indydog.c 2009-11-10 19:30:27.000000000 -0500 @@ -137,7 +137,7 @@ static int indydog_ioctl(struct inode *i } } -static struct file_operations indydog_fops = { +static const struct file_operations indydog_fops = { owner: THIS_MODULE, write: indydog_write, ioctl: indydog_ioctl, diff -urNp linux-2.4.37.7/drivers/char/ip27-rtc.c linux-2.4.37.7/drivers/char/ip27-rtc.c --- linux-2.4.37.7/drivers/char/ip27-rtc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/ip27-rtc.c 2009-11-10 19:30:27.000000000 -0500 @@ -192,7 +192,7 @@ static int rtc_release(struct inode *ino * The various file operations we support. */ -static struct file_operations rtc_fops = { +static const struct file_operations rtc_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .ioctl = rtc_ioctl, diff -urNp linux-2.4.37.7/drivers/char/ip2main.c linux-2.4.37.7/drivers/char/ip2main.c --- linux-2.4.37.7/drivers/char/ip2main.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/ip2main.c 2009-11-10 19:30:27.000000000 -0500 @@ -354,7 +354,7 @@ static struct termios * TermiosLocked /* This is the driver descriptor for the ip2ipl device, which is used to * download the loadware to the boards. */ -static struct file_operations ip2_ipl = { +static const struct file_operations ip2_ipl = { owner: THIS_MODULE, read: ip2_ipl_read, write: ip2_ipl_write, diff -urNp linux-2.4.37.7/drivers/char/ipmi/ipmi_devintf.c linux-2.4.37.7/drivers/char/ipmi/ipmi_devintf.c --- linux-2.4.37.7/drivers/char/ipmi/ipmi_devintf.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/ipmi/ipmi_devintf.c 2009-11-10 19:30:27.000000000 -0500 @@ -423,7 +423,7 @@ static int ipmi_ioctl(struct inode *ino } -static struct file_operations ipmi_fops = { +static const struct file_operations ipmi_fops = { owner: THIS_MODULE, ioctl: ipmi_ioctl, open: ipmi_open, diff -urNp linux-2.4.37.7/drivers/char/ipmi/ipmi_watchdog.c linux-2.4.37.7/drivers/char/ipmi/ipmi_watchdog.c --- linux-2.4.37.7/drivers/char/ipmi/ipmi_watchdog.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/ipmi/ipmi_watchdog.c 2009-11-10 19:30:27.000000000 -0500 @@ -699,7 +699,7 @@ static int ipmi_close(struct inode *ino, return 0; } -static struct file_operations ipmi_wdog_fops = { +static const struct file_operations ipmi_wdog_fops = { .owner = THIS_MODULE, .read = ipmi_read, .poll = ipmi_poll, diff -urNp linux-2.4.37.7/drivers/char/isicom.c linux-2.4.37.7/drivers/char/isicom.c --- linux-2.4.37.7/drivers/char/isicom.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/isicom.c 2009-11-10 19:30:27.000000000 -0500 @@ -113,7 +113,7 @@ static signed char linuxb_to_isib[] = { * */ -static struct file_operations ISILoad_fops = { +static const struct file_operations ISILoad_fops = { owner: THIS_MODULE, ioctl: ISILoad_ioctl, }; diff -urNp linux-2.4.37.7/drivers/char/istallion.c linux-2.4.37.7/drivers/char/istallion.c --- linux-2.4.37.7/drivers/char/istallion.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/istallion.c 2009-11-10 19:30:27.000000000 -0500 @@ -782,7 +782,7 @@ static inline int stli_initpcibrd(int br * will give access to the shared memory on the Stallion intelligent * board. This is also a very useful debugging tool. */ -static struct file_operations stli_fsiomem = { +static const struct file_operations stli_fsiomem = { owner: THIS_MODULE, read: stli_memread, write: stli_memwrite, diff -urNp linux-2.4.37.7/drivers/char/ite_gpio.c linux-2.4.37.7/drivers/char/ite_gpio.c --- linux-2.4.37.7/drivers/char/ite_gpio.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/ite_gpio.c 2009-11-10 19:30:27.000000000 -0500 @@ -364,7 +364,7 @@ DEB(printk("interrupt 0x%x %d\n",ITE_GPA } } -static struct file_operations ite_gpio_fops = { +static const struct file_operations ite_gpio_fops = { owner: THIS_MODULE, ioctl: ite_gpio_ioctl, open: ite_gpio_open, diff -urNp linux-2.4.37.7/drivers/char/keyboard.c linux-2.4.37.7/drivers/char/keyboard.c --- linux-2.4.37.7/drivers/char/keyboard.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/keyboard.c 2009-11-10 19:30:27.000000000 -0500 @@ -545,6 +545,16 @@ static void do_spec(unsigned char value, if ((kbd->kbdmode == VC_RAW || kbd->kbdmode == VC_MEDIUMRAW) && !(SPECIALS_ALLOWED_IN_RAW_MODE & (1 << value))) return; + +#if defined(CONFIG_GRKERNSEC_PROC) || defined(CONFIG_GRKERNSEC_PROC_MEMMAP) + { + void *func = spec_fn_table[value]; + if (func == show_state || func == show_ptregs || + func == show_mem) + return; + } +#endif + spec_fn_table[value](); } diff -urNp linux-2.4.37.7/drivers/char/lcd.c linux-2.4.37.7/drivers/char/lcd.c --- linux-2.4.37.7/drivers/char/lcd.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/lcd.c 2009-11-10 19:30:27.000000000 -0500 @@ -556,7 +556,7 @@ static long lcd_read(struct inode *inode * The various file operations we support. */ -static struct file_operations lcd_fops = { +static const struct file_operations lcd_fops = { read: lcd_read, ioctl: lcd_ioctl, open: lcd_open, diff -urNp linux-2.4.37.7/drivers/char/lp.c linux-2.4.37.7/drivers/char/lp.c --- linux-2.4.37.7/drivers/char/lp.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/lp.c 2009-11-10 19:30:27.000000000 -0500 @@ -664,7 +664,7 @@ static int lp_ioctl(struct inode *inode, return retval; } -static struct file_operations lp_fops = { +static const struct file_operations lp_fops = { owner: THIS_MODULE, write: lp_write, ioctl: lp_ioctl, diff -urNp linux-2.4.37.7/drivers/char/machzwd.c linux-2.4.37.7/drivers/char/machzwd.c --- linux-2.4.37.7/drivers/char/machzwd.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/machzwd.c 2009-11-10 19:30:27.000000000 -0500 @@ -448,7 +448,7 @@ static int zf_notify_sys(struct notifier -static struct file_operations zf_fops = { +static const struct file_operations zf_fops = { owner: THIS_MODULE, read: zf_read, write: zf_write, diff -urNp linux-2.4.37.7/drivers/char/mem.c linux-2.4.37.7/drivers/char/mem.c --- linux-2.4.37.7/drivers/char/mem.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/mem.c 2009-11-10 19:30:27.000000000 -0500 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,10 @@ extern void mda_console_init(void); #if defined(CONFIG_S390_TAPE) && defined(CONFIG_S390_TAPE_CHAR) extern void tapechar_init(void); #endif + +#ifdef CONFIG_GRKERNSEC +extern struct file_operations grsec_fops; +#endif static ssize_t do_write_mem(struct file * file, void *p, unsigned long realp, const char * buf, size_t count, loff_t *ppos) @@ -115,6 +120,11 @@ static ssize_t write_mem(struct file * f unsigned long p = *ppos; unsigned long end_mem; +#ifdef CONFIG_GRKERNSEC_KMEM + gr_handle_mem_write(); + return -EPERM; +#endif + end_mem = __pa(high_memory); if (p >= end_mem) return 0; @@ -187,6 +197,12 @@ static int mmap_mem(struct file * file, { unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; +#ifdef CONFIG_GRKERNSEC_KMEM + if (gr_handle_mem_mmap(offset, vma)) + return -EPERM; +#endif + + /* * Accessing memory above the top the kernel knows about or * through a file pointer that was marked O_SYNC will be @@ -286,6 +302,11 @@ static ssize_t write_kmem(struct file * ssize_t virtr = 0; char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */ +#ifdef CONFIG_GRKERNSEC_KMEM + gr_handle_kmem_write(); + return -EPERM; +#endif + if (p < (unsigned long) high_memory) { wrote = count; if (count > (unsigned long) high_memory - p) @@ -402,9 +423,25 @@ static inline size_t read_zero_pagealign count = size; zap_page_range(mm, addr, count); - if (zeromap_page_range(addr, count, PAGE_COPY)) + if (zeromap_page_range(addr, count, vma->vm_page_prot)) break; +#ifdef CONFIG_PAX_SEGMEXEC + if (vma->vm_flags & VM_MIRROR) { + unsigned long addr_m; + struct vm_area_struct * vma_m; + + addr_m = vma->vm_start + vma->vm_mirror; + vma_m = find_vma(mm, addr_m); + if (vma_m && vma_m->vm_start == addr_m && (vma_m->vm_flags & VM_MIRROR)) { + addr_m = addr + vma->vm_mirror; + zap_page_range(mm, addr_m, count); + } else + printk(KERN_ERR "PAX: VMMIRROR: read_zero bug, %08lx, %08lx\n", + addr, vma->vm_start); + } +#endif + size -= count; buf += count; addr += count; @@ -526,6 +563,15 @@ static loff_t memory_lseek(struct file * static int open_port(struct inode * inode, struct file * filp) { +#ifdef CONFIG_GRKERNSEC_KMEM + gr_handle_open_port(); + return -EPERM; +#endif + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; +} + +static int open_mem(struct inode * inode, struct file * filp) +{ return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; } @@ -574,7 +620,7 @@ out: return page; } -struct vm_operations_struct kmem_vm_ops = { +const struct vm_operations_struct kmem_vm_ops = { nopage: kmem_vm_nopage, }; @@ -583,6 +629,11 @@ static int mmap_kmem(struct file * file, unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; unsigned long size = vma->vm_end - vma->vm_start; +#ifdef CONFIG_GRKERNSEC_KMEM + if (gr_handle_mem_mmap(offset, vma)) + return -EPERM; +#endif + /* * If the user is not attempting to mmap a high memory address then * the standard mmap_mem mechanism will work. High memory addresses @@ -618,10 +669,9 @@ static int mmap_kmem(struct file * file, #define full_lseek null_lseek #define write_zero write_null #define read_full read_zero -#define open_mem open_port #define open_kmem open_mem -static struct file_operations mem_fops = { +static const struct file_operations mem_fops = { llseek: memory_lseek, read: read_mem, write: write_mem, @@ -629,7 +679,7 @@ static struct file_operations mem_fops = open: open_mem, }; -static struct file_operations kmem_fops = { +static const struct file_operations kmem_fops = { llseek: memory_lseek, read: read_kmem, write: write_kmem, @@ -637,14 +687,14 @@ static struct file_operations kmem_fops open: open_kmem, }; -static struct file_operations null_fops = { +static const struct file_operations null_fops = { llseek: null_lseek, read: read_null, write: write_null, }; #if defined(CONFIG_ISA) || !defined(__mc68000__) -static struct file_operations port_fops = { +static const struct file_operations port_fops = { llseek: memory_lseek, read: read_port, write: write_port, @@ -652,14 +702,14 @@ static struct file_operations port_fops }; #endif -static struct file_operations zero_fops = { +static const struct file_operations zero_fops = { llseek: zero_lseek, read: read_zero, write: write_zero, mmap: mmap_zero, }; -static struct file_operations full_fops = { +static const struct file_operations full_fops = { llseek: full_lseek, read: read_full, write: write_full, @@ -694,6 +744,11 @@ static int memory_open(struct inode * in case 9: filp->f_op = &urandom_fops; break; +#ifdef CONFIG_GRKERNSEC + case 13: + filp->f_op = &grsec_fops; + break; +#endif default: return -ENXIO; } @@ -709,7 +764,7 @@ void __init memory_devfs_register (void) unsigned short minor; char *name; umode_t mode; - struct file_operations *fops; + const struct file_operations *fops; } list[] = { /* list of minor devices */ {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops}, {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops}, @@ -720,7 +775,10 @@ void __init memory_devfs_register (void) {5, "zero", S_IRUGO | S_IWUGO, &zero_fops}, {7, "full", S_IRUGO | S_IWUGO, &full_fops}, {8, "random", S_IRUGO | S_IWUSR, &random_fops}, - {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops} + {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}, +#if defined(CONFIG_GRKERNSEC) && !defined(CONFIG_GRKERNSEC_NO_RBAC) + {13,"grsec", S_IRUSR | S_IWUGO, &grsec_fops} +#endif }; int i; @@ -731,7 +789,7 @@ void __init memory_devfs_register (void) list[i].fops, NULL); } -static struct file_operations memory_fops = { +static const struct file_operations memory_fops = { open: memory_open, /* just a selector for the real open */ }; diff -urNp linux-2.4.37.7/drivers/char/mips_rtc.c linux-2.4.37.7/drivers/char/mips_rtc.c --- linux-2.4.37.7/drivers/char/mips_rtc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/mips_rtc.c 2009-11-10 19:30:27.000000000 -0500 @@ -138,7 +138,7 @@ static int rtc_release(struct inode *ino * The various file operations we support. */ -static struct file_operations rtc_fops = { +static const struct file_operations rtc_fops = { owner:THIS_MODULE, llseek:no_llseek, ioctl:rtc_ioctl, diff -urNp linux-2.4.37.7/drivers/char/misc.c linux-2.4.37.7/drivers/char/misc.c --- linux-2.4.37.7/drivers/char/misc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/misc.c 2009-11-10 19:30:27.000000000 -0500 @@ -104,7 +104,7 @@ static int misc_open(struct inode * inod int minor = MINOR(inode->i_rdev); struct miscdevice *c; int err = -ENODEV; - struct file_operations *old_fops, *new_fops = NULL; + const struct file_operations *old_fops, *new_fops = NULL; down(&misc_sem); @@ -143,7 +143,7 @@ fail: return err; } -static struct file_operations misc_fops = { +static const struct file_operations misc_fops = { owner: THIS_MODULE, open: misc_open, }; diff -urNp linux-2.4.37.7/drivers/char/mixcomwd.c linux-2.4.37.7/drivers/char/mixcomwd.c --- linux-2.4.37.7/drivers/char/mixcomwd.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/mixcomwd.c 2009-11-10 19:30:27.000000000 -0500 @@ -197,8 +197,7 @@ static int mixcomwd_ioctl(struct inode * return 0; } -static struct file_operations mixcomwd_fops= -{ +static const struct file_operations mixcomwd_fops = { owner: THIS_MODULE, write: mixcomwd_write, ioctl: mixcomwd_ioctl, diff -urNp linux-2.4.37.7/drivers/char/mk712.c linux-2.4.37.7/drivers/char/mk712.c --- linux-2.4.37.7/drivers/char/mk712.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/mk712.c 2009-11-10 19:30:27.000000000 -0500 @@ -415,7 +415,7 @@ static ssize_t mk712_write(struct file * return -EINVAL; } -struct file_operations mk712_fops = { +const struct file_operations mk712_fops = { owner: THIS_MODULE, read: mk712_read, write: mk712_write, diff -urNp linux-2.4.37.7/drivers/char/mpc8xx_wdt.c linux-2.4.37.7/drivers/char/mpc8xx_wdt.c --- linux-2.4.37.7/drivers/char/mpc8xx_wdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/mpc8xx_wdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -144,7 +144,7 @@ mpc8xx_wdt_ioctl(struct inode *inode, st return 0; } -static struct file_operations mpc8xx_wdt_fops = { +static const struct file_operations mpc8xx_wdt_fops = { .owner = THIS_MODULE, .write = mpc8xx_wdt_write, .ioctl = mpc8xx_wdt_ioctl, diff -urNp linux-2.4.37.7/drivers/char/mwave/mwavedd.c linux-2.4.37.7/drivers/char/mwave/mwavedd.c --- linux-2.4.37.7/drivers/char/mwave/mwavedd.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/mwave/mwavedd.c 2009-11-10 19:30:27.000000000 -0500 @@ -431,7 +431,7 @@ static int register_serial_portandirq(un #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -static struct file_operations mwave_fops = { +static const struct file_operations mwave_fops = { owner:THIS_MODULE, read:mwave_read, write:mwave_write, @@ -440,7 +440,7 @@ static struct file_operations mwave_fops release:mwave_close }; #else -static struct file_operations mwave_fops = { +static const struct file_operations mwave_fops = { NULL, /* lseek */ mwave_read, /* read */ mwave_write, /* write */ diff -urNp linux-2.4.37.7/drivers/char/nvram.c linux-2.4.37.7/drivers/char/nvram.c --- linux-2.4.37.7/drivers/char/nvram.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/nvram.c 2009-11-10 19:30:27.000000000 -0500 @@ -443,7 +443,7 @@ nvram_read_proc(char *buffer, char **sta #endif /* CONFIG_PROC_FS */ -static struct file_operations nvram_fops = { +static const struct file_operations nvram_fops = { owner: THIS_MODULE, llseek: nvram_llseek, read: nvram_read, diff -urNp linux-2.4.37.7/drivers/char/nwbutton.c linux-2.4.37.7/drivers/char/nwbutton.c --- linux-2.4.37.7/drivers/char/nwbutton.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/nwbutton.c 2009-11-10 19:30:27.000000000 -0500 @@ -182,7 +182,7 @@ static int button_read (struct file *fil * attempts to perform these operations on the device. */ -static struct file_operations button_fops = { +static const struct file_operations button_fops = { owner: THIS_MODULE, read: button_read, }; diff -urNp linux-2.4.37.7/drivers/char/nwflash.c linux-2.4.37.7/drivers/char/nwflash.c --- linux-2.4.37.7/drivers/char/nwflash.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/nwflash.c 2009-11-10 19:30:27.000000000 -0500 @@ -636,8 +636,7 @@ static void kick_open(void) udelay(25); } -static struct file_operations flash_fops = -{ +static const struct file_operations flash_fops = { owner: THIS_MODULE, llseek: flash_llseek, read: flash_read, diff -urNp linux-2.4.37.7/drivers/char/pc110pad.c linux-2.4.37.7/drivers/char/pc110pad.c --- linux-2.4.37.7/drivers/char/pc110pad.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/pc110pad.c 2009-11-10 19:30:27.000000000 -0500 @@ -770,7 +770,7 @@ static int pad_ioctl(struct inode *inode } -static struct file_operations pad_fops = { +static const struct file_operations pad_fops = { owner: THIS_MODULE, read: read_pad, write: write_pad, diff -urNp linux-2.4.37.7/drivers/char/pc_keyb.c linux-2.4.37.7/drivers/char/pc_keyb.c --- linux-2.4.37.7/drivers/char/pc_keyb.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/pc_keyb.c 2009-11-10 19:30:27.000000000 -0500 @@ -1182,7 +1182,7 @@ static unsigned int aux_poll(struct file return 0; } -struct file_operations psaux_fops = { +const struct file_operations psaux_fops = { read: read_aux, write: write_aux, poll: aux_poll, diff -urNp linux-2.4.37.7/drivers/char/pcwd.c linux-2.4.37.7/drivers/char/pcwd.c --- linux-2.4.37.7/drivers/char/pcwd.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/pcwd.c 2009-11-10 19:30:27.000000000 -0500 @@ -710,7 +710,7 @@ static struct pci_driver pcwd_driver = { probe:pcwd_init_one, }; -static struct file_operations pcwd_fops = { +static const struct file_operations pcwd_fops = { owner:THIS_MODULE, write:pcwd_write, ioctl:pcwd_ioctl, @@ -724,7 +724,7 @@ static struct miscdevice pcwd_miscdev = &pcwd_fops }; -static struct file_operations pcwd_temp_fops = { +static const struct file_operations pcwd_temp_fops = { owner:THIS_MODULE, read:pcwd_read, open:pcwd_open, diff -urNp linux-2.4.37.7/drivers/char/ppdev.c linux-2.4.37.7/drivers/char/ppdev.c --- linux-2.4.37.7/drivers/char/ppdev.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/ppdev.c 2009-11-10 19:30:27.000000000 -0500 @@ -743,7 +743,7 @@ static unsigned int pp_poll (struct file return mask; } -static struct file_operations pp_fops = { +static const struct file_operations pp_fops = { owner: THIS_MODULE, llseek: no_llseek, read: pp_read, diff -urNp linux-2.4.37.7/drivers/char/qpmouse.c linux-2.4.37.7/drivers/char/qpmouse.c --- linux-2.4.37.7/drivers/char/qpmouse.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/qpmouse.c 2009-11-10 19:30:27.000000000 -0500 @@ -288,7 +288,7 @@ repeat: return 0; } -struct file_operations qp_fops = { +const struct file_operations qp_fops = { owner: THIS_MODULE, read: read_qp, write: write_qp, diff -urNp linux-2.4.37.7/drivers/char/qtronix.c linux-2.4.37.7/drivers/char/qtronix.c --- linux-2.4.37.7/drivers/char/qtronix.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/qtronix.c 2009-11-10 19:30:27.000000000 -0500 @@ -569,7 +569,7 @@ static unsigned int aux_poll(struct file return 0; } -struct file_operations psaux_fops = { +const struct file_operations psaux_fops = { read: read_aux, write: write_aux, poll: aux_poll, diff -urNp linux-2.4.37.7/drivers/char/random.c linux-2.4.37.7/drivers/char/random.c --- linux-2.4.37.7/drivers/char/random.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/random.c 2009-11-10 19:30:27.000000000 -0500 @@ -262,9 +262,15 @@ /* * Configuration information */ +#ifdef CONFIG_GRKERNSEC_RANDNET +#define DEFAULT_POOL_SIZE 1024 +#define SECONDARY_POOL_SIZE 256 +#define BATCH_ENTROPY_SIZE 512 +#else #define DEFAULT_POOL_SIZE 512 #define SECONDARY_POOL_SIZE 128 #define BATCH_ENTROPY_SIZE 256 +#endif #define USE_SHA /* @@ -1699,14 +1705,14 @@ random_ioctl(struct inode * inode, struc } } -struct file_operations random_fops = { +const struct file_operations random_fops = { read: random_read, write: random_write, poll: random_poll, ioctl: random_ioctl, }; -struct file_operations urandom_fops = { +const struct file_operations urandom_fops = { read: urandom_read, write: random_write, ioctl: random_ioctl, diff -urNp linux-2.4.37.7/drivers/char/raw.c linux-2.4.37.7/drivers/char/raw.c --- linux-2.4.37.7/drivers/char/raw.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/raw.c 2009-11-10 19:30:27.000000000 -0500 @@ -37,7 +37,7 @@ int raw_ctl_ioctl(struct inode *, struct int raw_ioctl(struct inode *, struct file *, unsigned int, unsigned long); -static struct file_operations raw_fops = { +static const struct file_operations raw_fops = { read: raw_read, write: raw_write, open: raw_open, @@ -45,7 +45,7 @@ static struct file_operations raw_fops = ioctl: raw_ioctl, }; -static struct file_operations raw_ctl_fops = { +static const struct file_operations raw_ctl_fops = { ioctl: raw_ctl_ioctl, open: raw_open, }; diff -urNp linux-2.4.37.7/drivers/char/rio/rio_linux.c linux-2.4.37.7/drivers/char/rio/rio_linux.c --- linux-2.4.37.7/drivers/char/rio/rio_linux.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/rio/rio_linux.c 2009-11-10 19:30:27.000000000 -0500 @@ -276,7 +276,7 @@ static struct real_driver rio_real_drive * */ -static struct file_operations rio_fw_fops = { +static const struct file_operations rio_fw_fops = { owner: THIS_MODULE, ioctl: rio_fw_ioctl, }; diff -urNp linux-2.4.37.7/drivers/char/rtc.c linux-2.4.37.7/drivers/char/rtc.c --- linux-2.4.37.7/drivers/char/rtc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/rtc.c 2009-11-10 19:30:27.000000000 -0500 @@ -686,7 +686,7 @@ static unsigned int rtc_poll(struct file * The various file operations we support. */ -static struct file_operations rtc_fops = { +static const struct file_operations rtc_fops = { owner: THIS_MODULE, llseek: no_llseek, read: rtc_read, diff -urNp linux-2.4.37.7/drivers/char/sbc60xxwdt.c linux-2.4.37.7/drivers/char/sbc60xxwdt.c --- linux-2.4.37.7/drivers/char/sbc60xxwdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/sbc60xxwdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -251,7 +251,7 @@ static int fop_ioctl(struct inode *inode } } -static struct file_operations wdt_fops = { +static const struct file_operations wdt_fops = { owner: THIS_MODULE, llseek: no_llseek, read: fop_read, diff -urNp linux-2.4.37.7/drivers/char/sc1200wdt.c linux-2.4.37.7/drivers/char/sc1200wdt.c --- linux-2.4.37.7/drivers/char/sc1200wdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/sc1200wdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -292,8 +292,7 @@ static struct notifier_block sc1200wdt_n notifier_call: sc1200wdt_notify_sys }; -static struct file_operations sc1200wdt_fops = -{ +static const struct file_operations sc1200wdt_fops = { owner: THIS_MODULE, write: sc1200wdt_write, ioctl: sc1200wdt_ioctl, diff -urNp linux-2.4.37.7/drivers/char/sc520_wdt.c linux-2.4.37.7/drivers/char/sc520_wdt.c --- linux-2.4.37.7/drivers/char/sc520_wdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/sc520_wdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -286,7 +286,7 @@ static int fop_ioctl(struct inode *inode } } -static struct file_operations wdt_fops = { +static const struct file_operations wdt_fops = { owner: THIS_MODULE, llseek: fop_llseek, write: fop_write, diff -urNp linux-2.4.37.7/drivers/char/scx200_gpio.c linux-2.4.37.7/drivers/char/scx200_gpio.c --- linux-2.4.37.7/drivers/char/scx200_gpio.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/scx200_gpio.c 2009-11-10 19:30:27.000000000 -0500 @@ -106,7 +106,7 @@ static int scx200_gpio_release(struct in } -static struct file_operations scx200_gpio_fops = { +static const struct file_operations scx200_gpio_fops = { .owner = THIS_MODULE, .write = scx200_gpio_write, .read = scx200_gpio_read, diff -urNp linux-2.4.37.7/drivers/char/scx200_wdt.c linux-2.4.37.7/drivers/char/scx200_wdt.c --- linux-2.4.37.7/drivers/char/scx200_wdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/scx200_wdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -200,7 +200,7 @@ static int scx200_wdt_ioctl(struct inode } } -static struct file_operations scx200_wdt_fops = { +static const struct file_operations scx200_wdt_fops = { .owner = THIS_MODULE, .write = scx200_wdt_write, .ioctl = scx200_wdt_ioctl, diff -urNp linux-2.4.37.7/drivers/char/shwdt.c linux-2.4.37.7/drivers/char/shwdt.c --- linux-2.4.37.7/drivers/char/shwdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/shwdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -405,7 +405,7 @@ static int sh_wdt_notify_sys(struct noti return NOTIFY_DONE; } -static struct file_operations sh_wdt_fops = { +static const struct file_operations sh_wdt_fops = { owner: THIS_MODULE, llseek: no_llseek, write: sh_wdt_write, diff -urNp linux-2.4.37.7/drivers/char/softdog.c linux-2.4.37.7/drivers/char/softdog.c --- linux-2.4.37.7/drivers/char/softdog.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/softdog.c 2009-11-10 19:30:27.000000000 -0500 @@ -198,7 +198,7 @@ static int softdog_ioctl(struct inode *i } } -static struct file_operations softdog_fops = { +static const struct file_operations softdog_fops = { owner: THIS_MODULE, write: softdog_write, ioctl: softdog_ioctl, diff -urNp linux-2.4.37.7/drivers/char/sonypi.c linux-2.4.37.7/drivers/char/sonypi.c --- linux-2.4.37.7/drivers/char/sonypi.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/sonypi.c 2009-11-10 19:30:27.000000000 -0500 @@ -613,7 +613,7 @@ static int sonypi_misc_ioctl(struct inod return ret; } -static struct file_operations sonypi_misc_fops = { +static const struct file_operations sonypi_misc_fops = { .owner = THIS_MODULE, .read = sonypi_misc_read, .poll = sonypi_misc_poll, diff -urNp linux-2.4.37.7/drivers/char/stallion.c linux-2.4.37.7/drivers/char/stallion.c --- linux-2.4.37.7/drivers/char/stallion.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/stallion.c 2009-11-10 19:30:27.000000000 -0500 @@ -735,7 +735,7 @@ static unsigned int sc26198_baudtable[] * Define the driver info for a user level control device. Used mainly * to get at port stats - only not using the port device itself. */ -static struct file_operations stl_fsiomem = { +static const struct file_operations stl_fsiomem = { owner: THIS_MODULE, ioctl: stl_memioctl, }; diff -urNp linux-2.4.37.7/drivers/char/sx.c linux-2.4.37.7/drivers/char/sx.c --- linux-2.4.37.7/drivers/char/sx.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/sx.c 2009-11-10 19:30:27.000000000 -0500 @@ -421,7 +421,7 @@ static struct real_driver sx_real_driver * */ -static struct file_operations sx_fw_fops = { +static const struct file_operations sx_fw_fops = { owner: THIS_MODULE, ioctl: sx_fw_ioctl, }; diff -urNp linux-2.4.37.7/drivers/char/tipar.c linux-2.4.37.7/drivers/char/tipar.c --- linux-2.4.37.7/drivers/char/tipar.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/tipar.c 2009-11-10 19:30:27.000000000 -0500 @@ -384,7 +384,7 @@ tipar_ioctl(struct inode *inode, struct /* ----- kernel module registering ------------------------------------ */ -static struct file_operations tipar_fops = { +static const struct file_operations tipar_fops = { owner:THIS_MODULE, llseek:no_llseek, read:tipar_read, diff -urNp linux-2.4.37.7/drivers/char/toshiba.c linux-2.4.37.7/drivers/char/toshiba.c --- linux-2.4.37.7/drivers/char/toshiba.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/toshiba.c 2009-11-10 19:30:27.000000000 -0500 @@ -90,7 +90,7 @@ static int tosh_ioctl(struct inode *, st unsigned long); -static struct file_operations tosh_fops = { +static const struct file_operations tosh_fops = { owner: THIS_MODULE, ioctl: tosh_ioctl, }; diff -urNp linux-2.4.37.7/drivers/char/tpqic02.c linux-2.4.37.7/drivers/char/tpqic02.c --- linux-2.4.37.7/drivers/char/tpqic02.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/tpqic02.c 2009-11-10 19:30:27.000000000 -0500 @@ -2703,7 +2703,7 @@ static int qic02_tape_ioctl(struct inode /* These are (most) of the interface functions: */ -static struct file_operations qic02_tape_fops = { +static const struct file_operations qic02_tape_fops = { owner:THIS_MODULE, llseek:no_llseek, read:qic02_tape_read, diff -urNp linux-2.4.37.7/drivers/char/tty_io.c linux-2.4.37.7/drivers/char/tty_io.c --- linux-2.4.37.7/drivers/char/tty_io.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/tty_io.c 2009-11-10 19:30:27.000000000 -0500 @@ -671,7 +671,7 @@ static int hung_up_tty_ioctl(struct inod return cmd == TIOCSPGRP ? -ENOTTY : -EIO; } -static struct file_operations tty_fops = { +static const struct file_operations tty_fops = { llseek: no_llseek, read: tty_read, write: tty_write, @@ -682,7 +682,7 @@ static struct file_operations tty_fops = fasync: tty_fasync, }; -static struct file_operations hung_up_tty_fops = { +static const struct file_operations hung_up_tty_fops = { llseek: no_llseek, read: hung_up_tty_read, write: hung_up_tty_write, @@ -1775,7 +1775,11 @@ init_dev_done: retval = -ENODEV; filp->f_flags = saved_flags; +#ifdef CONFIG_GRKERNSEC + if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_TTY_CONFIG)) +#else if (!retval && test_bit(TTY_EXCLUSIVE, &tty->flags) && !suser()) +#endif retval = -EBUSY; if (retval) { @@ -1882,7 +1886,11 @@ static int tiocsti(struct tty_struct *tt char ch, mbz = 0; struct tty_ldisc *ld; +#ifdef CONFIG_GRKERNSEC + if ((current->tty != tty) && !capable(CAP_SYS_TTY_CONFIG)) +#else if ((current->tty != tty) && !suser()) +#endif return -EPERM; if (get_user(ch, arg)) return -EFAULT; @@ -1922,7 +1930,11 @@ static int tioccons(struct inode *inode, if (inode->i_rdev == SYSCONS_DEV || inode->i_rdev == CONSOLE_DEV) { struct file *f; +#ifdef CONFIG_GRKERNSEC + if (!capable(CAP_SYS_TTY_CONFIG)) +#else if (!suser()) +#endif return -EPERM; spin_lock(&redirect_lock); f = redirect; @@ -1974,7 +1986,11 @@ static int tiocsctty(struct tty_struct * * This tty is already the controlling * tty for another session group! */ +#ifdef CONFIG_GRKERNSEC + if ((arg == 1) && capable(CAP_SYS_ADMIN)) { +#else if ((arg == 1) && suser()) { +#endif /* * Steal it away */ diff -urNp linux-2.4.37.7/drivers/char/vc_screen.c linux-2.4.37.7/drivers/char/vc_screen.c --- linux-2.4.37.7/drivers/char/vc_screen.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/vc_screen.c 2009-11-10 19:30:27.000000000 -0500 @@ -471,7 +471,7 @@ vcs_open(struct inode *inode, struct fil return 0; } -static struct file_operations vcs_fops = { +static const struct file_operations vcs_fops = { llseek: vcs_lseek, read: vcs_read, write: vcs_write, diff -urNp linux-2.4.37.7/drivers/char/vt.c linux-2.4.37.7/drivers/char/vt.c --- linux-2.4.37.7/drivers/char/vt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/vt.c 2009-11-10 19:30:27.000000000 -0500 @@ -182,6 +182,11 @@ do_kdsk_ioctl(int cmd, struct kbentry *u case KDSKBENT: if (!perm) return -EPERM; +#ifdef CONFIG_GRKERNSEC + if (!capable(CAP_SYS_TTY_CONFIG)) + return -EPERM; +#endif + if (!i && v == K_NOSUCHMAP) { /* disallocate map */ key_map = key_maps[s]; @@ -307,6 +312,11 @@ do_kdgkb_ioctl(int cmd, struct kbsentry if (!perm) return -EPERM; +#ifdef CONFIG_GRKERNSEC + if (!capable(CAP_SYS_TTY_CONFIG)) + return -EPERM; +#endif + q = func_table[i]; first_free = funcbufptr + (funcbufsize - funcbufleft); for (j = i+1; j < MAX_NR_FUNC && !func_table[j]; j++) @@ -449,7 +459,11 @@ int vt_ioctl(struct tty_struct *tty, str * to be the owner of the tty, or super-user. */ perm = 0; +#ifdef CONFIG_GRKERNSEC + if (current->tty == tty || capable(CAP_SYS_TTY_CONFIG)) +#else if (current->tty == tty || suser()) +#endif perm = 1; kbd = kbd_table + console; @@ -1043,12 +1057,20 @@ int vt_ioctl(struct tty_struct *tty, str return do_unimap_ioctl(cmd, (struct unimapdesc *)arg, perm); case VT_LOCKSWITCH: +#ifdef CONFIG_GRKERNSEC + if (!capable(CAP_SYS_TTY_CONFIG)) +#else if (!suser()) +#endif return -EPERM; vt_dont_switch = 1; return 0; case VT_UNLOCKSWITCH: +#ifdef CONFIG_GRKERNSEC + if (!capable(CAP_SYS_TTY_CONFIG)) +#else if (!suser()) +#endif return -EPERM; vt_dont_switch = 0; return 0; diff -urNp linux-2.4.37.7/drivers/char/w83877f_wdt.c linux-2.4.37.7/drivers/char/w83877f_wdt.c --- linux-2.4.37.7/drivers/char/w83877f_wdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/w83877f_wdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -268,7 +268,7 @@ static int fop_ioctl(struct inode *inode } } -static struct file_operations wdt_fops = { +static const struct file_operations wdt_fops = { owner: THIS_MODULE, llseek: no_llseek, read: fop_read, diff -urNp linux-2.4.37.7/drivers/char/wafer5823wdt.c linux-2.4.37.7/drivers/char/wafer5823wdt.c --- linux-2.4.37.7/drivers/char/wafer5823wdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/wafer5823wdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -199,7 +199,7 @@ static int wafwdt_notify_sys(struct noti * Kernel Interfaces */ -static struct file_operations wafwdt_fops = { +static const struct file_operations wafwdt_fops = { owner:THIS_MODULE, write:wafwdt_write, ioctl:wafwdt_ioctl, diff -urNp linux-2.4.37.7/drivers/char/wdt285.c linux-2.4.37.7/drivers/char/wdt285.c --- linux-2.4.37.7/drivers/char/wdt285.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/wdt285.c 2009-11-10 19:30:27.000000000 -0500 @@ -161,8 +161,7 @@ static int watchdog_ioctl(struct inode * } } -static struct file_operations watchdog_fops= -{ +static const struct file_operations watchdog_fops = { owner: THIS_MODULE, write: watchdog_write, ioctl: watchdog_ioctl, diff -urNp linux-2.4.37.7/drivers/char/wdt977.c linux-2.4.37.7/drivers/char/wdt977.c --- linux-2.4.37.7/drivers/char/wdt977.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/wdt977.c 2009-11-10 19:30:27.000000000 -0500 @@ -194,8 +194,7 @@ static ssize_t wdt977_write(struct file return 1; } -static struct file_operations wdt977_fops= -{ +static const struct file_operations wdt977_fops = { owner: THIS_MODULE, write: wdt977_write, open: wdt977_open, diff -urNp linux-2.4.37.7/drivers/char/wdt.c linux-2.4.37.7/drivers/char/wdt.c --- linux-2.4.37.7/drivers/char/wdt.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/wdt.c 2009-11-10 19:30:27.000000000 -0500 @@ -459,7 +459,7 @@ static int wdt_notify_sys(struct notifie */ -static struct file_operations wdt_fops = { +static const struct file_operations wdt_fops = { owner: THIS_MODULE, llseek: no_llseek, read: wdt_read, diff -urNp linux-2.4.37.7/drivers/char/wdt_pci.c linux-2.4.37.7/drivers/char/wdt_pci.c --- linux-2.4.37.7/drivers/char/wdt_pci.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/char/wdt_pci.c 2009-11-10 19:30:27.000000000 -0500 @@ -475,7 +475,7 @@ static int wdtpci_notify_sys(struct noti */ -static struct file_operations wdtpci_fops = { +static const struct file_operations wdtpci_fops = { owner: THIS_MODULE, llseek: no_llseek, read: wdtpci_read, diff -urNp linux-2.4.37.7/drivers/gsc/eisa_eeprom.c linux-2.4.37.7/drivers/gsc/eisa_eeprom.c --- linux-2.4.37.7/drivers/gsc/eisa_eeprom.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/gsc/eisa_eeprom.c 2009-11-10 19:30:27.000000000 -0500 @@ -84,7 +84,7 @@ static int eisa_eeprom_release(struct in /* * The various file operations we support. */ -static struct file_operations eisa_eeprom_fops = { +static const struct file_operations eisa_eeprom_fops = { owner: THIS_MODULE, llseek: eisa_eeprom_llseek, read: eisa_eeprom_read, diff -urNp linux-2.4.37.7/drivers/hil/hp_sdc_rtc.c linux-2.4.37.7/drivers/hil/hp_sdc_rtc.c --- linux-2.4.37.7/drivers/hil/hp_sdc_rtc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/hil/hp_sdc_rtc.c 2009-11-10 19:30:27.000000000 -0500 @@ -675,7 +675,7 @@ static int hp_sdc_rtc_ioctl(struct inode #endif } -static struct file_operations hp_sdc_rtc_fops = { +static const struct file_operations hp_sdc_rtc_fops = { .owner = THIS_MODULE, .llseek = hp_sdc_rtc_llseek, .read = hp_sdc_rtc_read, diff -urNp linux-2.4.37.7/drivers/hotplug/cpqphp_nvram.c linux-2.4.37.7/drivers/hotplug/cpqphp_nvram.c --- linux-2.4.37.7/drivers/hotplug/cpqphp_nvram.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/hotplug/cpqphp_nvram.c 2009-11-10 19:30:27.000000000 -0500 @@ -425,9 +425,13 @@ static u32 store_HRT (void *rom_start) void compaq_nvram_init (void *rom_start) { + +#ifndef CONFIG_PAX_KERNEXEC if (rom_start) { compaq_int15_entry_point = (rom_start + ROM_INT15_PHY_ADDR - ROM_PHY_ADDR); } +#endif + dbg("int15 entry = %p\n", compaq_int15_entry_point); /* initialize our int15 lock */ diff -urNp linux-2.4.37.7/drivers/hotplug/pci_hotplug_core.c linux-2.4.37.7/drivers/hotplug/pci_hotplug_core.c --- linux-2.4.37.7/drivers/hotplug/pci_hotplug_core.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/hotplug/pci_hotplug_core.c 2009-11-10 19:30:27.000000000 -0500 @@ -80,9 +80,9 @@ struct hotplug_slot_core { struct dentry *cur_bus_speed_dentry; }; -static struct super_operations pcihpfs_ops; -static struct file_operations default_file_operations; -static struct inode_operations pcihpfs_dir_inode_operations; +static const struct super_operations pcihpfs_ops; +static const struct file_operations default_file_operations; +static const struct inode_operations pcihpfs_dir_inode_operations; static struct vfsmount *pcihpfs_mount; /* one of the mounts of our fs for reference counting */ static int pcihpfs_mount_count; /* times we have mounted our fs */ static spinlock_t mount_lock; /* protects our mount_count */ @@ -269,7 +269,7 @@ static int default_open (struct inode *i return 0; } -static struct file_operations default_file_operations = { +static const struct file_operations default_file_operations = { read: default_read_file, write: default_write_file, open: default_open, @@ -279,7 +279,7 @@ static struct file_operations default_fi /* file ops for the "power" files */ static ssize_t power_read_file (struct file *file, char *buf, size_t count, loff_t *offset); static ssize_t power_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos); -static struct file_operations power_file_operations = { +static const struct file_operations power_file_operations = { read: power_read_file, write: power_write_file, open: default_open, @@ -289,7 +289,7 @@ static struct file_operations power_file /* file ops for the "attention" files */ static ssize_t attention_read_file (struct file *file, char *buf, size_t count, loff_t *offset); static ssize_t attention_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos); -static struct file_operations attention_file_operations = { +static const struct file_operations attention_file_operations = { read: attention_read_file, write: attention_write_file, open: default_open, @@ -298,7 +298,7 @@ static struct file_operations attention_ /* file ops for the "latch" files */ static ssize_t latch_read_file (struct file *file, char *buf, size_t count, loff_t *offset); -static struct file_operations latch_file_operations = { +static const struct file_operations latch_file_operations = { read: latch_read_file, write: default_write_file, open: default_open, @@ -307,7 +307,7 @@ static struct file_operations latch_file /* file ops for the "presence" files */ static ssize_t presence_read_file (struct file *file, char *buf, size_t count, loff_t *offset); -static struct file_operations presence_file_operations = { +static const struct file_operations presence_file_operations = { read: presence_read_file, write: default_write_file, open: default_open, @@ -316,7 +316,7 @@ static struct file_operations presence_f /* file ops for the "address" files */ static ssize_t address_read_file (struct file *file, char *buf, size_t count, loff_t *offset); -static struct file_operations address_file_operations = { +static const struct file_operations address_file_operations = { read: address_read_file, write: default_write_file, open: default_open, @@ -325,7 +325,7 @@ static struct file_operations address_fi /* file ops for the "max bus speed" files */ static ssize_t max_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset); -static struct file_operations max_bus_speed_file_operations = { +static const struct file_operations max_bus_speed_file_operations = { read: max_bus_speed_read_file, write: default_write_file, open: default_open, @@ -334,7 +334,7 @@ static struct file_operations max_bus_sp /* file ops for the "current bus speed" files */ static ssize_t cur_bus_speed_read_file (struct file *file, char *buf, size_t count, loff_t *offset); -static struct file_operations cur_bus_speed_file_operations = { +static const struct file_operations cur_bus_speed_file_operations = { read: cur_bus_speed_read_file, write: default_write_file, open: default_open, @@ -343,14 +343,14 @@ static struct file_operations cur_bus_sp /* file ops for the "test" files */ static ssize_t test_write_file (struct file *file, const char *buf, size_t count, loff_t *ppos); -static struct file_operations test_file_operations = { +static const struct file_operations test_file_operations = { read: default_read_file, write: test_write_file, open: default_open, llseek: default_file_lseek, }; -static struct inode_operations pcihpfs_dir_inode_operations = { +static const struct inode_operations pcihpfs_dir_inode_operations = { create: pcihpfs_create, lookup: pcihpfs_lookup, unlink: pcihpfs_unlink, @@ -359,7 +359,7 @@ static struct inode_operations pcihpfs_d mknod: pcihpfs_mknod, }; -static struct super_operations pcihpfs_ops = { +static const struct super_operations pcihpfs_ops = { statfs: pcihpfs_statfs, put_inode: force_delete, }; @@ -514,7 +514,7 @@ static int pcihpfs_create_by_name (const static struct dentry *fs_create_file (const char *name, mode_t mode, struct dentry *parent, void *data, - struct file_operations *fops) + const struct file_operations *fops) { struct dentry *dentry; int error; diff -urNp linux-2.4.37.7/drivers/i2c/i2c-core.c linux-2.4.37.7/drivers/i2c/i2c-core.c --- linux-2.4.37.7/drivers/i2c/i2c-core.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/i2c/i2c-core.c 2009-11-10 19:30:27.000000000 -0500 @@ -86,7 +86,7 @@ static int read_bus_i2c(char *buf, char /* To implement the dynamic /proc/bus/i2c-? files, we need our own implementation of the read hook */ -static struct file_operations i2cproc_operations = { +static const struct file_operations i2cproc_operations = { .read = i2cproc_bus_read, }; diff -urNp linux-2.4.37.7/drivers/i2c/i2c-dev.c linux-2.4.37.7/drivers/i2c/i2c-dev.c --- linux-2.4.37.7/drivers/i2c/i2c-dev.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/i2c/i2c-dev.c 2009-11-10 19:30:27.000000000 -0500 @@ -79,7 +79,7 @@ extern int __init i2c_dev_init(void); static int i2cdev_cleanup(void); -static struct file_operations i2cdev_fops = { +static const struct file_operations i2cdev_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = i2cdev_read, diff -urNp linux-2.4.37.7/drivers/ide/ide-tape.c linux-2.4.37.7/drivers/ide/ide-tape.c --- linux-2.4.37.7/drivers/ide/ide-tape.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/ide/ide-tape.c 2009-11-10 19:30:27.000000000 -0500 @@ -6500,7 +6500,7 @@ static ide_module_t idetape_module = { /* * Our character device supporting functions, passed to register_chrdev. */ -static struct file_operations idetape_fops = { +static const struct file_operations idetape_fops = { owner: THIS_MODULE, read: idetape_chrdev_read, write: idetape_chrdev_write, diff -urNp linux-2.4.37.7/drivers/ieee1394/amdtp.c linux-2.4.37.7/drivers/ieee1394/amdtp.c --- linux-2.4.37.7/drivers/ieee1394/amdtp.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/ieee1394/amdtp.c 2009-11-10 19:30:27.000000000 -0500 @@ -1196,8 +1196,7 @@ static int amdtp_release(struct inode *i return 0; } -static struct file_operations amdtp_fops = -{ +static const struct file_operations amdtp_fops = { .owner = THIS_MODULE, .write = amdtp_write, .poll = amdtp_poll, diff -urNp linux-2.4.37.7/drivers/ieee1394/dma.c linux-2.4.37.7/drivers/ieee1394/dma.c --- linux-2.4.37.7/drivers/ieee1394/dma.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/ieee1394/dma.c 2009-11-10 19:30:27.000000000 -0500 @@ -210,7 +210,7 @@ out: return ret; } -static struct vm_operations_struct dma_region_vm_ops = { +static const struct vm_operations_struct dma_region_vm_ops = { .nopage = dma_region_pagefault, }; diff -urNp linux-2.4.37.7/drivers/ieee1394/dv1394.c linux-2.4.37.7/drivers/ieee1394/dv1394.c --- linux-2.4.37.7/drivers/ieee1394/dv1394.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/ieee1394/dv1394.c 2009-11-10 19:30:27.000000000 -0500 @@ -2414,8 +2414,7 @@ out: spin_unlock(&video->spinlock); } -static struct file_operations dv1394_fops= -{ +static const struct file_operations dv1394_fops = { .owner = THIS_MODULE, .poll = dv1394_poll, .ioctl = dv1394_ioctl, diff -urNp linux-2.4.37.7/drivers/ieee1394/ieee1394_core.c linux-2.4.37.7/drivers/ieee1394/ieee1394_core.c --- linux-2.4.37.7/drivers/ieee1394/ieee1394_core.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/ieee1394/ieee1394_core.c 2009-11-10 19:30:27.000000000 -0500 @@ -1008,7 +1008,7 @@ static rwlock_t ieee1394_chardevs_lock = static int ieee1394_dispatch_open(struct inode *inode, struct file *file); -static struct file_operations ieee1394_chardev_ops = { +static const struct file_operations ieee1394_chardev_ops = { .owner =THIS_MODULE, .open = ieee1394_dispatch_open, }; diff -urNp linux-2.4.37.7/drivers/ieee1394/ohci1394.c linux-2.4.37.7/drivers/ieee1394/ohci1394.c --- linux-2.4.37.7/drivers/ieee1394/ohci1394.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/ieee1394/ohci1394.c 2009-11-10 19:30:27.000000000 -0500 @@ -169,8 +169,8 @@ static char version[] __devinitdata = /* Module Parameters */ MODULE_PARM(phys_dma,"i"); -MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 1)."); -static int phys_dma = 1; +MODULE_PARM_DESC(phys_dma, "Enable physical dma (default = 0)."); +static int phys_dma = 0; static void dma_trm_tasklet(unsigned long data); static void dma_trm_reset(struct dma_trm_ctx *d); diff -urNp linux-2.4.37.7/drivers/ieee1394/pcilynx.c linux-2.4.37.7/drivers/ieee1394/pcilynx.c --- linux-2.4.37.7/drivers/ieee1394/pcilynx.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/ieee1394/pcilynx.c 2009-11-10 19:30:27.000000000 -0500 @@ -861,7 +861,7 @@ static ssize_t mem_read (struct file*, c static ssize_t mem_write(struct file*, const char*, size_t, loff_t*); -static struct file_operations aux_ops = { +static const struct file_operations aux_ops = { .owner = THIS_MODULE, .read = mem_read, .write = mem_write, diff -urNp linux-2.4.37.7/drivers/ieee1394/raw1394.c linux-2.4.37.7/drivers/ieee1394/raw1394.c --- linux-2.4.37.7/drivers/ieee1394/raw1394.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/ieee1394/raw1394.c 2009-11-10 19:30:27.000000000 -0500 @@ -2538,7 +2538,7 @@ static struct hpsb_highlevel raw1394_hig .fcp_request = fcp_request, }; -static struct file_operations file_ops = { +static const struct file_operations file_ops = { .owner = THIS_MODULE, .read = raw1394_read, .write = raw1394_write, diff -urNp linux-2.4.37.7/drivers/ieee1394/video1394.c linux-2.4.37.7/drivers/ieee1394/video1394.c --- linux-2.4.37.7/drivers/ieee1394/video1394.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/ieee1394/video1394.c 2009-11-10 19:30:27.000000000 -0500 @@ -1254,8 +1254,7 @@ static int video1394_release(struct inod return 0; } -static struct file_operations video1394_fops= -{ +static const struct file_operations video1394_fops = { .owner = THIS_MODULE, .ioctl = video1394_ioctl, .mmap = video1394_mmap, diff -urNp linux-2.4.37.7/drivers/input/evdev.c linux-2.4.37.7/drivers/input/evdev.c --- linux-2.4.37.7/drivers/input/evdev.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/input/evdev.c 2009-11-10 19:30:27.000000000 -0500 @@ -317,7 +317,7 @@ static int evdev_ioctl(struct inode *ino return -EINVAL; } -static struct file_operations evdev_fops = { +static const struct file_operations evdev_fops = { owner: THIS_MODULE, read: evdev_read, write: evdev_write, diff -urNp linux-2.4.37.7/drivers/input/input.c linux-2.4.37.7/drivers/input/input.c --- linux-2.4.37.7/drivers/input/input.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/input/input.c 2009-11-10 19:30:27.000000000 -0500 @@ -371,7 +371,7 @@ void input_unregister_handler(struct inp static int input_open_file(struct inode *inode, struct file *file) { struct input_handler *handler = input_table[MINOR(inode->i_rdev) >> 5]; - struct file_operations *old_fops, *new_fops = NULL; + const struct file_operations *old_fops, *new_fops = NULL; int err; /* No load-on-demand here? */ @@ -401,7 +401,7 @@ static int input_open_file(struct inode return err; } -static struct file_operations input_fops = { +static const struct file_operations input_fops = { owner: THIS_MODULE, open: input_open_file, }; diff -urNp linux-2.4.37.7/drivers/input/joydev.c linux-2.4.37.7/drivers/input/joydev.c --- linux-2.4.37.7/drivers/input/joydev.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/input/joydev.c 2009-11-10 19:30:27.000000000 -0500 @@ -409,7 +409,7 @@ static int joydev_ioctl(struct inode *in return -EINVAL; } -static struct file_operations joydev_fops = { +static const struct file_operations joydev_fops = { owner: THIS_MODULE, read: joydev_read, write: joydev_write, diff -urNp linux-2.4.37.7/drivers/input/mousedev.c linux-2.4.37.7/drivers/input/mousedev.c --- linux-2.4.37.7/drivers/input/mousedev.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/input/mousedev.c 2009-11-10 19:30:27.000000000 -0500 @@ -393,7 +393,7 @@ static unsigned int mousedev_poll(struct return 0; } -struct file_operations mousedev_fops = { +const struct file_operations mousedev_fops = { owner: THIS_MODULE, read: mousedev_read, write: mousedev_write, diff -urNp linux-2.4.37.7/drivers/input/uinput.c linux-2.4.37.7/drivers/input/uinput.c --- linux-2.4.37.7/drivers/input/uinput.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/input/uinput.c 2009-11-10 19:30:27.000000000 -0500 @@ -393,7 +393,7 @@ static int uinput_ioctl(struct inode *in return retval; } -struct file_operations uinput_fops = { +const struct file_operations uinput_fops = { owner: THIS_MODULE, open: uinput_open, release: uinput_close, diff -urNp linux-2.4.37.7/drivers/isdn/avmb1/capi.c linux-2.4.37.7/drivers/isdn/avmb1/capi.c --- linux-2.4.37.7/drivers/isdn/avmb1/capi.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/isdn/avmb1/capi.c 2009-11-10 19:30:27.000000000 -0500 @@ -1068,8 +1068,7 @@ capi_release(struct inode *inode, struct return 0; } -static struct file_operations capi_fops = -{ +static const struct file_operations capi_fops = { owner: THIS_MODULE, llseek: no_llseek, read: capi_read, @@ -1258,8 +1257,7 @@ capinc_raw_release(struct inode *inode, return 0; } -static struct file_operations capinc_raw_fops = -{ +static const struct file_operations capinc_raw_fops = { owner: THIS_MODULE, llseek: no_llseek, read: capinc_raw_read, diff -urNp linux-2.4.37.7/drivers/isdn/avmb1/capifs.c linux-2.4.37.7/drivers/isdn/avmb1/capifs.c --- linux-2.4.37.7/drivers/isdn/avmb1/capifs.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/isdn/avmb1/capifs.c 2009-11-10 19:30:27.000000000 -0500 @@ -71,16 +71,16 @@ static struct dentry *capifs_root_lookup static int capifs_revalidate(struct dentry *, int); static struct inode *capifs_new_inode(struct super_block *sb); -static struct file_operations capifs_root_operations = { +static const struct file_operations capifs_root_operations = { read: generic_read_dir, readdir: capifs_root_readdir, }; -struct inode_operations capifs_root_inode_operations = { +const struct inode_operations capifs_root_inode_operations = { lookup: capifs_root_lookup, }; -static struct dentry_operations capifs_dentry_operations = { +static const struct dentry_operations capifs_dentry_operations = { d_revalidate: capifs_revalidate, }; @@ -217,7 +217,7 @@ static void capifs_put_super(struct supe static int capifs_statfs(struct super_block *sb, struct statfs *buf); -static struct super_operations capifs_sops = { +static const struct super_operations capifs_sops = { put_super: capifs_put_super, statfs: capifs_statfs, }; diff -urNp linux-2.4.37.7/drivers/isdn/divert/divert_procfs.c linux-2.4.37.7/drivers/isdn/divert/divert_procfs.c --- linux-2.4.37.7/drivers/isdn/divert/divert_procfs.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/isdn/divert/divert_procfs.c 2009-11-10 19:30:27.000000000 -0500 @@ -266,8 +266,7 @@ isdn_divert_ioctl(struct inode *inode, s #ifdef CONFIG_PROC_FS -static struct file_operations isdn_fops = -{ +static const struct file_operations isdn_fops = { llseek: no_llseek, read: isdn_divert_read, write: isdn_divert_write, diff -urNp linux-2.4.37.7/drivers/isdn/hysdn/hysdn_procconf.c linux-2.4.37.7/drivers/isdn/hysdn/hysdn_procconf.c --- linux-2.4.37.7/drivers/isdn/hysdn/hysdn_procconf.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/isdn/hysdn/hysdn_procconf.c 2009-11-10 19:30:27.000000000 -0500 @@ -378,8 +378,7 @@ hysdn_conf_close(struct inode *ino, stru /******************************************************/ /* table for conf filesystem functions defined above. */ /******************************************************/ -static struct file_operations conf_fops = -{ +static const struct file_operations conf_fops = { llseek: no_llseek, read: hysdn_conf_read, write: hysdn_conf_write, diff -urNp linux-2.4.37.7/drivers/isdn/hysdn/hysdn_proclog.c linux-2.4.37.7/drivers/isdn/hysdn/hysdn_proclog.c --- linux-2.4.37.7/drivers/isdn/hysdn/hysdn_proclog.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/isdn/hysdn/hysdn_proclog.c 2009-11-10 19:30:27.000000000 -0500 @@ -390,8 +390,7 @@ hysdn_log_poll(struct file *file, poll_t /**************************************************/ /* table for log filesystem functions defined above. */ /**************************************************/ -static struct file_operations log_fops = -{ +static const struct file_operations log_fops = { llseek: no_llseek, read: hysdn_log_read, write: hysdn_log_write, diff -urNp linux-2.4.37.7/drivers/isdn/isdn_common.c linux-2.4.37.7/drivers/isdn/isdn_common.c --- linux-2.4.37.7/drivers/isdn/isdn_common.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/isdn/isdn_common.c 2009-11-10 19:30:27.000000000 -0500 @@ -1753,8 +1753,7 @@ isdn_close(struct inode *ino, struct fil return 0; } -static struct file_operations isdn_fops = -{ +static const struct file_operations isdn_fops = { owner: THIS_MODULE, llseek: no_llseek, read: isdn_read, diff -urNp linux-2.4.37.7/drivers/macintosh/adb.c linux-2.4.37.7/drivers/macintosh/adb.c --- linux-2.4.37.7/drivers/macintosh/adb.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/macintosh/adb.c 2009-11-10 19:30:27.000000000 -0500 @@ -835,7 +835,7 @@ out: return ret; } -static struct file_operations adb_fops = { +static const struct file_operations adb_fops = { llseek: no_llseek, read: adb_read, write: adb_write, diff -urNp linux-2.4.37.7/drivers/macintosh/ans-lcd.c linux-2.4.37.7/drivers/macintosh/ans-lcd.c --- linux-2.4.37.7/drivers/macintosh/ans-lcd.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/macintosh/ans-lcd.c 2009-11-10 19:30:27.000000000 -0500 @@ -118,7 +118,7 @@ anslcd_open( struct inode * inode, struc return 0; } -struct file_operations anslcd_fops = { +const struct file_operations anslcd_fops = { write: anslcd_write, ioctl: anslcd_ioctl, open: anslcd_open, diff -urNp linux-2.4.37.7/drivers/macintosh/apm_emu.c linux-2.4.37.7/drivers/macintosh/apm_emu.c --- linux-2.4.37.7/drivers/macintosh/apm_emu.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/macintosh/apm_emu.c 2009-11-10 19:30:27.000000000 -0500 @@ -498,7 +498,7 @@ static int apm_emu_get_info(char *buf, c return p - buf; } -static struct file_operations apm_bios_fops = { +static const struct file_operations apm_bios_fops = { owner: THIS_MODULE, read: do_read, poll: do_poll, diff -urNp linux-2.4.37.7/drivers/macintosh/nvram.c linux-2.4.37.7/drivers/macintosh/nvram.c --- linux-2.4.37.7/drivers/macintosh/nvram.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/macintosh/nvram.c 2009-11-10 19:30:27.000000000 -0500 @@ -97,7 +97,7 @@ static int nvram_ioctl(struct inode *ino return 0; } -struct file_operations nvram_fops = { +const struct file_operations nvram_fops = { owner: THIS_MODULE, llseek: nvram_llseek, read: read_nvram, diff -urNp linux-2.4.37.7/drivers/macintosh/rtc.c linux-2.4.37.7/drivers/macintosh/rtc.c --- linux-2.4.37.7/drivers/macintosh/rtc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/macintosh/rtc.c 2009-11-10 19:30:27.000000000 -0500 @@ -115,7 +115,7 @@ static int rtc_release(struct inode *ino return 0; } -static struct file_operations rtc_fops = { +static const struct file_operations rtc_fops = { owner: THIS_MODULE, llseek: no_llseek, ioctl: rtc_ioctl, diff -urNp linux-2.4.37.7/drivers/macintosh/via-pmu68k.c linux-2.4.37.7/drivers/macintosh/via-pmu68k.c --- linux-2.4.37.7/drivers/macintosh/via-pmu68k.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/macintosh/via-pmu68k.c 2009-11-10 19:30:27.000000000 -0500 @@ -1039,7 +1039,7 @@ static int /*__openfirmware*/ pmu_ioctl( return -EINVAL; } -static struct file_operations pmu_device_fops = { +static const struct file_operations pmu_device_fops = { read: pmu_read, write: pmu_write, ioctl: pmu_ioctl, diff -urNp linux-2.4.37.7/drivers/macintosh/via-pmu.c linux-2.4.37.7/drivers/macintosh/via-pmu.c --- linux-2.4.37.7/drivers/macintosh/via-pmu.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/macintosh/via-pmu.c 2009-11-10 19:30:27.000000000 -0500 @@ -2825,7 +2825,7 @@ static int pmu_ioctl(struct inode * inod return -EINVAL; } -static struct file_operations pmu_device_fops = { +static const struct file_operations pmu_device_fops = { read: pmu_read, write: pmu_write, poll: pmu_fpoll, diff -urNp linux-2.4.37.7/drivers/md/lvm.c linux-2.4.37.7/drivers/md/lvm.c --- linux-2.4.37.7/drivers/md/lvm.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/md/lvm.c 2009-11-10 19:30:27.000000000 -0500 @@ -405,7 +405,7 @@ static struct buffer_head *_pe_requests; static DECLARE_RWSEM(_pe_lock); -struct file_operations lvm_chr_fops = { +const struct file_operations lvm_chr_fops = { owner:THIS_MODULE, open:lvm_chr_open, release:lvm_chr_close, diff -urNp linux-2.4.37.7/drivers/md/lvm-internal.h linux-2.4.37.7/drivers/md/lvm-internal.h --- linux-2.4.37.7/drivers/md/lvm-internal.h 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/md/lvm-internal.h 2009-11-10 19:30:27.000000000 -0500 @@ -45,7 +45,6 @@ extern int loadtime; extern const char *const lvm_name; -extern uint vg_count; extern vg_t *vg[]; extern struct file_operations lvm_chr_fops; diff -urNp linux-2.4.37.7/drivers/md/md.c linux-2.4.37.7/drivers/md/md.c --- linux-2.4.37.7/drivers/md/md.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/md/md.c 2009-11-10 19:30:27.000000000 -0500 @@ -3295,7 +3295,7 @@ static int md_seq_show(struct seq_file * } -static struct seq_operations md_seq_ops = { +static const struct seq_operations md_seq_ops = { .start = md_seq_start, .next = md_seq_next, .stop = md_seq_stop, @@ -3310,7 +3310,7 @@ static int md_seq_open(struct inode *ino return error; } -static struct file_operations md_seq_fops = { +static const struct file_operations md_seq_fops = { .open = md_seq_open, .read = seq_read, .llseek = seq_lseek, diff -urNp linux-2.4.37.7/drivers/media/radio/miropcm20-rds.c linux-2.4.37.7/drivers/media/radio/miropcm20-rds.c --- linux-2.4.37.7/drivers/media/radio/miropcm20-rds.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/media/radio/miropcm20-rds.c 2009-11-10 19:30:27.000000000 -0500 @@ -105,7 +105,7 @@ static ssize_t rds_f_read(struct file *f } } -static struct file_operations rds_f_ops = { +static const struct file_operations rds_f_ops = { read: rds_f_read, open: rds_f_open, release: rds_f_release diff -urNp linux-2.4.37.7/drivers/media/video/cpia.c linux-2.4.37.7/drivers/media/video/cpia.c --- linux-2.4.37.7/drivers/media/video/cpia.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/media/video/cpia.c 2009-11-10 19:30:27.000000000 -0500 @@ -3064,7 +3064,7 @@ static int cpia_mmap(struct file *file, return 0; } -static struct file_operations cpia_fops = { +static const struct file_operations cpia_fops = { owner: THIS_MODULE, open: cpia_open, release: cpia_close, diff -urNp linux-2.4.37.7/drivers/media/video/meye.c linux-2.4.37.7/drivers/media/video/meye.c --- linux-2.4.37.7/drivers/media/video/meye.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/media/video/meye.c 2009-11-10 19:30:27.000000000 -0500 @@ -1252,7 +1252,7 @@ static int meye_mmap(struct file *file, return 0; } -static struct file_operations meye_fops = { +static const struct file_operations meye_fops = { .owner = THIS_MODULE, .open = meye_open, .release = meye_release, diff -urNp linux-2.4.37.7/drivers/media/video/tvmixer.c linux-2.4.37.7/drivers/media/video/tvmixer.c --- linux-2.4.37.7/drivers/media/video/tvmixer.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/media/video/tvmixer.c 2009-11-10 19:30:27.000000000 -0500 @@ -226,7 +226,7 @@ static struct i2c_driver driver = { .detach_client = tvmixer_clients, }; -static struct file_operations tvmixer_fops = { +static const struct file_operations tvmixer_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .ioctl = tvmixer_ioctl, diff -urNp linux-2.4.37.7/drivers/media/video/videodev.c linux-2.4.37.7/drivers/media/video/videodev.c --- linux-2.4.37.7/drivers/media/video/videodev.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/media/video/videodev.c 2009-11-10 19:30:27.000000000 -0500 @@ -155,7 +155,7 @@ static int video_open(struct inode *inod } } if (vfl->fops) { - struct file_operations *old_fops; + const struct file_operations *old_fops; old_fops = file->f_op; file->f_op = fops_get(vfl->fops); @@ -489,8 +489,7 @@ static void videodev_proc_destroy_dev (s #endif /* CONFIG_VIDEO_PROC_FS */ -static struct file_operations video_fops= -{ +static const struct file_operations video_fops = { owner: THIS_MODULE, llseek: no_llseek, read: video_read, diff -urNp linux-2.4.37.7/drivers/media/video/vino.c linux-2.4.37.7/drivers/media/video/vino.c --- linux-2.4.37.7/drivers/media/video/vino.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/media/video/vino.c 2009-11-10 19:30:27.000000000 -0500 @@ -1007,7 +1007,7 @@ static int vino_ioctl(struct inode *inod return err; } -static struct file_operations vino_fops = { +static const struct file_operations vino_fops = { .owner = THIS_MODULE, .open = vino_open, .release = vino_close, diff -urNp linux-2.4.37.7/drivers/message/fusion/mptctl.c linux-2.4.37.7/drivers/message/fusion/mptctl.c --- linux-2.4.37.7/drivers/message/fusion/mptctl.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/message/fusion/mptctl.c 2009-11-10 19:30:27.000000000 -0500 @@ -2738,7 +2738,7 @@ mptctl_hp_targetinfo(unsigned long arg) #define owner_THIS_MODULE #endif -static struct file_operations mptctl_fops = { +static const struct file_operations mptctl_fops = { owner_THIS_MODULE .llseek = no_llseek, .read = mptctl_read, diff -urNp linux-2.4.37.7/drivers/message/i2o/i2o_config.c linux-2.4.37.7/drivers/message/i2o/i2o_config.c --- linux-2.4.37.7/drivers/message/i2o/i2o_config.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/message/i2o/i2o_config.c 2009-11-10 19:30:27.000000000 -0500 @@ -890,8 +890,7 @@ static int cfg_fasync(int fd, struct fil return fasync_helper(fd, fp, on, &p->fasync); } -static struct file_operations config_fops = -{ +static const struct file_operations config_fops = { owner: THIS_MODULE, llseek: no_llseek, read: cfg_read, diff -urNp linux-2.4.37.7/drivers/mtd/devices/doc2001.c linux-2.4.37.7/drivers/mtd/devices/doc2001.c --- linux-2.4.37.7/drivers/mtd/devices/doc2001.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/mtd/devices/doc2001.c 2009-11-10 19:30:27.000000000 -0500 @@ -418,6 +418,8 @@ static int doc_read_ecc (struct mtd_info /* Don't allow read past end of device */ if (from >= this->totlen) return -EINVAL; + if (!len) + return -EINVAL; /* Don't allow a single read to cross a 512-byte block boundary */ if (from + len > ((from | 0x1ff) + 1)) diff -urNp linux-2.4.37.7/drivers/mtd/ftl.c linux-2.4.37.7/drivers/mtd/ftl.c --- linux-2.4.37.7/drivers/mtd/ftl.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/mtd/ftl.c 2009-11-10 19:30:27.000000000 -0500 @@ -231,7 +231,7 @@ static int ftl_reread_partitions(int min static void ftl_erase_callback(struct erase_info *done); #if LINUX_VERSION_CODE < 0x20326 -static struct file_operations ftl_blk_fops = { +static const struct file_operations ftl_blk_fops = { open: ftl_open, release: ftl_close, ioctl: ftl_ioctl, diff -urNp linux-2.4.37.7/drivers/mtd/mtdblock.c linux-2.4.37.7/drivers/mtd/mtdblock.c --- linux-2.4.37.7/drivers/mtd/mtdblock.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/mtd/mtdblock.c 2009-11-10 19:30:27.000000000 -0500 @@ -567,8 +567,7 @@ static int mtdblock_ioctl(struct inode * } #if LINUX_VERSION_CODE < 0x20326 -static struct file_operations mtd_fops = -{ +static const struct file_operations mtd_fops = { open: mtdblock_open, ioctl: mtdblock_ioctl, release: mtdblock_release, diff -urNp linux-2.4.37.7/drivers/mtd/mtdblock_ro.c linux-2.4.37.7/drivers/mtd/mtdblock_ro.c --- linux-2.4.37.7/drivers/mtd/mtdblock_ro.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/mtd/mtdblock_ro.c 2009-11-10 19:30:27.000000000 -0500 @@ -242,8 +242,7 @@ static int mtdblock_ioctl(struct inode * } #if LINUX_VERSION_CODE < 0x20326 -static struct file_operations mtd_fops = -{ +static const struct file_operations mtd_fops = { open: mtdblock_open, ioctl: mtdblock_ioctl, release: mtdblock_release, diff -urNp linux-2.4.37.7/drivers/mtd/mtdchar.c linux-2.4.37.7/drivers/mtd/mtdchar.c --- linux-2.4.37.7/drivers/mtd/mtdchar.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/mtd/mtdchar.c 2009-11-10 19:30:27.000000000 -0500 @@ -533,7 +533,7 @@ static int mtd_ioctl(struct inode *inode return ret; } /* memory_ioctl */ -static struct file_operations mtd_fops = { +static const struct file_operations mtd_fops = { owner: THIS_MODULE, llseek: mtd_lseek, /* lseek */ read: mtd_read, /* read */ diff -urNp linux-2.4.37.7/drivers/mtd/nftlcore.c linux-2.4.37.7/drivers/mtd/nftlcore.c --- linux-2.4.37.7/drivers/mtd/nftlcore.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/mtd/nftlcore.c 2009-11-10 19:30:27.000000000 -0500 @@ -1020,7 +1020,7 @@ static int nftl_release(struct inode *in return 0; } #if LINUX_VERSION_CODE < 0x20326 -static struct file_operations nftl_fops = { +static const struct file_operations nftl_fops = { read: block_read, write: block_write, ioctl: nftl_ioctl, diff -urNp linux-2.4.37.7/drivers/net/bonding/bond_main.c linux-2.4.37.7/drivers/net/bonding/bond_main.c --- linux-2.4.37.7/drivers/net/bonding/bond_main.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/net/bonding/bond_main.c 2009-11-10 19:30:27.000000000 -0500 @@ -3246,7 +3246,7 @@ static int bond_info_seq_show(struct seq return 0; } -static struct seq_operations bond_info_seq_ops = { +static const struct seq_operations bond_info_seq_ops = { .start = bond_info_seq_start, .next = bond_info_seq_next, .stop = bond_info_seq_stop, @@ -3270,7 +3270,7 @@ static int bond_info_open(struct inode * return res; } -static struct file_operations bond_info_fops = { +static const struct file_operations bond_info_fops = { .owner = THIS_MODULE, .open = bond_info_open, .read = seq_read, diff -urNp linux-2.4.37.7/drivers/net/ibmveth.c linux-2.4.37.7/drivers/net/ibmveth.c --- linux-2.4.37.7/drivers/net/ibmveth.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/net/ibmveth.c 2009-11-10 19:30:27.000000000 -0500 @@ -1013,7 +1013,7 @@ static int ibmveth_seq_show(struct seq_f return 0; } -static struct seq_operations ibmveth_seq_ops = { +static const struct seq_operations ibmveth_seq_ops = { .start = ibmveth_seq_start, .next = ibmveth_seq_next, .stop = ibmveth_seq_stop, @@ -1036,7 +1036,7 @@ static int ibmveth_proc_open(struct inod return rc; } -static struct file_operations ibmveth_proc_fops = { +static const struct file_operations ibmveth_proc_fops = { .owner = THIS_MODULE, .open = ibmveth_proc_open, .read = seq_read, diff -urNp linux-2.4.37.7/drivers/net/ppp_generic.c linux-2.4.37.7/drivers/net/ppp_generic.c --- linux-2.4.37.7/drivers/net/ppp_generic.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/net/ppp_generic.c 2009-11-10 19:30:27.000000000 -0500 @@ -764,7 +764,7 @@ static int ppp_unattached_ioctl(struct p return err; } -static struct file_operations ppp_device_fops = { +static const struct file_operations ppp_device_fops = { owner: THIS_MODULE, read: ppp_read, write: ppp_write, diff -urNp linux-2.4.37.7/drivers/net/tun.c linux-2.4.37.7/drivers/net/tun.c --- linux-2.4.37.7/drivers/net/tun.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/net/tun.c 2009-11-10 19:30:27.000000000 -0500 @@ -563,7 +563,7 @@ static int tun_chr_close(struct inode *i return 0; } -static struct file_operations tun_fops = { +static const struct file_operations tun_fops = { owner: THIS_MODULE, llseek: no_llseek, read: tun_chr_read, diff -urNp linux-2.4.37.7/drivers/net/wan/8253x/8253xini.c linux-2.4.37.7/drivers/net/wan/8253x/8253xini.c --- linux-2.4.37.7/drivers/net/wan/8253x/8253xini.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/net/wan/8253x/8253xini.c 2009-11-10 19:30:27.000000000 -0500 @@ -182,8 +182,7 @@ struct net_device auraXX20n_prototype = sab8253xn_init /* network driver initialization */ }; -struct file_operations sab8253xc_fops = -{ +const struct file_operations sab8253xc_fops = { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 0)) NULL, #endif diff -urNp linux-2.4.37.7/drivers/net/wan/comx.c linux-2.4.37.7/drivers/net/wan/comx.c --- linux-2.4.37.7/drivers/net/wan/comx.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/net/wan/comx.c 2009-11-10 19:30:27.000000000 -0500 @@ -96,7 +96,7 @@ static int comx_mkdir(struct inode *, st static int comx_rmdir(struct inode *, struct dentry *); static struct dentry *comx_lookup(struct inode *, struct dentry *); -static struct inode_operations comx_root_inode_ops = { +static const struct inode_operations comx_root_inode_ops = { lookup: comx_lookup, mkdir: comx_mkdir, rmdir: comx_rmdir, @@ -106,7 +106,7 @@ static int comx_delete_dentry(struct den static struct proc_dir_entry *create_comx_proc_entry(char *name, int mode, int size, struct proc_dir_entry *dir); -static struct dentry_operations comx_dentry_operations = { +static const struct dentry_operations comx_dentry_operations = { d_delete: comx_delete_dentry, }; diff -urNp linux-2.4.37.7/drivers/net/wan/cosa.c linux-2.4.37.7/drivers/net/wan/cosa.c --- linux-2.4.37.7/drivers/net/wan/cosa.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/net/wan/cosa.c 2009-11-10 19:30:27.000000000 -0500 @@ -310,7 +310,7 @@ static int cosa_chardev_ioctl(struct ino static int cosa_fasync(struct inode *inode, struct file *file, int on); #endif -static struct file_operations cosa_fops = { +static const struct file_operations cosa_fops = { owner: THIS_MODULE, llseek: no_llseek, read: cosa_read, diff -urNp linux-2.4.37.7/drivers/net/wan/sdla_ppp.c linux-2.4.37.7/drivers/net/wan/sdla_ppp.c --- linux-2.4.37.7/drivers/net/wan/sdla_ppp.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/net/wan/sdla_ppp.c 2009-11-10 19:30:27.000000000 -0500 @@ -467,7 +467,7 @@ static int update(wan_device_t *wandev) sdla_t* card = wandev->private; netdevice_t* dev; volatile ppp_private_area_t *ppp_priv_area; - ppp_flags_t *flags = card->flags; + ppp_flags_t *flags; unsigned long timeout; /* sanity checks */ @@ -491,6 +491,7 @@ static int update(wan_device_t *wandev) ppp_priv_area->update_comms_stats = 2; ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UPDATE; + flags = card->flags; flags->imask |= PPP_INTR_TIMER; /* wait a maximum of 1 second for the statistics to be updated */ diff -urNp linux-2.4.37.7/drivers/net/wireless/airo.c linux-2.4.37.7/drivers/net/wireless/airo.c --- linux-2.4.37.7/drivers/net/wireless/airo.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/net/wireless/airo.c 2009-11-10 19:30:27.000000000 -0500 @@ -3473,53 +3473,53 @@ static int proc_BSSList_open( struct ino static int proc_config_open( struct inode *inode, struct file *file ); static int proc_wepkey_open( struct inode *inode, struct file *file ); -static struct file_operations proc_statsdelta_ops = { +static const struct file_operations proc_statsdelta_ops = { .read = proc_read, .open = proc_statsdelta_open, .release = proc_close }; -static struct file_operations proc_stats_ops = { +static const struct file_operations proc_stats_ops = { .read = proc_read, .open = proc_stats_open, .release = proc_close }; -static struct file_operations proc_status_ops = { +static const struct file_operations proc_status_ops = { .read = proc_read, .open = proc_status_open, .release = proc_close }; -static struct file_operations proc_SSID_ops = { +static const struct file_operations proc_SSID_ops = { .read = proc_read, .write = proc_write, .open = proc_SSID_open, .release = proc_close }; -static struct file_operations proc_BSSList_ops = { +static const struct file_operations proc_BSSList_ops = { .read = proc_read, .write = proc_write, .open = proc_BSSList_open, .release = proc_close }; -static struct file_operations proc_APList_ops = { +static const struct file_operations proc_APList_ops = { .read = proc_read, .write = proc_write, .open = proc_APList_open, .release = proc_close }; -static struct file_operations proc_config_ops = { +static const struct file_operations proc_config_ops = { .read = proc_read, .write = proc_write, .open = proc_config_open, .release = proc_close }; -static struct file_operations proc_wepkey_ops = { +static const struct file_operations proc_wepkey_ops = { .read = proc_read, .write = proc_write, .open = proc_wepkey_open, diff -urNp linux-2.4.37.7/drivers/pci/proc.c linux-2.4.37.7/drivers/pci/proc.c --- linux-2.4.37.7/drivers/pci/proc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/pci/proc.c 2009-11-10 19:30:27.000000000 -0500 @@ -284,7 +284,7 @@ static int proc_bus_pci_release(struct i } #endif /* HAVE_PCI_MMAP */ -static struct file_operations proc_bus_pci_operations = { +static const struct file_operations proc_bus_pci_operations = { llseek: proc_bus_pci_lseek, read: proc_bus_pci_read, write: proc_bus_pci_write, @@ -364,7 +364,7 @@ static int show_device(struct seq_file * return 0; } -static struct seq_operations proc_bus_pci_devices_op = { +static const struct seq_operations proc_bus_pci_devices_op = { start: pci_seq_start, next: pci_seq_next, stop: pci_seq_stop, @@ -524,7 +524,7 @@ static int show_dev_config(struct seq_fi return 0; } -static struct seq_operations proc_pci_op = { +static const struct seq_operations proc_pci_op = { start: pci_seq_start, next: pci_seq_next, stop: pci_seq_stop, @@ -535,7 +535,7 @@ static int proc_bus_pci_dev_open(struct { return seq_open(file, &proc_bus_pci_devices_op); } -static struct file_operations proc_bus_pci_dev_operations = { +static const struct file_operations proc_bus_pci_dev_operations = { open: proc_bus_pci_dev_open, read: seq_read, llseek: seq_lseek, @@ -545,7 +545,7 @@ static int proc_pci_open(struct inode *i { return seq_open(file, &proc_pci_op); } -static struct file_operations proc_pci_operations = { +static const struct file_operations proc_pci_operations = { open: proc_pci_open, read: seq_read, llseek: seq_lseek, @@ -564,7 +564,15 @@ static int __init pci_proc_init(void) pci_for_each_dev(dev) { pci_proc_attach_device(dev); } +#ifdef CONFIG_GRKERNSEC_PROC_ADD +#ifdef CONFIG_GRKERNSEC_PROC_USER + entry = create_proc_entry("pci", S_IRUSR, NULL); +#elif CONFIG_GRKERNSEC_PROC_USERGROUP + entry = create_proc_entry("pci", S_IRUSR | S_IRGRP, NULL); +#endif +#else entry = create_proc_entry("pci", 0, NULL); +#endif if (entry) entry->proc_fops = &proc_pci_operations; } diff -urNp linux-2.4.37.7/drivers/pcmcia/ds.c linux-2.4.37.7/drivers/pcmcia/ds.c --- linux-2.4.37.7/drivers/pcmcia/ds.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/pcmcia/ds.c 2009-11-10 19:30:27.000000000 -0500 @@ -867,7 +867,7 @@ static int ds_ioctl(struct inode * inode /*====================================================================*/ -static struct file_operations ds_fops = { +static const struct file_operations ds_fops = { owner: THIS_MODULE, open: ds_open, release: ds_release, diff -urNp linux-2.4.37.7/drivers/pnp/isapnp_proc.c linux-2.4.37.7/drivers/pnp/isapnp_proc.c --- linux-2.4.37.7/drivers/pnp/isapnp_proc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/pnp/isapnp_proc.c 2009-11-10 19:30:27.000000000 -0500 @@ -205,8 +205,7 @@ static unsigned int isapnp_info_entry_po return POLLIN | POLLRDNORM; } -static struct file_operations isapnp_info_entry_operations = -{ +static const struct file_operations isapnp_info_entry_operations = { llseek: isapnp_info_entry_lseek, read: isapnp_info_entry_read, write: isapnp_info_entry_write, @@ -269,8 +268,7 @@ static ssize_t isapnp_proc_bus_read(stru return nbytes; } -static struct file_operations isapnp_proc_bus_file_operations = -{ +static const struct file_operations isapnp_proc_bus_file_operations = { llseek: isapnp_proc_bus_lseek, read: isapnp_proc_bus_read, }; diff -urNp linux-2.4.37.7/drivers/s390/block/dasd.c linux-2.4.37.7/drivers/s390/block/dasd.c --- linux-2.4.37.7/drivers/s390/block/dasd.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/s390/block/dasd.c 2009-11-10 19:30:27.000000000 -0500 @@ -4968,14 +4968,14 @@ dasd_devices_close (struct inode *inode, return rc; } -static struct file_operations dasd_devices_file_ops = { +static const struct file_operations dasd_devices_file_ops = { read:dasd_generic_read, /* read */ write:dasd_devices_write, /* write */ open:dasd_devices_open, /* open */ release:dasd_devices_close, /* close */ }; -static struct inode_operations dasd_devices_inode_ops = { +static const struct inode_operations dasd_devices_inode_ops = { }; static int @@ -5248,14 +5248,14 @@ dasd_statistics_write (struct file *file return user_len; } -static struct file_operations dasd_statistics_file_ops = { +static const struct file_operations dasd_statistics_file_ops = { read:dasd_generic_read, /* read */ write:dasd_statistics_write, /* write */ open:dasd_statistics_open, /* open */ release:dasd_devices_close, /* close */ }; -static struct inode_operations dasd_statistics_inode_ops = { +static const struct inode_operations dasd_statistics_inode_ops = { }; int diff -urNp linux-2.4.37.7/drivers/s390/block/xpram.c linux-2.4.37.7/drivers/s390/block/xpram.c --- linux-2.4.37.7/drivers/s390/block/xpram.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/s390/block/xpram.c 2009-11-10 19:30:27.000000000 -0500 @@ -717,7 +717,7 @@ int xpram_ioctl (struct inode *inode, st */ #if (XPRAM_VERSION == 22) -struct file_operations xpram_fops = { +const struct file_operations xpram_fops = { NULL, /* lseek: default */ block_read, block_write, diff -urNp linux-2.4.37.7/drivers/s390/char/tapeblock.c linux-2.4.37.7/drivers/s390/char/tapeblock.c --- linux-2.4.37.7/drivers/s390/char/tapeblock.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/s390/char/tapeblock.c 2009-11-10 19:30:27.000000000 -0500 @@ -38,7 +38,7 @@ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98)) static struct block_device_operations tapeblock_fops = { #else -static struct file_operations tapeblock_fops = { +static const struct file_operations tapeblock_fops = { #endif owner : THIS_MODULE, open : tapeblock_open, /* open */ diff -urNp linux-2.4.37.7/drivers/s390/char/tape.c linux-2.4.37.7/drivers/s390/char/tape.c --- linux-2.4.37.7/drivers/s390/char/tape.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/s390/char/tape.c 2009-11-10 19:30:27.000000000 -0500 @@ -203,15 +203,13 @@ tape_devices_release (struct inode *inod return rc; } -static struct file_operations tape_devices_file_ops = -{ +static const struct file_operations tape_devices_file_ops = { read:tape_devices_read, /* read */ open:tape_devices_open, /* open */ release:tape_devices_release, /* close */ }; -static struct inode_operations tape_devices_inode_ops = -{ +static const struct inode_operations tape_devices_inode_ops = { #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98)) default_file_ops:&tape_devices_file_ops /* file ops */ #endif /* LINUX_IS_24 */ diff -urNp linux-2.4.37.7/drivers/s390/char/tapechar.c linux-2.4.37.7/drivers/s390/char/tapechar.c --- linux-2.4.37.7/drivers/s390/char/tapechar.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/s390/char/tapechar.c 2009-11-10 19:30:27.000000000 -0500 @@ -36,8 +36,7 @@ /* * file operation structure for tape devices */ -static struct file_operations tape_fops = -{ +static const struct file_operations tape_fops = { // owner : THIS_MODULE, llseek:NULL, /* lseek - default */ read:tape_read, /* read */ diff -urNp linux-2.4.37.7/drivers/s390/char/tubfs.c linux-2.4.37.7/drivers/s390/char/tubfs.c --- linux-2.4.37.7/drivers/s390/char/tubfs.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/s390/char/tubfs.c 2009-11-10 19:30:27.000000000 -0500 @@ -22,7 +22,7 @@ static int fs3270_wait(tub_t *, long *); static void fs3270_int(tub_t *tubp, devstat_t *dsp); extern void tty3270_refresh(tub_t *); -static struct file_operations fs3270_fops = { +static const struct file_operations fs3270_fops = { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)) owner: THIS_MODULE, /* owner */ #endif diff -urNp linux-2.4.37.7/drivers/s390/net/ctcmain.c linux-2.4.37.7/drivers/s390/net/ctcmain.c --- linux-2.4.37.7/drivers/s390/net/ctcmain.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/s390/net/ctcmain.c 2009-11-10 19:30:27.000000000 -0500 @@ -3202,38 +3202,38 @@ static ssize_t ctc_stat_read(struct file return ret; } -static struct file_operations ctc_stat_fops = { +static const struct file_operations ctc_stat_fops = { read: ctc_stat_read, write: ctc_stat_write, open: ctc_stat_open, release: ctc_stat_close, }; -static struct file_operations ctc_ctrl_fops = { +static const struct file_operations ctc_ctrl_fops = { read: ctc_ctrl_read, write: ctc_ctrl_write, open: ctc_ctrl_open, release: ctc_ctrl_close, }; -static struct file_operations ctc_loglevel_fops = { +static const struct file_operations ctc_loglevel_fops = { read: ctc_loglevel_read, write: ctc_loglevel_write, open: ctc_loglevel_open, release: ctc_loglevel_close, }; -static struct inode_operations ctc_stat_iops = { +static const struct inode_operations ctc_stat_iops = { #if LINUX_VERSION_CODE < 0x020363 default_file_ops: &ctc_stat_fops #endif }; -static struct inode_operations ctc_ctrl_iops = { +static const struct inode_operations ctc_ctrl_iops = { #if LINUX_VERSION_CODE < 0x020363 default_file_ops: &ctc_ctrl_fops #endif }; -static struct inode_operations ctc_loglevel_iops = { +static const struct inode_operations ctc_loglevel_iops = { #if LINUX_VERSION_CODE < 0x020363 default_file_ops: &ctc_loglevel_fops #endif diff -urNp linux-2.4.37.7/drivers/s390/net/netiucv.c linux-2.4.37.7/drivers/s390/net/netiucv.c --- linux-2.4.37.7/drivers/s390/net/netiucv.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/s390/net/netiucv.c 2009-11-10 19:30:27.000000000 -0500 @@ -1648,39 +1648,39 @@ netiucv_stat_read(struct file *file, cha return ret; } -static struct file_operations netiucv_stat_fops = { +static const struct file_operations netiucv_stat_fops = { read: netiucv_stat_read, write: netiucv_stat_write, open: netiucv_stat_open, release: netiucv_stat_close, }; -static struct file_operations netiucv_buffer_fops = { +static const struct file_operations netiucv_buffer_fops = { read: netiucv_buffer_read, write: netiucv_buffer_write, open: netiucv_buffer_open, release: netiucv_buffer_close, }; -static struct file_operations netiucv_user_fops = { +static const struct file_operations netiucv_user_fops = { read: netiucv_user_read, write: netiucv_user_write, open: netiucv_user_open, release: netiucv_user_close, }; -static struct inode_operations netiucv_stat_iops = { +static const struct inode_operations netiucv_stat_iops = { #if LINUX_VERSION_CODE < 0x020363 default_file_ops: &netiucv_stat_fops #endif }; -static struct inode_operations netiucv_buffer_iops = { +static const struct inode_operations netiucv_buffer_iops = { #if LINUX_VERSION_CODE < 0x020363 default_file_ops: &netiucv_buffer_fops #endif }; -static struct inode_operations netiucv_user_iops = { +static const struct inode_operations netiucv_user_iops = { #if LINUX_VERSION_CODE < 0x020363 default_file_ops: &netiucv_user_fops #endif diff -urNp linux-2.4.37.7/drivers/s390/net/qeth.c linux-2.4.37.7/drivers/s390/net/qeth.c --- linux-2.4.37.7/drivers/s390/net/qeth.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/s390/net/qeth.c 2009-11-10 19:30:27.000000000 -0500 @@ -10929,8 +10929,7 @@ static int qeth_procfile_ioctl(struct in return result; }; -static struct file_operations qeth_procfile_fops = -{ +static const struct file_operations qeth_procfile_fops = { ioctl:qeth_procfile_ioctl, read:qeth_procfile_read, write:qeth_procfile_write, @@ -10940,8 +10939,7 @@ static struct file_operations qeth_procf static struct proc_dir_entry *qeth_proc_file; -static struct file_operations qeth_ipato_procfile_fops = -{ +static const struct file_operations qeth_ipato_procfile_fops = { read:qeth_procfile_read, /* same as above! */ write:qeth_ipato_procfile_write, open:qeth_ipato_procfile_open, diff -urNp linux-2.4.37.7/drivers/s390/s390io.c linux-2.4.37.7/drivers/s390/s390io.c --- linux-2.4.37.7/drivers/s390/s390io.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/s390/s390io.c 2009-11-10 19:30:27.000000000 -0500 @@ -8350,7 +8350,7 @@ chan_subch_read (struct file *file, char } } -static struct file_operations chan_subch_file_ops = { +static const struct file_operations chan_subch_file_ops = { read:chan_subch_read, open:chan_subch_open, release:chan_subch_close, }; @@ -8597,17 +8597,17 @@ cio_chpid_entry_open (struct inode *inod return rc; } -static struct file_operations cio_sensedata_entry_file_ops = { +static const struct file_operations cio_sensedata_entry_file_ops = { read:cio_device_entry_read, open:cio_sensedata_entry_open, release:cio_device_entry_close, }; -static struct file_operations cio_in_use_entry_file_ops = { +static const struct file_operations cio_in_use_entry_file_ops = { read:cio_device_entry_read, open:cio_in_use_entry_open, release:cio_device_entry_close, }; -static struct file_operations cio_chpid_entry_file_ops = { +static const struct file_operations cio_chpid_entry_file_ops = { read:cio_device_entry_read, open:cio_chpid_entry_open, release:cio_device_entry_close, }; @@ -8926,7 +8926,7 @@ cio_ignore_proc_write (struct file *file return user_len; } -static struct file_operations cio_ignore_proc_file_ops = { +static const struct file_operations cio_ignore_proc_file_ops = { read:cio_ignore_proc_read, open:cio_ignore_proc_open, write:cio_ignore_proc_write, release:cio_ignore_proc_close, }; @@ -9019,7 +9019,7 @@ cio_irq_proc_read (struct file *file, ch } } -static struct file_operations cio_irq_proc_file_ops = { +static const struct file_operations cio_irq_proc_file_ops = { read:cio_irq_proc_read, open:cio_irq_proc_open, release:cio_irq_proc_close, }; @@ -9177,7 +9177,7 @@ cio_chpids_proc_write (struct file *file return user_len; } -static struct file_operations cio_chpids_proc_file_ops = +static const struct file_operations cio_chpids_proc_file_ops = { read:cio_chpids_proc_read, open:cio_chpids_proc_open, diff -urNp linux-2.4.37.7/drivers/sbus/audio/audio.c linux-2.4.37.7/drivers/sbus/audio/audio.c --- linux-2.4.37.7/drivers/sbus/audio/audio.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/audio/audio.c 2009-11-10 19:30:27.000000000 -0500 @@ -1701,7 +1701,7 @@ static int sparcaudio_ioctl(struct inode return retval; } -static struct file_operations sparcaudioctl_fops = { +static const struct file_operations sparcaudioctl_fops = { owner: THIS_MODULE, poll: sparcaudio_poll, ioctl: sparcaudio_ioctl, @@ -1893,7 +1893,7 @@ static int sparcaudio_release(struct ino return 0; } -static struct file_operations sparcaudio_fops = { +static const struct file_operations sparcaudio_fops = { owner: THIS_MODULE, llseek: no_llseek, read: sparcaudio_read, diff -urNp linux-2.4.37.7/drivers/sbus/char/bpp.c linux-2.4.37.7/drivers/sbus/char/bpp.c --- linux-2.4.37.7/drivers/sbus/char/bpp.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/char/bpp.c 2009-11-10 19:30:27.000000000 -0500 @@ -859,7 +859,7 @@ static int bpp_ioctl(struct inode *inode return errno; } -static struct file_operations bpp_fops = { +static const struct file_operations bpp_fops = { owner: THIS_MODULE, read: bpp_read, write: bpp_write, diff -urNp linux-2.4.37.7/drivers/sbus/char/cpwatchdog.c linux-2.4.37.7/drivers/sbus/char/cpwatchdog.c --- linux-2.4.37.7/drivers/sbus/char/cpwatchdog.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/char/cpwatchdog.c 2009-11-10 19:30:27.000000000 -0500 @@ -461,7 +461,7 @@ static void wd_interrupt(int irq, void * return; } -static struct file_operations wd_fops = { +static const struct file_operations wd_fops = { owner: THIS_MODULE, ioctl: wd_ioctl, open: wd_open, diff -urNp linux-2.4.37.7/drivers/sbus/char/display7seg.c linux-2.4.37.7/drivers/sbus/char/display7seg.c --- linux-2.4.37.7/drivers/sbus/char/display7seg.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/char/display7seg.c 2009-11-10 19:30:27.000000000 -0500 @@ -164,7 +164,7 @@ static int d7s_ioctl(struct inode *inode return 0; } -static struct file_operations d7s_fops = { +static const struct file_operations d7s_fops = { owner: THIS_MODULE, ioctl: d7s_ioctl, open: d7s_open, diff -urNp linux-2.4.37.7/drivers/sbus/char/envctrl.c linux-2.4.37.7/drivers/sbus/char/envctrl.c --- linux-2.4.37.7/drivers/sbus/char/envctrl.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/char/envctrl.c 2009-11-10 19:30:27.000000000 -0500 @@ -721,7 +721,7 @@ envctrl_release(struct inode *inode, str return 0; } -static struct file_operations envctrl_fops = { +static const struct file_operations envctrl_fops = { owner: THIS_MODULE, read: envctrl_read, ioctl: envctrl_ioctl, diff -urNp linux-2.4.37.7/drivers/sbus/char/flash.c linux-2.4.37.7/drivers/sbus/char/flash.c --- linux-2.4.37.7/drivers/sbus/char/flash.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/char/flash.c 2009-11-10 19:30:27.000000000 -0500 @@ -147,7 +147,7 @@ flash_release(struct inode *inode, struc return 0; } -static struct file_operations flash_fops = { +static const struct file_operations flash_fops = { /* no write to the Flash, use mmap * and play flash dependent tricks. */ diff -urNp linux-2.4.37.7/drivers/sbus/char/jsflash.c linux-2.4.37.7/drivers/sbus/char/jsflash.c --- linux-2.4.37.7/drivers/sbus/char/jsflash.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/char/jsflash.c 2009-11-10 19:30:27.000000000 -0500 @@ -533,7 +533,7 @@ static int jsfd_release(struct inode *in return 0; } -static struct file_operations jsf_fops = { +static const struct file_operations jsf_fops = { owner: THIS_MODULE, llseek: jsf_lseek, read: jsf_read, diff -urNp linux-2.4.37.7/drivers/sbus/char/openprom.c linux-2.4.37.7/drivers/sbus/char/openprom.c --- linux-2.4.37.7/drivers/sbus/char/openprom.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/char/openprom.c 2009-11-10 19:30:27.000000000 -0500 @@ -610,7 +610,7 @@ static int openprom_release(struct inode return 0; } -static struct file_operations openprom_fops = { +static const struct file_operations openprom_fops = { owner: THIS_MODULE, llseek: no_llseek, ioctl: openprom_ioctl, diff -urNp linux-2.4.37.7/drivers/sbus/char/pcikbd.c linux-2.4.37.7/drivers/sbus/char/pcikbd.c --- linux-2.4.37.7/drivers/sbus/char/pcikbd.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/char/pcikbd.c 2009-11-10 19:30:27.000000000 -0500 @@ -1183,7 +1183,7 @@ static unsigned int aux_poll(struct file return 0; } -struct file_operations psaux_fops = { +const struct file_operations psaux_fops = { owner: THIS_MODULE, read: aux_read, write: aux_write, @@ -1198,7 +1198,7 @@ static int aux_no_open(struct inode *ino return -ENODEV; } -struct file_operations psaux_no_fops = { +const struct file_operations psaux_no_fops = { owner: THIS_MODULE, open: aux_no_open, }; diff -urNp linux-2.4.37.7/drivers/sbus/char/riowatchdog.c linux-2.4.37.7/drivers/sbus/char/riowatchdog.c --- linux-2.4.37.7/drivers/sbus/char/riowatchdog.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/char/riowatchdog.c 2009-11-10 19:30:27.000000000 -0500 @@ -199,7 +199,7 @@ static ssize_t riowd_read(struct file *f return -EINVAL; } -static struct file_operations riowd_fops = { +static const struct file_operations riowd_fops = { owner: THIS_MODULE, ioctl: riowd_ioctl, open: riowd_open, diff -urNp linux-2.4.37.7/drivers/sbus/char/rtc.c linux-2.4.37.7/drivers/sbus/char/rtc.c --- linux-2.4.37.7/drivers/sbus/char/rtc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/char/rtc.c 2009-11-10 19:30:27.000000000 -0500 @@ -137,7 +137,7 @@ static int rtc_release(struct inode *ino return 0; } -static struct file_operations rtc_fops = { +static const struct file_operations rtc_fops = { owner: THIS_MODULE, llseek: no_llseek, ioctl: rtc_ioctl, diff -urNp linux-2.4.37.7/drivers/sbus/char/sunkbd.c linux-2.4.37.7/drivers/sbus/char/sunkbd.c --- linux-2.4.37.7/drivers/sbus/char/sunkbd.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/char/sunkbd.c 2009-11-10 19:30:27.000000000 -0500 @@ -1546,8 +1546,7 @@ kbd_close (struct inode *i, struct file return 0; } -static struct file_operations kbd_fops = -{ +static const struct file_operations kbd_fops = { read: kbd_read, poll: kbd_poll, ioctl: kbd_ioctl, diff -urNp linux-2.4.37.7/drivers/sbus/char/sunmouse.c linux-2.4.37.7/drivers/sbus/char/sunmouse.c --- linux-2.4.37.7/drivers/sbus/char/sunmouse.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/char/sunmouse.c 2009-11-10 19:30:27.000000000 -0500 @@ -586,7 +586,7 @@ sun_mouse_ioctl (struct inode *inode, st return 0; } -struct file_operations sun_mouse_fops = { +const struct file_operations sun_mouse_fops = { read: sun_mouse_read, write: sun_mouse_write, poll: sun_mouse_poll, diff -urNp linux-2.4.37.7/drivers/sbus/char/uctrl.c linux-2.4.37.7/drivers/sbus/char/uctrl.c --- linux-2.4.37.7/drivers/sbus/char/uctrl.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/char/uctrl.c 2009-11-10 19:30:27.000000000 -0500 @@ -223,7 +223,7 @@ void uctrl_interrupt(int irq, void *dev_ printk("in uctrl_interrupt\n"); } -static struct file_operations uctrl_fops = { +static const struct file_operations uctrl_fops = { owner: THIS_MODULE, llseek: no_llseek, ioctl: uctrl_ioctl, diff -urNp linux-2.4.37.7/drivers/sbus/char/vfc_dev.c linux-2.4.37.7/drivers/sbus/char/vfc_dev.c --- linux-2.4.37.7/drivers/sbus/char/vfc_dev.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sbus/char/vfc_dev.c 2009-11-10 19:30:27.000000000 -0500 @@ -43,7 +43,7 @@ #include "vfc.h" #include -static struct file_operations vfc_fops; +static const struct file_operations vfc_fops; static devfs_handle_t devfs_handle; /* For the directory */ struct vfc_dev **vfc_dev_lst; static char vfcstr[]="vfc"; @@ -642,7 +642,7 @@ static int vfc_mmap(struct inode *inode, } -static struct file_operations vfc_fops = { +static const struct file_operations vfc_fops = { owner: THIS_MODULE, llseek: no_llseek, ioctl: vfc_ioctl, diff -urNp linux-2.4.37.7/drivers/scsi/3w-xxxx.c linux-2.4.37.7/drivers/scsi/3w-xxxx.c --- linux-2.4.37.7/drivers/scsi/3w-xxxx.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/scsi/3w-xxxx.c 2009-11-10 19:30:27.000000000 -0500 @@ -234,7 +234,7 @@ static struct notifier_block tw_notifier }; /* File operations struct for character device */ -static struct file_operations tw_fops = { +static const struct file_operations tw_fops = { owner: THIS_MODULE, ioctl: tw_chrdev_ioctl, open: tw_chrdev_open, diff -urNp linux-2.4.37.7/drivers/scsi/aacraid/linit.c linux-2.4.37.7/drivers/scsi/aacraid/linit.c --- linux-2.4.37.7/drivers/scsi/aacraid/linit.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/scsi/aacraid/linit.c 2009-11-10 19:30:27.000000000 -0500 @@ -122,7 +122,7 @@ static int aac_cfg_ioctl(struct inode * static int aac_cfg_open(struct inode * inode, struct file * file); static int aac_cfg_release(struct inode * inode,struct file * file); -static struct file_operations aac_cfg_fops = { +static const struct file_operations aac_cfg_fops = { owner: THIS_MODULE, ioctl: aac_cfg_ioctl, open: aac_cfg_open, diff -urNp linux-2.4.37.7/drivers/scsi/dpt_i2o.c linux-2.4.37.7/drivers/scsi/dpt_i2o.c --- linux-2.4.37.7/drivers/scsi/dpt_i2o.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/scsi/dpt_i2o.c 2009-11-10 19:30:27.000000000 -0500 @@ -110,7 +110,7 @@ static adpt_hba* hbas[DPTI_MAX_HBA]; static adpt_hba* hba_chain = NULL; static int hba_count = 0; -static struct file_operations adpt_fops = { +static const struct file_operations adpt_fops = { ioctl: adpt_ioctl, open: adpt_open, release: adpt_close diff -urNp linux-2.4.37.7/drivers/scsi/gdth.c linux-2.4.37.7/drivers/scsi/gdth.c --- linux-2.4.37.7/drivers/scsi/gdth.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/scsi/gdth.c 2009-11-10 19:30:27.000000000 -0500 @@ -698,7 +698,7 @@ MODULE_LICENSE("GPL"); #endif /* ioctl interface */ -static struct file_operations gdth_fops = { +static const struct file_operations gdth_fops = { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) .ioctl = gdth_ioctl, .open = gdth_open, diff -urNp linux-2.4.37.7/drivers/scsi/libata-scsi.c linux-2.4.37.7/drivers/scsi/libata-scsi.c --- linux-2.4.37.7/drivers/scsi/libata-scsi.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/scsi/libata-scsi.c 2009-11-10 19:30:27.000000000 -0500 @@ -1497,7 +1497,7 @@ unsigned int ata_scsiop_inq_80(struct at return 0; } -static const char *inq_83_str = "Linux ATA-SCSI simulator"; +static const char inq_83_str[] = "Linux ATA-SCSI simulator"; /** * ata_scsiop_inq_83 - Simulate INQUIRY EVPD page 83, device identity @@ -1516,13 +1516,13 @@ unsigned int ata_scsiop_inq_83(struct at unsigned int buflen) { rbuf[1] = 0x83; /* this page code */ - rbuf[3] = 4 + strlen(inq_83_str); /* page len */ + rbuf[3] = 3 + sizeof(inq_83_str); /* page len */ /* our one and only identification descriptor (vendor-specific) */ - if (buflen > (strlen(inq_83_str) + 4 + 4 - 1)) { + if (buflen >= (sizeof(inq_83_str) + 4 + 4 - 1)) { rbuf[4 + 0] = 2; /* code set: ASCII */ - rbuf[4 + 3] = strlen(inq_83_str); - memcpy(rbuf + 4 + 4, inq_83_str, strlen(inq_83_str)); + rbuf[4 + 3] = sizeof(inq_83_str)-1; + memcpy(rbuf + 4 + 4, inq_83_str, sizeof(inq_83_str)-1); } return 0; diff -urNp linux-2.4.37.7/drivers/scsi/megaraid2.c linux-2.4.37.7/drivers/scsi/megaraid2.c --- linux-2.4.37.7/drivers/scsi/megaraid2.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/scsi/megaraid2.c 2009-11-10 19:30:27.000000000 -0500 @@ -97,7 +97,7 @@ static struct semaphore megaraid_ioc_mtx /* * The File Operations structure for the serial/ioctl interface of the driver */ -static struct file_operations megadev_fops = { +static const struct file_operations megadev_fops = { .ioctl = megadev_ioctl_entry, .open = megadev_open, .release = megadev_close, diff -urNp linux-2.4.37.7/drivers/scsi/megaraid.c linux-2.4.37.7/drivers/scsi/megaraid.c --- linux-2.4.37.7/drivers/scsi/megaraid.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/scsi/megaraid.c 2009-11-10 19:30:27.000000000 -0500 @@ -873,7 +873,7 @@ struct mega_hbas mega_hbas[MAX_CONTROLLE */ /* For controller re-ordering */ -static struct file_operations megadev_fops = { +static const struct file_operations megadev_fops = { ioctl:megadev_ioctl_entry, open:megadev_open, release:megadev_close, diff -urNp linux-2.4.37.7/drivers/scsi/osst.c linux-2.4.37.7/drivers/scsi/osst.c --- linux-2.4.37.7/drivers/scsi/osst.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/scsi/osst.c 2009-11-10 19:30:27.000000000 -0500 @@ -5501,7 +5501,7 @@ __setup("osst=", osst_setup); #endif -static struct file_operations osst_fops = { +static const struct file_operations osst_fops = { read: osst_read, write: osst_write, ioctl: osst_ioctl, diff -urNp linux-2.4.37.7/drivers/scsi/sg.c linux-2.4.37.7/drivers/scsi/sg.c --- linux-2.4.37.7/drivers/scsi/sg.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/scsi/sg.c 2009-11-10 19:30:27.000000000 -0500 @@ -1149,7 +1149,7 @@ static struct page * sg_vma_nopage(struc return page; } -static struct vm_operations_struct sg_mmap_vm_ops = { +static const struct vm_operations_struct sg_mmap_vm_ops = { nopage : sg_vma_nopage, }; @@ -1321,7 +1321,7 @@ static void sg_cmd_done_bh(Scsi_Cmnd * S } } -static struct file_operations sg_fops = { +static const struct file_operations sg_fops = { owner: THIS_MODULE, read: sg_read, write: sg_write, diff -urNp linux-2.4.37.7/drivers/scsi/st.c linux-2.4.37.7/drivers/scsi/st.c --- linux-2.4.37.7/drivers/scsi/st.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/scsi/st.c 2009-11-10 19:30:27.000000000 -0500 @@ -3772,8 +3772,7 @@ __setup("st=", st_setup); #endif -static struct file_operations st_fops = -{ +static const struct file_operations st_fops = { owner: THIS_MODULE, read: st_read, write: st_write, diff -urNp linux-2.4.37.7/drivers/sound/ac97_plugin_wm97xx.c linux-2.4.37.7/drivers/sound/ac97_plugin_wm97xx.c --- linux-2.4.37.7/drivers/sound/ac97_plugin_wm97xx.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/ac97_plugin_wm97xx.c 2009-11-10 19:30:27.000000000 -0500 @@ -789,7 +789,7 @@ static int wm97xx_release(struct inode * return 0; } -static struct file_operations ts_fops = { +static const struct file_operations ts_fops = { owner: THIS_MODULE, read: wm97xx_read, poll: wm97xx_poll, diff -urNp linux-2.4.37.7/drivers/sound/ad1889.c linux-2.4.37.7/drivers/sound/ad1889.c --- linux-2.4.37.7/drivers/sound/ad1889.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/ad1889.c 2009-11-10 19:30:27.000000000 -0500 @@ -776,7 +776,7 @@ static int ad1889_release(struct inode * return 0; } -static struct file_operations ad1889_fops = { +static const struct file_operations ad1889_fops = { llseek: no_llseek, read: ad1889_read, write: ad1889_write, @@ -811,7 +811,7 @@ static int ad1889_mixer_ioctl(struct ino return codec->mixer_ioctl(codec, cmd, arg); } -static struct file_operations ad1889_mixer_fops = { +static const struct file_operations ad1889_mixer_fops = { llseek: no_llseek, ioctl: ad1889_mixer_ioctl, open: ad1889_mixer_open, diff -urNp linux-2.4.37.7/drivers/sound/btaudio.c linux-2.4.37.7/drivers/sound/btaudio.c --- linux-2.4.37.7/drivers/sound/btaudio.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/btaudio.c 2009-11-10 19:30:27.000000000 -0500 @@ -425,7 +425,7 @@ static int btaudio_mixer_ioctl(struct in return 0; } -static struct file_operations btaudio_mixer_fops = { +static const struct file_operations btaudio_mixer_fops = { owner: THIS_MODULE, llseek: no_llseek, open: btaudio_mixer_open, @@ -790,7 +790,7 @@ static unsigned int btaudio_dsp_poll(str return mask; } -static struct file_operations btaudio_digital_dsp_fops = { +static const struct file_operations btaudio_digital_dsp_fops = { owner: THIS_MODULE, llseek: no_llseek, open: btaudio_dsp_open_digital, @@ -801,7 +801,7 @@ static struct file_operations btaudio_di poll: btaudio_dsp_poll, }; -static struct file_operations btaudio_analog_dsp_fops = { +static const struct file_operations btaudio_analog_dsp_fops = { owner: THIS_MODULE, llseek: no_llseek, open: btaudio_dsp_open_analog, diff -urNp linux-2.4.37.7/drivers/sound/dmasound/dmasound_core.c linux-2.4.37.7/drivers/sound/dmasound/dmasound_core.c --- linux-2.4.37.7/drivers/sound/dmasound/dmasound_core.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/dmasound/dmasound_core.c 2009-11-10 19:30:27.000000000 -0500 @@ -365,7 +365,7 @@ static int mixer_ioctl(struct inode *ino return -EINVAL; } -static struct file_operations mixer_fops = +static const struct file_operations mixer_fops = { owner: THIS_MODULE, llseek: no_llseek, @@ -1325,7 +1325,7 @@ static int sq_ioctl(struct inode *inode, return -EINVAL; } -static struct file_operations sq_fops = +static const struct file_operations sq_fops = { owner: THIS_MODULE, llseek: no_llseek, @@ -1548,7 +1548,7 @@ static ssize_t state_read(struct file *f return n; } -static struct file_operations state_fops = { +static const struct file_operations state_fops = { owner: THIS_MODULE, llseek: no_llseek, read: state_read, diff -urNp linux-2.4.37.7/drivers/sound/emu10k1/audio.c linux-2.4.37.7/drivers/sound/emu10k1/audio.c --- linux-2.4.37.7/drivers/sound/emu10k1/audio.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/emu10k1/audio.c 2009-11-10 19:30:27.000000000 -0500 @@ -1020,7 +1020,7 @@ static struct page *emu10k1_mm_nopage (s return dmapage; } -struct vm_operations_struct emu10k1_mm_ops = { +const struct vm_operations_struct emu10k1_mm_ops = { nopage: emu10k1_mm_nopage, }; @@ -1558,7 +1558,7 @@ void emu10k1_waveout_bh(unsigned long re return; } -struct file_operations emu10k1_audio_fops = { +const struct file_operations emu10k1_audio_fops = { owner: THIS_MODULE, llseek: no_llseek, read: emu10k1_audio_read, diff -urNp linux-2.4.37.7/drivers/sound/emu10k1/midi.c linux-2.4.37.7/drivers/sound/emu10k1/midi.c --- linux-2.4.37.7/drivers/sound/emu10k1/midi.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/emu10k1/midi.c 2009-11-10 19:30:27.000000000 -0500 @@ -465,7 +465,7 @@ int emu10k1_midi_callback(unsigned long } /* MIDI file operations */ -struct file_operations emu10k1_midi_fops = { +const struct file_operations emu10k1_midi_fops = { owner: THIS_MODULE, read: emu10k1_midi_read, write: emu10k1_midi_write, diff -urNp linux-2.4.37.7/drivers/sound/emu10k1/mixer.c linux-2.4.37.7/drivers/sound/emu10k1/mixer.c --- linux-2.4.37.7/drivers/sound/emu10k1/mixer.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/emu10k1/mixer.c 2009-11-10 19:30:27.000000000 -0500 @@ -675,7 +675,7 @@ static int emu10k1_mixer_release(struct return 0; } -struct file_operations emu10k1_mixer_fops = { +const struct file_operations emu10k1_mixer_fops = { owner: THIS_MODULE, llseek: no_llseek, ioctl: emu10k1_mixer_ioctl, diff -urNp linux-2.4.37.7/drivers/sound/forte.c linux-2.4.37.7/drivers/sound/forte.c --- linux-2.4.37.7/drivers/sound/forte.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/forte.c 2009-11-10 19:30:27.000000000 -0500 @@ -365,7 +365,7 @@ forte_mixer_ioctl (struct inode *inode, } -static struct file_operations forte_mixer_fops = { +static const struct file_operations forte_mixer_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .ioctl = forte_mixer_ioctl, @@ -1667,7 +1667,7 @@ forte_dsp_read (struct file *file, char } -static struct file_operations forte_dsp_fops = { +static const struct file_operations forte_dsp_fops = { .owner = THIS_MODULE, .llseek = &no_llseek, .read = &forte_dsp_read, diff -urNp linux-2.4.37.7/drivers/sound/hal2.c linux-2.4.37.7/drivers/sound/hal2.c --- linux-2.4.37.7/drivers/sound/hal2.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/hal2.c 2009-11-10 19:30:27.000000000 -0500 @@ -1372,7 +1372,7 @@ static int hal2_release(struct inode *in return 0; } -static struct file_operations hal2_audio_fops = { +static const struct file_operations hal2_audio_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = hal2_read, @@ -1383,7 +1383,7 @@ static struct file_operations hal2_audio .release = hal2_release, }; -static struct file_operations hal2_mixer_fops = { +static const struct file_operations hal2_mixer_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .ioctl = hal2_ioctl_mixdev, diff -urNp linux-2.4.37.7/drivers/sound/harmony.c linux-2.4.37.7/drivers/sound/harmony.c --- linux-2.4.37.7/drivers/sound/harmony.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/harmony.c 2009-11-10 19:30:27.000000000 -0500 @@ -809,7 +809,7 @@ static void harmony_interrupt(int irq, v * Sound playing functions */ -static struct file_operations harmony_audio_fops = { +static const struct file_operations harmony_audio_fops = { owner: THIS_MODULE, llseek: no_llseek, read: harmony_audio_read, @@ -1131,7 +1131,7 @@ static int harmony_mixer_release(struct return 0; } -static struct file_operations harmony_mixer_fops = { +static const struct file_operations harmony_mixer_fops = { owner: THIS_MODULE, llseek: no_llseek, open: harmony_mixer_open, diff -urNp linux-2.4.37.7/drivers/sound/maestro3.c linux-2.4.37.7/drivers/sound/maestro3.c --- linux-2.4.37.7/drivers/sound/maestro3.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/maestro3.c 2009-11-10 19:30:27.000000000 -0500 @@ -2176,7 +2176,7 @@ static int m3_ioctl_mixdev(struct inode return codec->mixer_ioctl(codec, cmd, arg); } -static struct file_operations m3_mixer_fops = { +static const struct file_operations m3_mixer_fops = { llseek: no_llseek, ioctl: m3_ioctl_mixdev, open: m3_open_mixdev, @@ -2554,7 +2554,7 @@ static void m3_enable_ints(struct m3_car io + ASSP_CONTROL_C); } -static struct file_operations m3_audio_fops = { +static const struct file_operations m3_audio_fops = { llseek: &no_llseek, read: &m3_read, write: &m3_write, diff -urNp linux-2.4.37.7/drivers/sound/maestro.c linux-2.4.37.7/drivers/sound/maestro.c --- linux-2.4.37.7/drivers/sound/maestro.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/maestro.c 2009-11-10 19:30:27.000000000 -0500 @@ -3097,7 +3097,7 @@ ess_release(struct inode *inode, struct return 0; } -static struct file_operations ess_audio_fops = { +static const struct file_operations ess_audio_fops = { owner: THIS_MODULE, llseek: no_llseek, read: ess_read, diff -urNp linux-2.4.37.7/drivers/sound/msnd_pinnacle.c linux-2.4.37.7/drivers/sound/msnd_pinnacle.c --- linux-2.4.37.7/drivers/sound/msnd_pinnacle.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/msnd_pinnacle.c 2009-11-10 19:30:27.000000000 -0500 @@ -1100,7 +1100,7 @@ static void intr(int irq, void *dev_id, } } -static struct file_operations dev_fileops = { +static const struct file_operations dev_fileops = { owner: THIS_MODULE, read: dev_read, write: dev_write, diff -urNp linux-2.4.37.7/drivers/sound/rme96xx.c linux-2.4.37.7/drivers/sound/rme96xx.c --- linux-2.4.37.7/drivers/sound/rme96xx.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/rme96xx.c 2009-11-10 19:30:27.000000000 -0500 @@ -254,8 +254,8 @@ static const char invalid_magic[] = KERN /* --------------------------------------------------------------------- */ -static struct file_operations rme96xx_audio_fops; -static struct file_operations rme96xx_mixer_fops; +static const struct file_operations rme96xx_audio_fops; +static const struct file_operations rme96xx_mixer_fops; static int numcards; typedef int32_t raw_sample_t; @@ -1736,7 +1736,7 @@ static unsigned int rme96xx_poll(struct } -static struct file_operations rme96xx_audio_fops = { +static const struct file_operations rme96xx_audio_fops = { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) owner: THIS_MODULE, #endif diff -urNp linux-2.4.37.7/drivers/sound/soundcard.c linux-2.4.37.7/drivers/sound/soundcard.c --- linux-2.4.37.7/drivers/sound/soundcard.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/soundcard.c 2009-11-10 19:30:27.000000000 -0500 @@ -493,7 +493,7 @@ static int sound_mmap(struct file *file, return 0; } -struct file_operations oss_sound_fops = { +const struct file_operations oss_sound_fops = { owner: THIS_MODULE, llseek: no_llseek, read: sound_read, diff -urNp linux-2.4.37.7/drivers/sound/sound_core.c linux-2.4.37.7/drivers/sound/sound_core.c --- linux-2.4.37.7/drivers/sound/sound_core.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/sound_core.c 2009-11-10 19:30:27.000000000 -0500 @@ -52,7 +52,7 @@ struct sound_unit { int unit_minor; - struct file_operations *unit_fops; + const struct file_operations *unit_fops; struct sound_unit *next; devfs_handle_t de; }; @@ -69,7 +69,7 @@ extern int msnd_pinnacle_init(void); * join into it. Called with the lock asserted */ -static int __sound_insert_unit(struct sound_unit * s, struct sound_unit **list, struct file_operations *fops, int index, int low, int top) +static int __sound_insert_unit(struct sound_unit * s, struct sound_unit **list, const struct file_operations *fops, int index, int low, int top) { int n=low; @@ -154,7 +154,7 @@ static spinlock_t sound_loader_lock = SP static devfs_handle_t devfs_handle; -static int sound_insert_unit(struct sound_unit **list, struct file_operations *fops, int index, int low, int top, const char *name, umode_t mode) +static int sound_insert_unit(struct sound_unit **list, const struct file_operations *fops, int index, int low, int top, const char *name, umode_t mode) { int r; struct sound_unit *s=(struct sound_unit *)kmalloc(sizeof(struct sound_unit), GFP_KERNEL); @@ -229,7 +229,7 @@ static struct sound_unit *chains[16]; * a negative error code is returned. */ -int register_sound_special(struct file_operations *fops, int unit) +int register_sound_special(const struct file_operations *fops, int unit) { char *name; @@ -299,7 +299,7 @@ EXPORT_SYMBOL(register_sound_special); * number is returned, on failure a negative error code is returned. */ -int register_sound_mixer(struct file_operations *fops, int dev) +int register_sound_mixer(const struct file_operations *fops, int dev) { return sound_insert_unit(&chains[0], fops, dev, 0, 128, "mixer", S_IRUSR | S_IWUSR); @@ -317,7 +317,7 @@ EXPORT_SYMBOL(register_sound_mixer); * number is returned, on failure a negative error code is returned. */ -int register_sound_midi(struct file_operations *fops, int dev) +int register_sound_midi(const struct file_operations *fops, int dev) { return sound_insert_unit(&chains[2], fops, dev, 2, 130, "midi", S_IRUSR | S_IWUSR); @@ -343,7 +343,7 @@ EXPORT_SYMBOL(register_sound_midi); * and will always allocate them as a matching pair - eg dsp3/audio3 */ -int register_sound_dsp(struct file_operations *fops, int dev) +int register_sound_dsp(const struct file_operations *fops, int dev) { return sound_insert_unit(&chains[3], fops, dev, 3, 131, "dsp", S_IWUSR | S_IRUSR); @@ -362,7 +362,7 @@ EXPORT_SYMBOL(register_sound_dsp); */ -int register_sound_synth(struct file_operations *fops, int dev) +int register_sound_synth(const struct file_operations *fops, int dev) { return sound_insert_unit(&chains[9], fops, dev, 9, 137, "synth", S_IRUSR | S_IWUSR); @@ -456,8 +456,7 @@ EXPORT_SYMBOL(unregister_sound_synth); static int soundcore_open(struct inode *, struct file *); -static struct file_operations soundcore_fops= -{ +static const struct file_operations soundcore_fops = { /* We must have an owner or the module locking fails */ owner: THIS_MODULE, open: soundcore_open, @@ -482,7 +481,7 @@ int soundcore_open(struct inode *inode, int chain; int unit=MINOR(inode->i_rdev); struct sound_unit *s; - struct file_operations *new_fops = NULL; + const struct file_operations *new_fops = NULL; chain=unit&0x0F; if(chain==4 || chain==5) /* dsp/audio/dsp16 */ @@ -525,7 +524,7 @@ int soundcore_open(struct inode *inode, * switching ->f_op in the first place. */ int err = 0; - struct file_operations *old_fops = file->f_op; + const struct file_operations *old_fops = file->f_op; file->f_op = new_fops; spin_unlock(&sound_loader_lock); if(file->f_op->open) diff -urNp linux-2.4.37.7/drivers/sound/via82cxxx_audio.c linux-2.4.37.7/drivers/sound/via82cxxx_audio.c --- linux-2.4.37.7/drivers/sound/via82cxxx_audio.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/via82cxxx_audio.c 2009-11-10 19:30:27.000000000 -0500 @@ -1629,7 +1629,7 @@ out: } -static struct file_operations via_mixer_fops = { +static const struct file_operations via_mixer_fops = { owner: THIS_MODULE, open: via_mixer_open, llseek: no_llseek, @@ -2048,7 +2048,7 @@ static int via_interrupt_init (struct vi * */ -static struct file_operations via_dsp_fops = { +static const struct file_operations via_dsp_fops = { owner: THIS_MODULE, open: via_dsp_open, release: via_dsp_release, @@ -2168,7 +2168,7 @@ static int via_mm_swapout (struct page * #endif /* VM_RESERVED */ -struct vm_operations_struct via_mm_ops = { +const struct vm_operations_struct via_mm_ops = { nopage: via_mm_nopage, #ifndef VM_RESERVED diff -urNp linux-2.4.37.7/drivers/sound/vwsnd.c linux-2.4.37.7/drivers/sound/vwsnd.c --- linux-2.4.37.7/drivers/sound/vwsnd.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/sound/vwsnd.c 2009-11-10 19:30:27.000000000 -0500 @@ -3029,7 +3029,7 @@ static int vwsnd_audio_release(struct in return err; } -static struct file_operations vwsnd_audio_fops = { +static const struct file_operations vwsnd_audio_fops = { owner: THIS_MODULE, llseek: no_llseek, read: vwsnd_audio_read, @@ -3219,7 +3219,7 @@ static int vwsnd_mixer_ioctl(struct inod return retval; } -static struct file_operations vwsnd_mixer_fops = { +static const struct file_operations vwsnd_mixer_fops = { owner: THIS_MODULE, llseek: no_llseek, ioctl: vwsnd_mixer_ioctl, diff -urNp linux-2.4.37.7/drivers/telephony/ixj.c linux-2.4.37.7/drivers/telephony/ixj.c --- linux-2.4.37.7/drivers/telephony/ixj.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/telephony/ixj.c 2009-11-10 19:30:27.000000000 -0500 @@ -6767,8 +6767,7 @@ static int ixj_fasync(int fd, struct fil return fasync_helper(fd, file_p, mode, &j->async_queue); } -struct file_operations ixj_fops = -{ +const struct file_operations ixj_fops = { owner: THIS_MODULE, read: ixj_enhanced_read, write: ixj_enhanced_write, diff -urNp linux-2.4.37.7/drivers/telephony/phonedev.c linux-2.4.37.7/drivers/telephony/phonedev.c --- linux-2.4.37.7/drivers/telephony/phonedev.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/telephony/phonedev.c 2009-11-10 19:30:27.000000000 -0500 @@ -49,7 +49,7 @@ static int phone_open(struct inode *inod unsigned int minor = MINOR(inode->i_rdev); int err = 0; struct phone_device *p; - struct file_operations *old_fops, *new_fops = NULL; + const struct file_operations *old_fops, *new_fops = NULL; if (minor >= PHONE_NUM_DEVICES) return -ENODEV; @@ -133,8 +133,7 @@ void phone_unregister_device(struct phon } -static struct file_operations phone_fops = -{ +static const struct file_operations phone_fops = { owner: THIS_MODULE, open: phone_open, }; diff -urNp linux-2.4.37.7/drivers/usb/auermain.c linux-2.4.37.7/drivers/usb/auermain.c --- linux-2.4.37.7/drivers/usb/auermain.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/auermain.c 2009-11-10 19:30:27.000000000 -0500 @@ -547,7 +547,7 @@ void auerswald_removeservice(struct auer /*----------------------------------------------------------------------*/ /* File operation structure */ -static struct file_operations auerswald_fops = { +static const struct file_operations auerswald_fops = { owner:THIS_MODULE, llseek:auerchar_llseek, read:auerchar_read, diff -urNp linux-2.4.37.7/drivers/usb/brlvger.c linux-2.4.37.7/drivers/usb/brlvger.c --- linux-2.4.37.7/drivers/usb/brlvger.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/brlvger.c 2009-11-10 19:30:27.000000000 -0500 @@ -228,8 +228,7 @@ static struct usb_device_id brlvger_ids }; MODULE_DEVICE_TABLE (usb, brlvger_ids); -static struct file_operations brlvger_fops = -{ +static const struct file_operations brlvger_fops = { owner: THIS_MODULE, llseek: brlvger_llseek, read: brlvger_read, diff -urNp linux-2.4.37.7/drivers/usb/dabusb.c linux-2.4.37.7/drivers/usb/dabusb.c --- linux-2.4.37.7/drivers/usb/dabusb.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/dabusb.c 2009-11-10 19:30:27.000000000 -0500 @@ -698,8 +698,7 @@ static int dabusb_ioctl (struct inode *i return ret; } -static struct file_operations dabusb_fops = -{ +static const struct file_operations dabusb_fops = { owner: THIS_MODULE, llseek: no_llseek, read: dabusb_read, diff -urNp linux-2.4.37.7/drivers/usb/devices.c linux-2.4.37.7/drivers/usb/devices.c --- linux-2.4.37.7/drivers/usb/devices.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/devices.c 2009-11-10 19:30:27.000000000 -0500 @@ -664,7 +664,7 @@ static loff_t usb_device_lseek(struct fi } } -struct file_operations usbdevfs_devices_fops = { +const struct file_operations usbdevfs_devices_fops = { llseek: usb_device_lseek, read: usb_device_read, poll: usb_device_poll, diff -urNp linux-2.4.37.7/drivers/usb/devio.c linux-2.4.37.7/drivers/usb/devio.c --- linux-2.4.37.7/drivers/usb/devio.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/devio.c 2009-11-10 19:30:27.000000000 -0500 @@ -1310,7 +1310,7 @@ static unsigned int usbdev_poll(struct f return mask; } -struct file_operations usbdevfs_device_file_operations = { +const struct file_operations usbdevfs_device_file_operations = { llseek: usbdev_lseek, read: usbdev_read, poll: usbdev_poll, diff -urNp linux-2.4.37.7/drivers/usb/drivers.c linux-2.4.37.7/drivers/usb/drivers.c --- linux-2.4.37.7/drivers/usb/drivers.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/drivers.c 2009-11-10 19:30:27.000000000 -0500 @@ -113,7 +113,7 @@ static loff_t usb_driver_lseek(struct fi } } -struct file_operations usbdevfs_drivers_fops = { +const struct file_operations usbdevfs_drivers_fops = { llseek: usb_driver_lseek, read: usb_driver_read, }; diff -urNp linux-2.4.37.7/drivers/usb/hiddev.c linux-2.4.37.7/drivers/usb/hiddev.c --- linux-2.4.37.7/drivers/usb/hiddev.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/hiddev.c 2009-11-10 19:30:27.000000000 -0500 @@ -686,7 +686,7 @@ static int hiddev_ioctl(struct inode *in return -EINVAL; } -static struct file_operations hiddev_fops = { +static const struct file_operations hiddev_fops = { owner: THIS_MODULE, read: hiddev_read, write: hiddev_write, diff -urNp linux-2.4.37.7/drivers/usb/host/uhci-debug.h linux-2.4.37.7/drivers/usb/host/uhci-debug.h --- linux-2.4.37.7/drivers/usb/host/uhci-debug.h 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/host/uhci-debug.h 2009-11-10 19:30:27.000000000 -0500 @@ -561,7 +561,7 @@ static int uhci_proc_release(struct inod return 0; } -static struct file_operations uhci_proc_operations = { +static const struct file_operations uhci_proc_operations = { open: uhci_proc_open, llseek: uhci_proc_lseek, read: uhci_proc_read, diff -urNp linux-2.4.37.7/drivers/usb/inode.c linux-2.4.37.7/drivers/usb/inode.c --- linux-2.4.37.7/drivers/usb/inode.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/inode.c 2009-11-10 19:30:27.000000000 -0500 @@ -41,8 +41,8 @@ #include #include -static struct inode_operations usbdevfs_bus_inode_operations; -static struct file_operations usbdevfs_bus_file_operations; +static const struct inode_operations usbdevfs_bus_inode_operations; +static const struct file_operations usbdevfs_bus_file_operations; /* --------------------------------------------------------------------- */ @@ -55,7 +55,7 @@ static LIST_HEAD(superlist); struct special { const char *name; - struct file_operations *fops; + const struct file_operations *fops; struct inode *inode; struct list_head inodes; }; @@ -313,7 +313,7 @@ static int usbdevfs_revalidate(struct de return 1; } -static struct dentry_operations usbdevfs_dentry_operations = { +static const struct dentry_operations usbdevfs_dentry_operations = { d_revalidate: usbdevfs_revalidate, }; @@ -490,19 +490,19 @@ static int usbdevfs_bus_readdir(struct f } } -static struct file_operations usbdevfs_root_file_operations = { +static const struct file_operations usbdevfs_root_file_operations = { readdir: usbdevfs_root_readdir, }; -static struct inode_operations usbdevfs_root_inode_operations = { +static const struct inode_operations usbdevfs_root_inode_operations = { lookup: usbdevfs_root_lookup, }; -static struct file_operations usbdevfs_bus_file_operations = { +static const struct file_operations usbdevfs_bus_file_operations = { readdir: usbdevfs_bus_readdir, }; -static struct inode_operations usbdevfs_bus_inode_operations = { +static const struct inode_operations usbdevfs_bus_inode_operations = { lookup: usbdevfs_bus_lookup, }; @@ -595,7 +595,7 @@ static int usbdevfs_remount(struct super return 0; } -static struct super_operations usbdevfs_sops = { +static const struct super_operations usbdevfs_sops = { read_inode: usbdevfs_read_inode, put_super: usbdevfs_put_super, statfs: usbdevfs_statfs, diff -urNp linux-2.4.37.7/drivers/usb/mdc800.c linux-2.4.37.7/drivers/usb/mdc800.c --- linux-2.4.37.7/drivers/usb/mdc800.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/mdc800.c 2009-11-10 19:30:27.000000000 -0500 @@ -916,8 +916,7 @@ static ssize_t mdc800_device_write (stru ****************************************************************************/ /* File Operations of this drivers */ -static struct file_operations mdc800_device_ops = -{ +static const struct file_operations mdc800_device_ops = { owner: THIS_MODULE, read: mdc800_device_read, write: mdc800_device_write, diff -urNp linux-2.4.37.7/drivers/usb/ov511.c linux-2.4.37.7/drivers/usb/ov511.c --- linux-2.4.37.7/drivers/usb/ov511.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/ov511.c 2009-11-10 19:30:27.000000000 -0500 @@ -410,7 +410,7 @@ rvfree(void *mem, unsigned long size) static struct proc_dir_entry *ov511_proc_entry = NULL; extern struct proc_dir_entry *video_proc_entry; -static struct file_operations ov511_control_fops = { +static const struct file_operations ov511_control_fops = { .ioctl = ov51x_control_ioctl, }; @@ -5284,7 +5284,7 @@ ov51x_v4l1_mmap(struct file *file, struc return 0; } -static struct file_operations ov511_fops = { +static const struct file_operations ov511_fops = { .owner = THIS_MODULE, .open = ov51x_v4l1_open, .release = ov51x_v4l1_close, diff -urNp linux-2.4.37.7/drivers/usb/printer.c linux-2.4.37.7/drivers/usb/printer.c --- linux-2.4.37.7/drivers/usb/printer.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/printer.c 2009-11-10 19:30:27.000000000 -0500 @@ -818,7 +818,7 @@ static unsigned int usblp_quirks (__u16 return 0; } -static struct file_operations usblp_fops = { +static const struct file_operations usblp_fops = { owner: THIS_MODULE, read: usblp_read, write: usblp_write, diff -urNp linux-2.4.37.7/drivers/usb/rio500.c linux-2.4.37.7/drivers/usb/rio500.c --- linux-2.4.37.7/drivers/usb/rio500.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/rio500.c 2009-11-10 19:30:27.000000000 -0500 @@ -436,8 +436,7 @@ read_rio(struct file *file, char *buffer return read_count; } -static struct -file_operations usb_rio_fops = { +static const struct file_operations usb_rio_fops = { read: read_rio, write: write_rio, ioctl: ioctl_rio, diff -urNp linux-2.4.37.7/drivers/usb/scanner.c linux-2.4.37.7/drivers/usb/scanner.c --- linux-2.4.37.7/drivers/usb/scanner.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/scanner.c 2009-11-10 19:30:27.000000000 -0500 @@ -852,8 +852,7 @@ ioctl_scanner(struct inode *inode, struc return retval; } -static struct -file_operations usb_scanner_fops = { +static const struct file_operations usb_scanner_fops = { owner: THIS_MODULE, read: read_scanner, write: write_scanner, diff -urNp linux-2.4.37.7/drivers/usb/tiglusb.c linux-2.4.37.7/drivers/usb/tiglusb.c --- linux-2.4.37.7/drivers/usb/tiglusb.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/tiglusb.c 2009-11-10 19:30:27.000000000 -0500 @@ -311,7 +311,7 @@ tiglusb_ioctl (struct inode *inode, stru /* ----- kernel module registering ------------------------------------ */ -static struct file_operations tiglusb_fops = { +static const struct file_operations tiglusb_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .read = tiglusb_read, diff -urNp linux-2.4.37.7/drivers/usb/usb.c linux-2.4.37.7/drivers/usb/usb.c --- linux-2.4.37.7/drivers/usb/usb.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/usb.c 2009-11-10 19:30:27.000000000 -0500 @@ -2324,7 +2324,7 @@ static int usb_open(struct inode * inode int minor = MINOR(inode->i_rdev); struct usb_driver *c = usb_minors[minor/16]; int err = -ENODEV; - struct file_operations *old_fops, *new_fops = NULL; + const struct file_operations *old_fops, *new_fops = NULL; /* * No load-on-demand? Randy, could you ACK that it's really not @@ -2345,7 +2345,7 @@ static int usb_open(struct inode * inode return err; } -static struct file_operations usb_fops = { +static const struct file_operations usb_fops = { owner: THIS_MODULE, open: usb_open, }; diff -urNp linux-2.4.37.7/drivers/usb/usblcd.c linux-2.4.37.7/drivers/usb/usblcd.c --- linux-2.4.37.7/drivers/usb/usblcd.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/usblcd.c 2009-11-10 19:30:27.000000000 -0500 @@ -300,8 +300,7 @@ static struct usb_device_id id_table [] MODULE_DEVICE_TABLE (usb, id_table); -static struct -file_operations usb_lcd_fops = { +static const struct file_operations usb_lcd_fops = { .owner = THIS_MODULE, .read = read_lcd, .write = write_lcd, diff -urNp linux-2.4.37.7/drivers/usb/usb-midi.c linux-2.4.37.7/drivers/usb/usb-midi.c --- linux-2.4.37.7/drivers/usb/usb-midi.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/usb-midi.c 2009-11-10 19:30:27.000000000 -0500 @@ -989,7 +989,7 @@ static int usb_midi_release(struct inode return 0; } -static struct file_operations usb_midi_fops = { +static const struct file_operations usb_midi_fops = { llseek: usb_midi_llseek, read: usb_midi_read, write: usb_midi_write, diff -urNp linux-2.4.37.7/drivers/usb/usb-skeleton.c linux-2.4.37.7/drivers/usb/usb-skeleton.c --- linux-2.4.37.7/drivers/usb/usb-skeleton.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/usb-skeleton.c 2009-11-10 19:30:27.000000000 -0500 @@ -150,7 +150,7 @@ static DECLARE_MUTEX (minor_table_mutex) * would use "struct net_driver" instead, and a serial * device would use "struct tty_driver". */ -static struct file_operations skel_fops = { +static const struct file_operations skel_fops = { /* * The owner field is part of the module-locking * mechanism. The idea is that the kernel knows diff -urNp linux-2.4.37.7/drivers/usb/w9968cf.c linux-2.4.37.7/drivers/usb/w9968cf.c --- linux-2.4.37.7/drivers/usb/w9968cf.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/usb/w9968cf.c 2009-11-10 19:30:27.000000000 -0500 @@ -375,7 +375,7 @@ MODULE_PARM_DESC(specific_debug, ****************************************************************************/ /* Video4linux interface */ -static struct file_operations w9968cf_fops; +static const struct file_operations w9968cf_fops; static int w9968cf_open(struct inode*, struct file*); static int w9968cf_release(struct inode*, struct file*); static ssize_t w9968cf_read(struct file*, char*, size_t, loff_t*); @@ -3708,7 +3708,7 @@ ioctl_fail: } -static struct file_operations w9968cf_fops = { +static const struct file_operations w9968cf_fops = { .owner = THIS_MODULE, .open = w9968cf_open, .release = w9968cf_release, diff -urNp linux-2.4.37.7/drivers/video/fbmem.c linux-2.4.37.7/drivers/video/fbmem.c --- linux-2.4.37.7/drivers/video/fbmem.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/video/fbmem.c 2009-11-10 19:30:27.000000000 -0500 @@ -748,7 +748,7 @@ fb_release(struct inode *inode, struct f return 0; } -static struct file_operations fb_fops = { +static const struct file_operations fb_fops = { owner: THIS_MODULE, read: fb_read, write: fb_write, diff -urNp linux-2.4.37.7/drivers/video/vesafb.c linux-2.4.37.7/drivers/video/vesafb.c --- linux-2.4.37.7/drivers/video/vesafb.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/video/vesafb.c 2009-11-10 19:30:27.000000000 -0500 @@ -546,7 +546,7 @@ int __init vesafb_init(void) video_visual = (video_bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; -#ifndef __i386__ +#if !defined(__i386__) || defined(CONFIG_PAX_KERNEXEC) screen_info.vesapm_seg = 0; #endif diff -urNp linux-2.4.37.7/drivers/zorro/proc.c linux-2.4.37.7/drivers/zorro/proc.c --- linux-2.4.37.7/drivers/zorro/proc.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/drivers/zorro/proc.c 2009-11-10 19:30:27.000000000 -0500 @@ -70,7 +70,7 @@ proc_bus_zorro_read(struct file *file, c return nbytes; } -static struct file_operations proc_bus_zorro_operations = { +static const struct file_operations proc_bus_zorro_operations = { llseek: proc_bus_zorro_lseek, read: proc_bus_zorro_read, }; diff -urNp linux-2.4.37.7/fs/adfs/adfs.h linux-2.4.37.7/fs/adfs/adfs.h --- linux-2.4.37.7/fs/adfs/adfs.h 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/adfs/adfs.h 2009-11-10 19:30:27.000000000 -0500 @@ -95,17 +95,17 @@ extern struct dentry *adfs_lookup(struct */ /* dir_*.c */ -extern struct inode_operations adfs_dir_inode_operations; -extern struct file_operations adfs_dir_operations; -extern struct dentry_operations adfs_dentry_operations; +extern const struct inode_operations adfs_dir_inode_operations; +extern const struct file_operations adfs_dir_operations; +extern const struct dentry_operations adfs_dentry_operations; extern struct adfs_dir_ops adfs_f_dir_ops; extern struct adfs_dir_ops adfs_fplus_dir_ops; extern int adfs_dir_update(struct super_block *sb, struct object_info *obj); /* file.c */ -extern struct inode_operations adfs_file_inode_operations; -extern struct file_operations adfs_file_operations; +extern const struct inode_operations adfs_file_inode_operations; +extern const struct file_operations adfs_file_operations; extern inline __u32 signed_asl(__u32 val, signed int shift) { diff -urNp linux-2.4.37.7/fs/adfs/dir.c linux-2.4.37.7/fs/adfs/dir.c --- linux-2.4.37.7/fs/adfs/dir.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/adfs/dir.c 2009-11-10 19:30:27.000000000 -0500 @@ -192,7 +192,7 @@ out: return ret; } -struct file_operations adfs_dir_operations = { +const struct file_operations adfs_dir_operations = { read: generic_read_dir, readdir: adfs_readdir, fsync: file_fsync, @@ -259,7 +259,7 @@ adfs_compare(struct dentry *parent, stru return 0; } -struct dentry_operations adfs_dentry_operations = { +const struct dentry_operations adfs_dentry_operations = { d_hash: adfs_hash, d_compare: adfs_compare, }; @@ -289,7 +289,7 @@ struct dentry *adfs_lookup(struct inode /* * directories can handle most operations... */ -struct inode_operations adfs_dir_inode_operations = { +const struct inode_operations adfs_dir_inode_operations = { lookup: adfs_lookup, setattr: adfs_notify_change, }; diff -urNp linux-2.4.37.7/fs/adfs/file.c linux-2.4.37.7/fs/adfs/file.c --- linux-2.4.37.7/fs/adfs/file.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/adfs/file.c 2009-11-10 19:30:27.000000000 -0500 @@ -28,7 +28,7 @@ #include "adfs.h" -struct file_operations adfs_file_operations = { +const struct file_operations adfs_file_operations = { llseek: generic_file_llseek, read: generic_file_read, mmap: generic_file_mmap, @@ -36,6 +36,6 @@ struct file_operations adfs_file_operati write: generic_file_write, }; -struct inode_operations adfs_file_inode_operations = { +const struct inode_operations adfs_file_inode_operations = { setattr: adfs_notify_change, }; diff -urNp linux-2.4.37.7/fs/adfs/inode.c linux-2.4.37.7/fs/adfs/inode.c --- linux-2.4.37.7/fs/adfs/inode.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/adfs/inode.c 2009-11-10 19:30:27.000000000 -0500 @@ -76,7 +76,7 @@ static int _adfs_bmap(struct address_spa return generic_block_bmap(mapping, block, adfs_get_block); } -static struct address_space_operations adfs_aops = { +static const struct address_space_operations adfs_aops = { readpage: adfs_readpage, writepage: adfs_writepage, sync_page: block_sync_page, diff -urNp linux-2.4.37.7/fs/adfs/super.c linux-2.4.37.7/fs/adfs/super.c --- linux-2.4.37.7/fs/adfs/super.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/adfs/super.c 2009-11-10 19:30:27.000000000 -0500 @@ -232,7 +232,7 @@ static int adfs_statfs(struct super_bloc return 0; } -static struct super_operations adfs_sops = { +static const struct super_operations adfs_sops = { write_inode: adfs_write_inode, put_super: adfs_put_super, statfs: adfs_statfs, diff -urNp linux-2.4.37.7/fs/affs/dir.c linux-2.4.37.7/fs/affs/dir.c --- linux-2.4.37.7/fs/affs/dir.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/affs/dir.c 2009-11-10 19:30:27.000000000 -0500 @@ -25,7 +25,7 @@ static int affs_readdir(struct file *, void *, filldir_t); -struct file_operations affs_dir_operations = { +const struct file_operations affs_dir_operations = { read: generic_read_dir, readdir: affs_readdir, fsync: file_fsync, @@ -34,7 +34,7 @@ struct file_operations affs_dir_operatio /* * directories can handle most operations... */ -struct inode_operations affs_dir_inode_operations = { +const struct inode_operations affs_dir_inode_operations = { create: affs_create, lookup: affs_lookup, link: affs_link, diff -urNp linux-2.4.37.7/fs/affs/file.c linux-2.4.37.7/fs/affs/file.c --- linux-2.4.37.7/fs/affs/file.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/affs/file.c 2009-11-10 19:30:27.000000000 -0500 @@ -44,7 +44,7 @@ static ssize_t affs_file_write(struct fi static int affs_file_open(struct inode *inode, struct file *filp); static int affs_file_release(struct inode *inode, struct file *filp); -struct file_operations affs_file_operations = { +const struct file_operations affs_file_operations = { llseek: generic_file_llseek, read: generic_file_read, write: affs_file_write, @@ -54,7 +54,7 @@ struct file_operations affs_file_operati fsync: file_fsync, }; -struct inode_operations affs_file_inode_operations = { +const struct inode_operations affs_file_inode_operations = { truncate: affs_truncate, setattr: affs_notify_change, }; @@ -427,7 +427,7 @@ static int _affs_bmap(struct address_spa { return generic_block_bmap(mapping,block,affs_get_block); } -struct address_space_operations affs_aops = { +const struct address_space_operations affs_aops = { readpage: affs_readpage, writepage: affs_writepage, sync_page: block_sync_page, @@ -787,7 +787,7 @@ out: goto done; } -struct address_space_operations affs_aops_ofs = { +const struct address_space_operations affs_aops_ofs = { readpage: affs_readpage_ofs, //writepage: affs_writepage_ofs, //sync_page: affs_sync_page_ofs, diff -urNp linux-2.4.37.7/fs/affs/inode.c linux-2.4.37.7/fs/affs/inode.c --- linux-2.4.37.7/fs/affs/inode.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/affs/inode.c 2009-11-10 19:30:27.000000000 -0500 @@ -31,7 +31,7 @@ #include #include -extern struct inode_operations affs_symlink_inode_operations; +extern const struct inode_operations affs_symlink_inode_operations; extern struct timezone sys_tz; void diff -urNp linux-2.4.37.7/fs/affs/namei.c linux-2.4.37.7/fs/affs/namei.c --- linux-2.4.37.7/fs/affs/namei.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/affs/namei.c 2009-11-10 19:30:27.000000000 -0500 @@ -22,7 +22,7 @@ typedef int (*toupper_t)(int); -extern struct inode_operations affs_symlink_inode_operations; +extern const struct inode_operations affs_symlink_inode_operations; static int affs_toupper(int ch); static int affs_hash_dentry(struct dentry *, struct qstr *); @@ -31,12 +31,12 @@ static int affs_intl_toupper(int ch); static int affs_intl_hash_dentry(struct dentry *, struct qstr *); static int affs_intl_compare_dentry(struct dentry *, struct qstr *, struct qstr *); -struct dentry_operations affs_dentry_operations = { +const struct dentry_operations affs_dentry_operations = { d_hash: affs_hash_dentry, d_compare: affs_compare_dentry, }; -struct dentry_operations affs_intl_dentry_operations = { +const struct dentry_operations affs_intl_dentry_operations = { d_hash: affs_intl_hash_dentry, d_compare: affs_intl_compare_dentry, }; diff -urNp linux-2.4.37.7/fs/affs/super.c linux-2.4.37.7/fs/affs/super.c --- linux-2.4.37.7/fs/affs/super.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/affs/super.c 2009-11-10 19:30:27.000000000 -0500 @@ -77,7 +77,7 @@ affs_write_super(struct super_block *sb) pr_debug("AFFS: write_super() at %lu, clean=%d\n", CURRENT_TIME, clean); } -static struct super_operations affs_sops = { +static const struct super_operations affs_sops = { read_inode: affs_read_inode, write_inode: affs_write_inode, put_inode: affs_put_inode, diff -urNp linux-2.4.37.7/fs/affs/symlink.c linux-2.4.37.7/fs/affs/symlink.c --- linux-2.4.37.7/fs/affs/symlink.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/affs/symlink.c 2009-11-10 19:30:27.000000000 -0500 @@ -76,11 +76,11 @@ fail: return err; } -struct address_space_operations affs_symlink_aops = { +const struct address_space_operations affs_symlink_aops = { readpage: affs_symlink_readpage, }; -struct inode_operations affs_symlink_inode_operations = { +const struct inode_operations affs_symlink_inode_operations = { readlink: page_readlink, follow_link: page_follow_link, setattr: affs_notify_change, diff -urNp linux-2.4.37.7/fs/autofs/autofs_i.h linux-2.4.37.7/fs/autofs/autofs_i.h --- linux-2.4.37.7/fs/autofs/autofs_i.h 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/autofs/autofs_i.h 2009-11-10 19:30:27.000000000 -0500 @@ -137,10 +137,10 @@ struct autofs_dir_ent *autofs_expire(str /* Operations structures */ -extern struct inode_operations autofs_root_inode_operations; -extern struct inode_operations autofs_symlink_inode_operations; -extern struct inode_operations autofs_dir_inode_operations; -extern struct file_operations autofs_root_operations; +extern const struct inode_operations autofs_root_inode_operations; +extern const struct inode_operations autofs_symlink_inode_operations; +extern const struct inode_operations autofs_dir_inode_operations; +extern const struct file_operations autofs_root_operations; /* Initializing function */ diff -urNp linux-2.4.37.7/fs/autofs/dir.c linux-2.4.37.7/fs/autofs/dir.c --- linux-2.4.37.7/fs/autofs/dir.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/autofs/dir.c 2009-11-10 19:30:27.000000000 -0500 @@ -23,7 +23,7 @@ static struct dentry *autofs_dir_lookup( return NULL; } -struct inode_operations autofs_dir_inode_operations = { +const struct inode_operations autofs_dir_inode_operations = { lookup: autofs_dir_lookup, }; diff -urNp linux-2.4.37.7/fs/autofs/inode.c linux-2.4.37.7/fs/autofs/inode.c --- linux-2.4.37.7/fs/autofs/inode.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/autofs/inode.c 2009-11-10 19:30:27.000000000 -0500 @@ -41,7 +41,7 @@ static void autofs_put_super(struct supe static int autofs_statfs(struct super_block *sb, struct statfs *buf); static void autofs_read_inode(struct inode *inode); -static struct super_operations autofs_sops = { +static const struct super_operations autofs_sops = { read_inode: autofs_read_inode, put_super: autofs_put_super, statfs: autofs_statfs, diff -urNp linux-2.4.37.7/fs/autofs/root.c linux-2.4.37.7/fs/autofs/root.c --- linux-2.4.37.7/fs/autofs/root.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/autofs/root.c 2009-11-10 19:30:27.000000000 -0500 @@ -25,13 +25,13 @@ static int autofs_root_rmdir(struct inod static int autofs_root_mkdir(struct inode *,struct dentry *,int); static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long); -struct file_operations autofs_root_operations = { +const struct file_operations autofs_root_operations = { read: generic_read_dir, readdir: autofs_root_readdir, ioctl: autofs_root_ioctl, }; -struct inode_operations autofs_root_inode_operations = { +const struct inode_operations autofs_root_inode_operations = { lookup: autofs_root_lookup, unlink: autofs_root_unlink, symlink: autofs_root_symlink, @@ -187,7 +187,7 @@ static int autofs_revalidate(struct dent return 1; } -static struct dentry_operations autofs_dentry_operations = { +static const struct dentry_operations autofs_dentry_operations = { d_revalidate: autofs_revalidate, }; diff -urNp linux-2.4.37.7/fs/autofs/symlink.c linux-2.4.37.7/fs/autofs/symlink.c --- linux-2.4.37.7/fs/autofs/symlink.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/autofs/symlink.c 2009-11-10 19:30:27.000000000 -0500 @@ -24,7 +24,7 @@ static int autofs_follow_link(struct den return vfs_follow_link(nd, s); } -struct inode_operations autofs_symlink_inode_operations = { +const struct inode_operations autofs_symlink_inode_operations = { readlink: autofs_readlink, follow_link: autofs_follow_link }; diff -urNp linux-2.4.37.7/fs/autofs4/autofs_i.h linux-2.4.37.7/fs/autofs4/autofs_i.h --- linux-2.4.37.7/fs/autofs4/autofs_i.h 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/autofs4/autofs_i.h 2009-11-10 19:30:27.000000000 -0500 @@ -136,10 +136,10 @@ int autofs4_expire_multi(struct super_bl /* Operations structures */ -extern struct inode_operations autofs4_symlink_inode_operations; -extern struct inode_operations autofs4_dir_inode_operations; -extern struct inode_operations autofs4_root_inode_operations; -extern struct file_operations autofs4_root_operations; +extern const struct inode_operations autofs4_symlink_inode_operations; +extern const struct inode_operations autofs4_dir_inode_operations; +extern const struct inode_operations autofs4_root_inode_operations; +extern const struct file_operations autofs4_root_operations; /* Initializing function */ diff -urNp linux-2.4.37.7/fs/autofs4/inode.c linux-2.4.37.7/fs/autofs4/inode.c --- linux-2.4.37.7/fs/autofs4/inode.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/autofs4/inode.c 2009-11-10 19:30:27.000000000 -0500 @@ -92,7 +92,7 @@ static void autofs4_put_super(struct sup static int autofs4_statfs(struct super_block *sb, struct statfs *buf); -static struct super_operations autofs4_sops = { +static const struct super_operations autofs4_sops = { put_super: autofs4_put_super, statfs: autofs4_statfs, }; diff -urNp linux-2.4.37.7/fs/autofs4/root.c linux-2.4.37.7/fs/autofs4/root.c --- linux-2.4.37.7/fs/autofs4/root.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/autofs4/root.c 2009-11-10 19:30:27.000000000 -0500 @@ -26,7 +26,7 @@ static int autofs4_dir_mkdir(struct inod static int autofs4_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long); static struct dentry *autofs4_root_lookup(struct inode *,struct dentry *); -struct file_operations autofs4_root_operations = { +const struct file_operations autofs4_root_operations = { open: dcache_dir_open, release: dcache_dir_close, llseek: dcache_dir_lseek, @@ -36,7 +36,7 @@ struct file_operations autofs4_root_oper ioctl: autofs4_root_ioctl, }; -struct inode_operations autofs4_root_inode_operations = { +const struct inode_operations autofs4_root_inode_operations = { lookup: autofs4_root_lookup, unlink: autofs4_dir_unlink, symlink: autofs4_dir_symlink, @@ -44,7 +44,7 @@ struct inode_operations autofs4_root_ino rmdir: autofs4_dir_rmdir, }; -struct inode_operations autofs4_dir_inode_operations = { +const struct inode_operations autofs4_dir_inode_operations = { lookup: autofs4_dir_lookup, unlink: autofs4_dir_unlink, symlink: autofs4_dir_symlink, @@ -216,13 +216,13 @@ static void autofs4_dentry_release(struc } /* For dentries of directories in the root dir */ -static struct dentry_operations autofs4_root_dentry_operations = { +static const struct dentry_operations autofs4_root_dentry_operations = { d_revalidate: autofs4_root_revalidate, d_release: autofs4_dentry_release, }; /* For other dentries */ -static struct dentry_operations autofs4_dentry_operations = { +static const struct dentry_operations autofs4_dentry_operations = { d_revalidate: autofs4_revalidate, d_release: autofs4_dentry_release, }; diff -urNp linux-2.4.37.7/fs/autofs4/symlink.c linux-2.4.37.7/fs/autofs4/symlink.c --- linux-2.4.37.7/fs/autofs4/symlink.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/autofs4/symlink.c 2009-11-10 19:30:27.000000000 -0500 @@ -26,7 +26,7 @@ static int autofs4_follow_link(struct de return vfs_follow_link(nd, ino->u.symlink); } -struct inode_operations autofs4_symlink_inode_operations = { +const struct inode_operations autofs4_symlink_inode_operations = { readlink: autofs4_readlink, follow_link: autofs4_follow_link }; diff -urNp linux-2.4.37.7/fs/bad_inode.c linux-2.4.37.7/fs/bad_inode.c --- linux-2.4.37.7/fs/bad_inode.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/bad_inode.c 2009-11-10 19:30:27.000000000 -0500 @@ -90,8 +90,7 @@ static int bad_follow_link(struct dentry return vfs_follow_link(nd, ERR_PTR(-EIO)); } -static struct file_operations bad_file_ops = -{ +static const struct file_operations bad_file_ops = { llseek: bad_file_llseek, read: bad_file_read, write: bad_file_write, @@ -175,8 +174,7 @@ static int bad_inode_revalidate(struct d return -EIO; } -struct inode_operations bad_inode_ops = -{ +const struct inode_operations bad_inode_ops = { create: bad_inode_create, lookup: bad_inode_lookup, link: bad_inode_link, diff -urNp linux-2.4.37.7/fs/befs/linuxvfs.c linux-2.4.37.7/fs/befs/linuxvfs.c --- linux-2.4.37.7/fs/befs/linuxvfs.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/befs/linuxvfs.c 2009-11-10 19:30:27.000000000 -0500 @@ -66,31 +66,31 @@ static const struct super_operations bef remount_fs:befs_remount, }; -struct file_operations befs_dir_operations = { +const struct file_operations befs_dir_operations = { read:generic_read_dir, readdir:befs_readdir, }; -struct inode_operations befs_dir_inode_operations = { +const struct inode_operations befs_dir_inode_operations = { lookup:befs_lookup, }; -struct file_operations befs_file_operations = { +const struct file_operations befs_file_operations = { llseek:default_llseek, read:generic_file_read, mmap:generic_file_mmap, }; -struct inode_operations befs_file_inode_operations = { +const struct inode_operations befs_file_inode_operations = { }; -struct address_space_operations befs_aops = { +const struct address_space_operations befs_aops = { readpage:befs_readpage, sync_page:block_sync_page, bmap:befs_bmap, }; -static struct inode_operations befs_symlink_inode_operations = { +static const struct inode_operations befs_symlink_inode_operations = { readlink:befs_readlink, follow_link:befs_follow_link, }; diff -urNp linux-2.4.37.7/fs/bfs/dir.c linux-2.4.37.7/fs/bfs/dir.c --- linux-2.4.37.7/fs/bfs/dir.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/bfs/dir.c 2009-11-10 19:30:27.000000000 -0500 @@ -65,7 +65,7 @@ static int bfs_readdir(struct file * f, return 0; } -struct file_operations bfs_dir_operations = { +const struct file_operations bfs_dir_operations = { read: generic_read_dir, readdir: bfs_readdir, fsync: file_fsync, @@ -243,7 +243,7 @@ end_rename: return error; } -struct inode_operations bfs_dir_inops = { +const struct inode_operations bfs_dir_inops = { create: bfs_create, lookup: bfs_lookup, link: bfs_link, diff -urNp linux-2.4.37.7/fs/bfs/file.c linux-2.4.37.7/fs/bfs/file.c --- linux-2.4.37.7/fs/bfs/file.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/bfs/file.c 2009-11-10 19:30:27.000000000 -0500 @@ -18,7 +18,7 @@ #define dprintf(x...) #endif -struct file_operations bfs_file_operations = { +const struct file_operations bfs_file_operations = { llseek: generic_file_llseek, read: generic_file_read, write: generic_file_write, @@ -156,7 +156,7 @@ static int bfs_bmap(struct address_space return generic_block_bmap(mapping, block, bfs_get_block); } -struct address_space_operations bfs_aops = { +const struct address_space_operations bfs_aops = { readpage: bfs_readpage, writepage: bfs_writepage, sync_page: block_sync_page, @@ -165,4 +165,4 @@ struct address_space_operations bfs_aops bmap: bfs_bmap, }; -struct inode_operations bfs_file_inops; +const struct inode_operations bfs_file_inops; diff -urNp linux-2.4.37.7/fs/bfs/inode.c linux-2.4.37.7/fs/bfs/inode.c --- linux-2.4.37.7/fs/bfs/inode.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/bfs/inode.c 2009-11-10 19:30:27.000000000 -0500 @@ -209,7 +209,7 @@ static void bfs_write_super(struct super s->s_dirt = 0; } -static struct super_operations bfs_sops = { +static const struct super_operations bfs_sops = { read_inode: bfs_read_inode, write_inode: bfs_write_inode, delete_inode: bfs_delete_inode, diff -urNp linux-2.4.37.7/fs/binfmt_aout.c linux-2.4.37.7/fs/binfmt_aout.c --- linux-2.4.37.7/fs/binfmt_aout.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/binfmt_aout.c 2009-11-10 19:30:27.000000000 -0500 @@ -121,10 +121,12 @@ static int aout_core_dump(long signr, st /* If the size of the dump file exceeds the rlimit, then see what would happen if we wrote the stack, but not the data area. */ #ifdef __sparc__ + gr_learn_resource(current, RLIMIT_CORE, dump.u_dsize+dump.u_ssize, 1); if ((dump.u_dsize+dump.u_ssize) > current->rlim[RLIMIT_CORE].rlim_cur) dump.u_dsize = 0; #else + gr_learn_resource(current, RLIMIT_CORE, (dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE, 1); if ((dump.u_dsize+dump.u_ssize+1) * PAGE_SIZE > current->rlim[RLIMIT_CORE].rlim_cur) dump.u_dsize = 0; @@ -132,10 +134,12 @@ static int aout_core_dump(long signr, st /* Make sure we have enough room to write the stack and data areas. */ #ifdef __sparc__ + gr_learn_resource(current, RLIMIT_CORE, dump.u_ssize, 1); if ((dump.u_ssize) > current->rlim[RLIMIT_CORE].rlim_cur) dump.u_ssize = 0; #else + gr_learn_resource(current, RLIMIT_CORE, (dump.u_ssize+1) * PAGE_SIZE, 1); if ((dump.u_ssize+1) * PAGE_SIZE > current->rlim[RLIMIT_CORE].rlim_cur) dump.u_ssize = 0; @@ -284,6 +288,8 @@ static int load_aout_binary(struct linux rlim = current->rlim[RLIMIT_DATA].rlim_cur; if (rlim >= RLIM_INFINITY) rlim = ~0; + + gr_learn_resource(current, RLIMIT_DATA, ex.a_data + ex.a_bss, 1); if (ex.a_data + ex.a_bss > rlim) return -ENOMEM; @@ -315,6 +321,28 @@ static int load_aout_binary(struct linux current->mm->mmap = NULL; compute_creds(bprm); current->flags &= ~PF_FORKNOEXEC; + +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) + current->mm->pax_flags = 0UL; +#endif + +#ifdef CONFIG_PAX_PAGEEXEC + if (!(N_FLAGS(ex) & F_PAX_PAGEEXEC)) { + current->mm->pax_flags |= MF_PAX_PAGEEXEC; + +#ifdef CONFIG_PAX_EMUTRAMP + if (N_FLAGS(ex) & F_PAX_EMUTRAMP) + current->mm->pax_flags |= MF_PAX_EMUTRAMP; +#endif + +#ifdef CONFIG_PAX_MPROTECT + if (!(N_FLAGS(ex) & F_PAX_MPROTECT)) + current->mm->pax_flags |= MF_PAX_MPROTECT; +#endif + + } +#endif + #ifdef __sparc__ if (N_MAGIC(ex) == NMAGIC) { loff_t pos = fd_offset; @@ -408,7 +436,7 @@ static int load_aout_binary(struct linux down_write(¤t->mm->mmap_sem); error = do_mmap(bprm->file, N_DATADDR(ex), ex.a_data, - PROT_READ | PROT_WRITE | PROT_EXEC, + PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_DENYWRITE | MAP_EXECUTABLE, fd_offset + ex.a_text); up_write(¤t->mm->mmap_sem); diff -urNp linux-2.4.37.7/fs/binfmt_elf.c linux-2.4.37.7/fs/binfmt_elf.c --- linux-2.4.37.7/fs/binfmt_elf.c 2009-11-07 11:52:20.000000000 -0500 +++ linux-2.4.37.7/fs/binfmt_elf.c 2009-11-10 19:30:27.000000000 -0500 @@ -33,15 +33,23 @@ #include #include #include +#include +#include #include #include #include +#include #define DLINFO_ITEMS 13 #include +#ifdef CONFIG_PAX_HOOK_ACL_FLAGS +void (*pax_set_flags_func)(struct linux_binprm * bprm); +EXPORT_SYMBOL(pax_set_flags_func); +#endif + static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs); static int load_elf_library(struct file*); static unsigned long elf_map (struct file *, unsigned long, struct elf_phdr *, int, int); @@ -81,18 +89,22 @@ static struct linux_binfmt elf_format = static int set_brk(unsigned long start, unsigned long end) { + unsigned long e = end, retval; + start = ELF_PAGEALIGN(start); end = ELF_PAGEALIGN(end); + + down_write(¤t->mm->mmap_sem); if (end > start) { - unsigned long addr; - down_write(¤t->mm->mmap_sem); - addr = do_brk(start, end - start); - up_write(¤t->mm->mmap_sem); - if (BAD_ADDR(addr)) - return addr; + retval = do_brk(start, end - start); + if (BAD_ADDR(retval)) + goto out; } - current->mm->start_brk = current->mm->brk = end; - return 0; + current->mm->start_brk = current->mm->brk = e; + retval = 0UL; +out: + up_write(¤t->mm->mmap_sem); + return retval; } @@ -275,7 +287,7 @@ static unsigned long load_elf_interp(str unsigned long load_addr = 0; int load_addr_set = 0; unsigned long last_bss = 0, elf_bss = 0; - unsigned long error = ~0UL; + unsigned long error = -EINVAL; int retval, i, size; /* First of all, some simple consistency checks */ @@ -397,6 +409,8 @@ static unsigned long load_elf_interp(str * switch to out-of-band error reporting. */ error = ((unsigned long) interp_elf_ex->e_entry) + load_addr; + if (BAD_ADDR(error)) + error = -EFAULT; out_close: kfree(elf_phdata); @@ -407,7 +421,7 @@ out: static unsigned long load_aout_interp(struct exec * interp_ex, struct file * interpreter) { - unsigned long text_data, elf_entry = ~0UL; + unsigned long text_data, elf_entry = -EINVAL; char * addr; loff_t offset; @@ -452,6 +466,171 @@ out: return elf_entry; } +#if (defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS)) && defined(CONFIG_PAX_SOFTMODE) +static unsigned long pax_parse_softmode(const struct elf_phdr * const elf_phdata) +{ + unsigned long pax_flags = 0UL; + +#ifdef CONFIG_PAX_PAGEEXEC + if (elf_phdata->p_flags & PF_PAGEEXEC) + pax_flags |= MF_PAX_PAGEEXEC; +#endif + +#ifdef CONFIG_PAX_SEGMEXEC + if (elf_phdata->p_flags & PF_SEGMEXEC) { + pax_flags &= ~MF_PAX_PAGEEXEC; + pax_flags |= MF_PAX_SEGMEXEC; + } +#endif + +#ifdef CONFIG_PAX_EMUTRAMP + if (elf_phdata->p_flags & PF_EMUTRAMP) + pax_flags |= MF_PAX_EMUTRAMP; +#endif + +#ifdef CONFIG_PAX_MPROTECT + if (elf_phdata->p_flags & PF_MPROTECT) + pax_flags |= MF_PAX_MPROTECT; +#endif + +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) + +#ifdef CONFIG_PAX_SOFTMODE + if (pax_aslr) +#endif + + if (elf_phdata->p_flags & PF_RANDMMAP) + pax_flags |= MF_PAX_RANDMMAP; +#endif + + return pax_flags; +} +#endif + +#ifdef CONFIG_PAX_PT_PAX_FLAGS +static unsigned long pax_parse_hardmode(const struct elf_phdr * const elf_phdata) +{ + unsigned long pax_flags = 0UL; + +#ifdef CONFIG_PAX_PAGEEXEC + if (!(elf_phdata->p_flags & PF_NOPAGEEXEC)) + pax_flags |= MF_PAX_PAGEEXEC; +#endif + +#ifdef CONFIG_PAX_SEGMEXEC + if (!(elf_phdata->p_flags & PF_NOSEGMEXEC)) { + pax_flags &= ~MF_PAX_PAGEEXEC; + pax_flags |= MF_PAX_SEGMEXEC; + } +#endif + +#ifdef CONFIG_PAX_EMUTRAMP + if (!(elf_phdata->p_flags & PF_NOEMUTRAMP)) + pax_flags |= MF_PAX_EMUTRAMP; +#endif + +#ifdef CONFIG_PAX_MPROTECT + if (!(elf_phdata->p_flags & PF_NOMPROTECT)) + pax_flags |= MF_PAX_MPROTECT; +#endif + +#if defined(CONFIG_PAX_RANDMMAP) || defined(CONFIG_PAX_RANDUSTACK) + +#ifdef CONFIG_PAX_SOFTMODE + if (pax_aslr) +#endif + + if (!(elf_phdata->p_flags & PF_NORANDMMAP)) + pax_flags |= MF_PAX_RANDMMAP; +#endif + + return pax_flags; +} +#endif + +#ifdef CONFIG_PAX_EI_PAX +static unsigned long pax_parse_ei_pax(const struct elfhdr * const elf_ex) +{ + unsigned long pax_flags = 0UL; + +#ifdef CONFIG_PAX_PAGEEXEC + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_PAGEEXEC)) + pax_flags |= MF_PAX_PAGEEXEC; +#endif + +#ifdef CONFIG_PAX_SEGMEXEC + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_SEGMEXEC)) { + pax_flags &= ~MF_PAX_PAGEEXEC; + pax_flags |= MF_PAX_SEGMEXEC; + } +#endif + +#ifdef CONFIG_PAX_EMUTRAMP + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && (elf_ex->e_ident[EI_PAX] & EF_PAX_EMUTRAMP)) + pax_flags |= MF_PAX_EMUTRAMP; +#endif + +#ifdef CONFIG_PAX_MPROTECT + if ((pax_flags & (MF_PAX_PAGEEXEC | MF_PAX_SEGMEXEC)) && !(elf_ex->e_ident[EI_PAX] & EF_PAX_MPROTECT)) + pax_flags |= MF_PAX_MPROTECT; +#endif + +#ifdef CONFIG_PAX_ASLR + +#ifdef CONFIG_PAX_SOFTMODE + if (pax_aslr) +#endif + + if (!(elf_ex->e_ident[EI_PAX] & EF_PAX_RANDMMAP)) + pax_flags |= MF_PAX_RANDMMAP; +#endif + + return pax_flags; +} +#endif + +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) +static long pax_parse_elf_flags(const struct elfhdr * const elf_ex, const struct elf_phdr * const elf_phdata) +{ + unsigned long pax_flags = 0UL; + +#ifdef CONFIG_PAX_PT_PAX_FLAGS + unsigned long i; +#endif + +#ifdef CONFIG_PAX_EI_PAX + pax_flags = pax_parse_ei_pax(elf_ex); +#endif + +#ifdef CONFIG_PAX_PT_PAX_FLAGS + for (i = 0UL; i < elf_ex->e_phnum; i++) + if (elf_phdata[i].p_type == PT_PAX_FLAGS) { + if (((elf_phdata[i].p_flags & PF_PAGEEXEC) && (elf_phdata[i].p_flags & PF_NOPAGEEXEC)) || + ((elf_phdata[i].p_flags & PF_SEGMEXEC) && (elf_phdata[i].p_flags & PF_NOSEGMEXEC)) || + ((elf_phdata[i].p_flags & PF_EMUTRAMP) && (elf_phdata[i].p_flags & PF_NOEMUTRAMP)) || + ((elf_phdata[i].p_flags & PF_MPROTECT) && (elf_phdata[i].p_flags & PF_NOMPROTECT)) || + ((elf_phdata[i].p_flags & PF_RANDMMAP) && (elf_phdata[i].p_flags & PF_NORANDMMAP))) + return -EINVAL; + +#ifdef CONFIG_PAX_SOFTMODE + if (pax_softmode) + pax_flags = pax_parse_softmode(&elf_phdata[i]); + else +#endif + + pax_flags = pax_parse_hardmode(&elf_phdata[i]); + break; + } +#endif + + if (0 > pax_check_flags(&pax_flags)) + return -EINVAL; + + current->mm->pax_flags = pax_flags; + return 0; +} +#endif + /* * These are the functions used to load ELF style executables and shared * libraries. There is no binary dependent code anywhere else. @@ -484,7 +663,7 @@ static int load_elf_binary(struct linux_ struct exec interp_ex; char passed_fileno[6]; struct files_struct *files; - + /* Get the exec-header */ elf_ex = *((struct elfhdr *) bprm->buf); @@ -684,7 +863,47 @@ static int load_elf_binary(struct linux_ current->mm->end_data = 0; current->mm->end_code = 0; current->mm->mmap = NULL; + +#if defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR) + current->mm->pax_flags = 0UL; +#endif + +#ifdef CONFIG_PAX_DLRESOLVE + current->mm->call_dl_resolve = 0UL; +#endif + +#if defined(CONFIG_PPC32) && defined(CONFIG_PAX_EMUSIGRT) + current->mm->call_syscall = 0UL; +#endif + +#ifdef CONFIG_PAX_ASLR + current->mm->delta_mmap = 0UL; + current->mm->delta_stack = 0UL; +#endif + current->flags &= ~PF_FORKNOEXEC; + +#if defined(CONFIG_PAX_EI_PAX) || defined(CONFIG_PAX_PT_PAX_FLAGS) + if (0 > pax_parse_elf_flags(&elf_ex, elf_phdata)) { + send_sig(SIGKILL, current, 0); + goto out_free_dentry; + } +#endif + +#if defined(CONFIG_PAX_HAVE_ACL_FLAGS) && (defined(CONFIG_PAX_NOEXEC) || defined(CONFIG_PAX_ASLR)) + pax_set_initial_flags(bprm); +#elif defined(CONFIG_PAX_HOOK_ACL_FLAGS) + if (pax_set_initial_flags_func) + (*pax_set_initial_flags_func)(bprm); +#endif + +#ifdef CONFIG_PAX_ASLR + if (current->mm->pax_flags & MF_PAX_RANDMMAP) { + current->mm->delta_mmap = (net_random() & ((1UL << PAX_DELTA_MMAP_LEN)-1)) << PAGE_SHIFT; + current->mm->delta_stack = (net_random() & ((1UL << PAX_DELTA_STACK_LEN)-1)) << PAGE_SHIFT; + } +#endif + elf_entry = (unsigned long) elf_ex.e_entry; /* Do this so that we can load the interpreter, if need be. We will @@ -693,7 +912,7 @@ static int load_elf_binary(struct linux_ retval = setup_arg_pages(bprm); if (retval < 0) { send_sig(SIGKILL, current, 0); - return retval; + goto out_free_dentry; } current->mm->start_stack = bprm->p; @@ -745,6 +964,20 @@ static int load_elf_binary(struct linux_ base, as well as whatever program they might try to exec. This is because the brk will follow the loader, and is not movable. */ load_bias = ELF_PAGESTART(ELF_ET_DYN_BASE - vaddr); + +#ifdef CONFIG_PAX_RANDMMAP + /* PaX: randomize base address at the default exe base if requested */ + if ((current->mm->pax_flags & MF_PAX_RANDMMAP) && elf_interpreter) { +#ifdef __sparc_v9__ + load_bias = (net_random() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << (PAGE_SHIFT+1); +#else + load_bias = (net_random() & ((1UL << PAX_DELTA_MMAP_LEN) - 1)) << PAGE_SHIFT; +#endif + load_bias = ELF_PAGESTART(PAX_ELF_ET_DYN_BASE - vaddr + load_bias); + elf_flags |= MAP_FIXED; + } +#endif + } error = elf_map(bprm->file, load_bias + vaddr, elf_ppnt, elf_prot, elf_flags); @@ -801,6 +1034,11 @@ static int load_elf_binary(struct linux_ start_data += l