The sweeping change is to make add_taint() explicitly indicate whether to disable
lockdep, but it's a mechanical change. Cheers, Rusty. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJRJAcuAAoJENkgDmzRrbjxsw0P/3eXb+LddYnx0V0uHYdKpCUf 4vdW7X0fX3Z+aUK69IWRL/6ahoO4TpaHYGHBDjEoivyQ0GDq14X7JNWsYYt3LdMf 3wmDgRc2cn/mZOJbFeVpNV8ox5l/xc0CUvV+iQ8tMjfQItXMXgWUFZKMECsXKSO6 eex3lrw9M2jAX2uL8LQPp9W8xtKu24nSZRC6tH5riE/8fCzi1cZPPAqfxP5c8Lee ZXtbCRSyAFENZLpKyMe1PC7HvtJyi5NDn9xwOQiXULZV/VOlvP94DGBLIKCM/6dn 4QvZxpG0P0uOlpCgRAVLyh/z7g4XY4VF/fHopLCmEcqLsvgD+V2LQpQ9zWUalLPC Z+pUpz2vu0gIddPU1nR8R6oGpEdJ8O12aJle62p/RSXWZGx12qUQ+Tamu0tgKcv1 AsiJfbUGNDYfxgU6sHsoQjl2f68LTVckCU1C1LqEbW/S104EIORtGx30CHM4LRiO 32kDC5TtgYDBKQAIqJ4bL48ZMh+9W3uX40p7xzOI5khHQjvswUKa3jcxupU0C1uv lx8KXo7pn8WT33QGysWC782wJCgJuzSc2vRn+KQoqoynuHGM6agaEtR59gil3QWO rQEcxH63BBRDgHlg4FM9IkJwwsnC3PWKL8gbX0uAWXAPMbgapJkuuGZAwt0WDGVK +GszxsFkCjlW0mK0egTb =tiSY -----END PGP SIGNATURE----- Merge tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux Pull module update from Rusty Russell: "The sweeping change is to make add_taint() explicitly indicate whether to disable lockdep, but it's a mechanical change." * tag 'modules-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux: MODSIGN: Add option to not sign modules during modules_install MODSIGN: Add -s <signature> option to sign-file MODSIGN: Specify the hash algorithm on sign-file command line MODSIGN: Simplify Makefile with a Kconfig helper module: clean up load_module a little more. modpost: Ignore ARC specific non-alloc sections module: constify within_module_* taint: add explicit flag to show whether lock dep is still OK. module: printk message when module signature fail taints kernel.
This commit is contained in:
commit
9043a2650c
4
Makefile
4
Makefile
@ -720,11 +720,11 @@ endif # INSTALL_MOD_STRIP
|
|||||||
export mod_strip_cmd
|
export mod_strip_cmd
|
||||||
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_MODULE_SIG),y)
|
ifdef CONFIG_MODULE_SIG_ALL
|
||||||
MODSECKEY = ./signing_key.priv
|
MODSECKEY = ./signing_key.priv
|
||||||
MODPUBKEY = ./signing_key.x509
|
MODPUBKEY = ./signing_key.x509
|
||||||
export MODPUBKEY
|
export MODPUBKEY
|
||||||
mod_sign_cmd = perl $(srctree)/scripts/sign-file $(MODSECKEY) $(MODPUBKEY)
|
mod_sign_cmd = perl $(srctree)/scripts/sign-file $(CONFIG_MODULE_SIG_HASH) $(MODSECKEY) $(MODPUBKEY)
|
||||||
else
|
else
|
||||||
mod_sign_cmd = true
|
mod_sign_cmd = true
|
||||||
endif
|
endif
|
||||||
|
@ -186,7 +186,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
|
|||||||
#endif
|
#endif
|
||||||
printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err);
|
printk("%s(%d): %s %ld\n", current->comm, task_pid_nr(current), str, err);
|
||||||
dik_show_regs(regs, r9_15);
|
dik_show_regs(regs, r9_15);
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
dik_show_trace((unsigned long *)(regs+1));
|
dik_show_trace((unsigned long *)(regs+1));
|
||||||
dik_show_code((unsigned int *)regs->pc);
|
dik_show_code((unsigned int *)regs->pc);
|
||||||
|
|
||||||
|
@ -296,7 +296,7 @@ static void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
|
|||||||
|
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
die_owner = -1;
|
die_owner = -1;
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
die_nest_count--;
|
die_nest_count--;
|
||||||
if (!die_nest_count)
|
if (!die_nest_count)
|
||||||
/* Nest count reaches zero, release the lock. */
|
/* Nest count reaches zero, release the lock. */
|
||||||
|
@ -242,7 +242,7 @@ void die(const char *str, struct pt_regs *regs, int err)
|
|||||||
crash_kexec(regs);
|
crash_kexec(regs);
|
||||||
|
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
raw_spin_unlock_irq(&die_lock);
|
raw_spin_unlock_irq(&die_lock);
|
||||||
oops_exit();
|
oops_exit();
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ void die(const char *str, struct pt_regs *regs, long err)
|
|||||||
show_regs_log_lvl(regs, KERN_EMERG);
|
show_regs_log_lvl(regs, KERN_EMERG);
|
||||||
show_stack_log_lvl(current, regs->sp, regs, KERN_EMERG);
|
show_stack_log_lvl(current, regs->sp, regs, KERN_EMERG);
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
spin_unlock_irq(&die_lock);
|
spin_unlock_irq(&die_lock);
|
||||||
|
|
||||||
if (in_interrupt())
|
if (in_interrupt())
|
||||||
|
@ -225,7 +225,7 @@ int die(const char *str, struct pt_regs *regs, long err)
|
|||||||
do_show_stack(current, ®s->r30, pt_elr(regs));
|
do_show_stack(current, ®s->r30, pt_elr(regs));
|
||||||
|
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
|
|
||||||
spin_unlock_irq(&die.lock);
|
spin_unlock_irq(&die.lock);
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ die (const char *str, struct pt_regs *regs, long err)
|
|||||||
|
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
die.lock_owner = -1;
|
die.lock_owner = -1;
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
spin_unlock_irq(&die.lock);
|
spin_unlock_irq(&die.lock);
|
||||||
|
|
||||||
if (!regs)
|
if (!regs)
|
||||||
|
@ -1176,7 +1176,7 @@ void die_if_kernel (char *str, struct pt_regs *fp, int nr)
|
|||||||
console_verbose();
|
console_verbose();
|
||||||
printk("%s: %08x\n",str,nr);
|
printk("%s: %08x\n",str,nr);
|
||||||
show_registers(fp);
|
show_registers(fp);
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
do_exit(SIGSEGV);
|
do_exit(SIGSEGV);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -396,7 +396,7 @@ void __noreturn die(const char *str, struct pt_regs *regs)
|
|||||||
|
|
||||||
printk("%s[#%d]:\n", str, ++die_counter);
|
printk("%s[#%d]:\n", str, ++die_counter);
|
||||||
show_registers(regs);
|
show_registers(regs);
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
raw_spin_unlock_irq(&die_lock);
|
raw_spin_unlock_irq(&die_lock);
|
||||||
|
|
||||||
oops_exit();
|
oops_exit();
|
||||||
|
@ -282,7 +282,7 @@ void die_if_kernel(char *str, struct pt_regs *regs, long err)
|
|||||||
|
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
dump_stack();
|
dump_stack();
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
|
|
||||||
if (in_interrupt())
|
if (in_interrupt())
|
||||||
panic("Fatal exception in interrupt");
|
panic("Fatal exception in interrupt");
|
||||||
|
@ -146,7 +146,7 @@ static void __kprobes oops_end(unsigned long flags, struct pt_regs *regs,
|
|||||||
{
|
{
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
die_owner = -1;
|
die_owner = -1;
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
die_nest_count--;
|
die_nest_count--;
|
||||||
oops_exit();
|
oops_exit();
|
||||||
printk("\n");
|
printk("\n");
|
||||||
|
@ -271,7 +271,7 @@ void die(struct pt_regs *regs, const char *str)
|
|||||||
print_modules();
|
print_modules();
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
spin_unlock_irq(&die_lock);
|
spin_unlock_irq(&die_lock);
|
||||||
if (in_interrupt())
|
if (in_interrupt())
|
||||||
panic("Fatal exception in interrupt");
|
panic("Fatal exception in interrupt");
|
||||||
|
@ -38,7 +38,7 @@ void die(const char *str, struct pt_regs *regs, long err)
|
|||||||
notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV);
|
notify_die(DIE_OOPS, str, regs, err, 255, SIGSEGV);
|
||||||
|
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
spin_unlock_irq(&die_lock);
|
spin_unlock_irq(&die_lock);
|
||||||
oops_exit();
|
oops_exit();
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ static void __init process_switch(char c)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cheetah_pcache_forced_on = 1;
|
cheetah_pcache_forced_on = 1;
|
||||||
add_taint(TAINT_MACHINE_CHECK);
|
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
|
||||||
cheetah_enable_pcache();
|
cheetah_enable_pcache();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
|
|||||||
|
|
||||||
printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter);
|
printk("%s(%d): %s [#%d]\n", current->comm, task_pid_nr(current), str, ++die_counter);
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
|
|
||||||
__SAVE; __SAVE; __SAVE; __SAVE;
|
__SAVE; __SAVE; __SAVE; __SAVE;
|
||||||
__SAVE; __SAVE; __SAVE; __SAVE;
|
__SAVE; __SAVE; __SAVE; __SAVE;
|
||||||
|
@ -2383,7 +2383,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
|
|||||||
notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV);
|
notify_die(DIE_OOPS, str, regs, 0, 255, SIGSEGV);
|
||||||
__asm__ __volatile__("flushw");
|
__asm__ __volatile__("flushw");
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
if (regs->tstate & TSTATE_PRIV) {
|
if (regs->tstate & TSTATE_PRIV) {
|
||||||
struct thread_info *tp = current_thread_info();
|
struct thread_info *tp = current_thread_info();
|
||||||
struct reg_window *rw = (struct reg_window *)
|
struct reg_window *rw = (struct reg_window *)
|
||||||
|
@ -231,7 +231,7 @@ void die(const char *str, struct pt_regs *regs, int err)
|
|||||||
ret = __die(str, err, thread, regs);
|
ret = __die(str, err, thread, regs);
|
||||||
|
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
spin_unlock_irq(&die_lock);
|
spin_unlock_irq(&die_lock);
|
||||||
oops_exit();
|
oops_exit();
|
||||||
|
|
||||||
|
@ -219,8 +219,7 @@ static void __cpuinit amd_k7_smp_check(struct cpuinfo_x86 *c)
|
|||||||
*/
|
*/
|
||||||
WARN_ONCE(1, "WARNING: This combination of AMD"
|
WARN_ONCE(1, "WARNING: This combination of AMD"
|
||||||
" processors is not suitable for SMP.\n");
|
" processors is not suitable for SMP.\n");
|
||||||
if (!test_taint(TAINT_UNSAFE_SMP))
|
add_taint(TAINT_UNSAFE_SMP, LOCKDEP_NOW_UNRELIABLE);
|
||||||
add_taint(TAINT_UNSAFE_SMP);
|
|
||||||
|
|
||||||
valid_k7:
|
valid_k7:
|
||||||
;
|
;
|
||||||
|
@ -1082,7 +1082,7 @@ void do_machine_check(struct pt_regs *regs, long error_code)
|
|||||||
/*
|
/*
|
||||||
* Set taint even when machine check was not enabled.
|
* Set taint even when machine check was not enabled.
|
||||||
*/
|
*/
|
||||||
add_taint(TAINT_MACHINE_CHECK);
|
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
|
||||||
|
|
||||||
severity = mce_severity(&m, cfg->tolerant, NULL);
|
severity = mce_severity(&m, cfg->tolerant, NULL);
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ static void pentium_machine_check(struct pt_regs *regs, long error_code)
|
|||||||
smp_processor_id());
|
smp_processor_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
add_taint(TAINT_MACHINE_CHECK);
|
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up machine check reporting for processors with Intel style MCE: */
|
/* Set up machine check reporting for processors with Intel style MCE: */
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
static void winchip_machine_check(struct pt_regs *regs, long error_code)
|
static void winchip_machine_check(struct pt_regs *regs, long error_code)
|
||||||
{
|
{
|
||||||
printk(KERN_EMERG "CPU0: Machine Check Exception.\n");
|
printk(KERN_EMERG "CPU0: Machine Check Exception.\n");
|
||||||
add_taint(TAINT_MACHINE_CHECK);
|
add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set up machine check reporting on the Winchip C6 series */
|
/* Set up machine check reporting on the Winchip C6 series */
|
||||||
|
@ -542,7 +542,7 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
|
|||||||
|
|
||||||
if (tmp != mask_lo) {
|
if (tmp != mask_lo) {
|
||||||
printk(KERN_WARNING "mtrr: your BIOS has configured an incorrect mask, fixing it.\n");
|
printk(KERN_WARNING "mtrr: your BIOS has configured an incorrect mask, fixing it.\n");
|
||||||
add_taint(TAINT_FIRMWARE_WORKAROUND);
|
add_taint(TAINT_FIRMWARE_WORKAROUND, LOCKDEP_STILL_OK);
|
||||||
mask_lo = tmp;
|
mask_lo = tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr)
|
|||||||
|
|
||||||
bust_spinlocks(0);
|
bust_spinlocks(0);
|
||||||
die_owner = -1;
|
die_owner = -1;
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
die_nest_count--;
|
die_nest_count--;
|
||||||
if (!die_nest_count)
|
if (!die_nest_count)
|
||||||
/* Nest count reaches zero, release the lock. */
|
/* Nest count reaches zero, release the lock. */
|
||||||
|
@ -524,7 +524,7 @@ void die(const char * str, struct pt_regs * regs, long err)
|
|||||||
if (!user_mode(regs))
|
if (!user_mode(regs))
|
||||||
show_stack(NULL, (unsigned long*)regs->areg[1]);
|
show_stack(NULL, (unsigned long*)regs->areg[1]);
|
||||||
|
|
||||||
add_taint(TAINT_DIE);
|
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
spin_unlock_irq(&die_lock);
|
spin_unlock_irq(&die_lock);
|
||||||
|
|
||||||
if (in_interrupt())
|
if (in_interrupt())
|
||||||
|
@ -66,7 +66,7 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf,
|
|||||||
buf = NULL;
|
buf = NULL;
|
||||||
if (ACPI_FAILURE(status))
|
if (ACPI_FAILURE(status))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
|
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
@ -661,7 +661,7 @@ static void acpi_table_taint(struct acpi_table_header *table)
|
|||||||
pr_warn(PREFIX
|
pr_warn(PREFIX
|
||||||
"Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n",
|
"Override [%4.4s-%8.8s], this is unsafe: tainting kernel\n",
|
||||||
table->signature, table->oem_table_id);
|
table->signature, table->oem_table_id);
|
||||||
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE);
|
add_taint(TAINT_OVERRIDDEN_ACPI_TABLE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -279,7 +279,7 @@ static ssize_t regmap_map_write_file(struct file *file,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Userspace has been fiddling around behind the kernel's back */
|
/* Userspace has been fiddling around behind the kernel's back */
|
||||||
add_taint(TAINT_USER);
|
add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE);
|
||||||
|
|
||||||
regmap_write(map, reg, value);
|
regmap_write(map, reg, value);
|
||||||
return buf_size;
|
return buf_size;
|
||||||
|
@ -398,7 +398,11 @@ extern int panic_on_unrecovered_nmi;
|
|||||||
extern int panic_on_io_nmi;
|
extern int panic_on_io_nmi;
|
||||||
extern int sysctl_panic_on_stackoverflow;
|
extern int sysctl_panic_on_stackoverflow;
|
||||||
extern const char *print_tainted(void);
|
extern const char *print_tainted(void);
|
||||||
extern void add_taint(unsigned flag);
|
enum lockdep_ok {
|
||||||
|
LOCKDEP_STILL_OK,
|
||||||
|
LOCKDEP_NOW_UNRELIABLE
|
||||||
|
};
|
||||||
|
extern void add_taint(unsigned flag, enum lockdep_ok);
|
||||||
extern int test_taint(unsigned flag);
|
extern int test_taint(unsigned flag);
|
||||||
extern unsigned long get_taint(void);
|
extern unsigned long get_taint(void);
|
||||||
extern int root_mountflags;
|
extern int root_mountflags;
|
||||||
|
@ -396,13 +396,13 @@ bool is_module_address(unsigned long addr);
|
|||||||
bool is_module_percpu_address(unsigned long addr);
|
bool is_module_percpu_address(unsigned long addr);
|
||||||
bool is_module_text_address(unsigned long addr);
|
bool is_module_text_address(unsigned long addr);
|
||||||
|
|
||||||
static inline int within_module_core(unsigned long addr, struct module *mod)
|
static inline int within_module_core(unsigned long addr, const struct module *mod)
|
||||||
{
|
{
|
||||||
return (unsigned long)mod->module_core <= addr &&
|
return (unsigned long)mod->module_core <= addr &&
|
||||||
addr < (unsigned long)mod->module_core + mod->core_size;
|
addr < (unsigned long)mod->module_core + mod->core_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int within_module_init(unsigned long addr, struct module *mod)
|
static inline int within_module_init(unsigned long addr, const struct module *mod)
|
||||||
{
|
{
|
||||||
return (unsigned long)mod->module_init <= addr &&
|
return (unsigned long)mod->module_init <= addr &&
|
||||||
addr < (unsigned long)mod->module_init + mod->init_size;
|
addr < (unsigned long)mod->module_init + mod->init_size;
|
||||||
|
20
init/Kconfig
20
init/Kconfig
@ -1670,6 +1670,17 @@ config MODULE_SIG_FORCE
|
|||||||
Reject unsigned modules or signed modules for which we don't have a
|
Reject unsigned modules or signed modules for which we don't have a
|
||||||
key. Without this, such modules will simply taint the kernel.
|
key. Without this, such modules will simply taint the kernel.
|
||||||
|
|
||||||
|
config MODULE_SIG_ALL
|
||||||
|
bool "Automatically sign all modules"
|
||||||
|
default y
|
||||||
|
depends on MODULE_SIG
|
||||||
|
help
|
||||||
|
Sign all modules during make modules_install. Without this option,
|
||||||
|
modules must be signed manually, using the scripts/sign-file tool.
|
||||||
|
|
||||||
|
comment "Do not forget to sign required modules with scripts/sign-file"
|
||||||
|
depends on MODULE_SIG_FORCE && !MODULE_SIG_ALL
|
||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "Which hash algorithm should modules be signed with?"
|
prompt "Which hash algorithm should modules be signed with?"
|
||||||
depends on MODULE_SIG
|
depends on MODULE_SIG
|
||||||
@ -1702,6 +1713,15 @@ config MODULE_SIG_SHA512
|
|||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
config MODULE_SIG_HASH
|
||||||
|
string
|
||||||
|
depends on MODULE_SIG
|
||||||
|
default "sha1" if MODULE_SIG_SHA1
|
||||||
|
default "sha224" if MODULE_SIG_SHA224
|
||||||
|
default "sha256" if MODULE_SIG_SHA256
|
||||||
|
default "sha384" if MODULE_SIG_SHA384
|
||||||
|
default "sha512" if MODULE_SIG_SHA512
|
||||||
|
|
||||||
endif # MODULES
|
endif # MODULES
|
||||||
|
|
||||||
config INIT_ALL_POSSIBLE
|
config INIT_ALL_POSSIBLE
|
||||||
|
@ -153,23 +153,7 @@ kernel/modsign_certificate.o: signing_key.x509 extra_certificates
|
|||||||
# fail and that the kernel may be used afterwards.
|
# fail and that the kernel may be used afterwards.
|
||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
sign_key_with_hash :=
|
ifndef CONFIG_MODULE_SIG_HASH
|
||||||
ifeq ($(CONFIG_MODULE_SIG_SHA1),y)
|
|
||||||
sign_key_with_hash := -sha1
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_MODULE_SIG_SHA224),y)
|
|
||||||
sign_key_with_hash := -sha224
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_MODULE_SIG_SHA256),y)
|
|
||||||
sign_key_with_hash := -sha256
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_MODULE_SIG_SHA384),y)
|
|
||||||
sign_key_with_hash := -sha384
|
|
||||||
endif
|
|
||||||
ifeq ($(CONFIG_MODULE_SIG_SHA512),y)
|
|
||||||
sign_key_with_hash := -sha512
|
|
||||||
endif
|
|
||||||
ifeq ($(sign_key_with_hash),)
|
|
||||||
$(error Could not determine digest type to use from kernel config)
|
$(error Could not determine digest type to use from kernel config)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -182,8 +166,8 @@ signing_key.priv signing_key.x509: x509.genkey
|
|||||||
@echo "### needs to be run as root, and uses a hardware random"
|
@echo "### needs to be run as root, and uses a hardware random"
|
||||||
@echo "### number generator if one is available."
|
@echo "### number generator if one is available."
|
||||||
@echo "###"
|
@echo "###"
|
||||||
openssl req -new -nodes -utf8 $(sign_key_with_hash) -days 36500 -batch \
|
openssl req -new -nodes -utf8 -$(CONFIG_MODULE_SIG_HASH) -days 36500 \
|
||||||
-x509 -config x509.genkey \
|
-batch -x509 -config x509.genkey \
|
||||||
-outform DER -out signing_key.x509 \
|
-outform DER -out signing_key.x509 \
|
||||||
-keyout signing_key.priv
|
-keyout signing_key.priv
|
||||||
@echo "###"
|
@echo "###"
|
||||||
|
138
kernel/module.c
138
kernel/module.c
@ -197,9 +197,10 @@ static inline int strong_try_module_get(struct module *mod)
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void add_taint_module(struct module *mod, unsigned flag)
|
static inline void add_taint_module(struct module *mod, unsigned flag,
|
||||||
|
enum lockdep_ok lockdep_ok)
|
||||||
{
|
{
|
||||||
add_taint(flag);
|
add_taint(flag, lockdep_ok);
|
||||||
mod->taints |= (1U << flag);
|
mod->taints |= (1U << flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,7 +728,7 @@ static inline int try_force_unload(unsigned int flags)
|
|||||||
{
|
{
|
||||||
int ret = (flags & O_TRUNC);
|
int ret = (flags & O_TRUNC);
|
||||||
if (ret)
|
if (ret)
|
||||||
add_taint(TAINT_FORCED_RMMOD);
|
add_taint(TAINT_FORCED_RMMOD, LOCKDEP_NOW_UNRELIABLE);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@ -1138,7 +1139,7 @@ static int try_to_force_load(struct module *mod, const char *reason)
|
|||||||
if (!test_taint(TAINT_FORCED_MODULE))
|
if (!test_taint(TAINT_FORCED_MODULE))
|
||||||
printk(KERN_WARNING "%s: %s: kernel tainted.\n",
|
printk(KERN_WARNING "%s: %s: kernel tainted.\n",
|
||||||
mod->name, reason);
|
mod->name, reason);
|
||||||
add_taint_module(mod, TAINT_FORCED_MODULE);
|
add_taint_module(mod, TAINT_FORCED_MODULE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
#else
|
||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
@ -2147,7 +2148,8 @@ static void set_license(struct module *mod, const char *license)
|
|||||||
if (!test_taint(TAINT_PROPRIETARY_MODULE))
|
if (!test_taint(TAINT_PROPRIETARY_MODULE))
|
||||||
printk(KERN_WARNING "%s: module license '%s' taints "
|
printk(KERN_WARNING "%s: module license '%s' taints "
|
||||||
"kernel.\n", mod->name, license);
|
"kernel.\n", mod->name, license);
|
||||||
add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
|
add_taint_module(mod, TAINT_PROPRIETARY_MODULE,
|
||||||
|
LOCKDEP_NOW_UNRELIABLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2700,10 +2702,10 @@ static int check_modinfo(struct module *mod, struct load_info *info, int flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!get_modinfo(info, "intree"))
|
if (!get_modinfo(info, "intree"))
|
||||||
add_taint_module(mod, TAINT_OOT_MODULE);
|
add_taint_module(mod, TAINT_OOT_MODULE, LOCKDEP_STILL_OK);
|
||||||
|
|
||||||
if (get_modinfo(info, "staging")) {
|
if (get_modinfo(info, "staging")) {
|
||||||
add_taint_module(mod, TAINT_CRAP);
|
add_taint_module(mod, TAINT_CRAP, LOCKDEP_STILL_OK);
|
||||||
printk(KERN_WARNING "%s: module is from the staging directory,"
|
printk(KERN_WARNING "%s: module is from the staging directory,"
|
||||||
" the quality is unknown, you have been warned.\n",
|
" the quality is unknown, you have been warned.\n",
|
||||||
mod->name);
|
mod->name);
|
||||||
@ -2869,15 +2871,17 @@ static int check_module_license_and_versions(struct module *mod)
|
|||||||
* using GPL-only symbols it needs.
|
* using GPL-only symbols it needs.
|
||||||
*/
|
*/
|
||||||
if (strcmp(mod->name, "ndiswrapper") == 0)
|
if (strcmp(mod->name, "ndiswrapper") == 0)
|
||||||
add_taint(TAINT_PROPRIETARY_MODULE);
|
add_taint(TAINT_PROPRIETARY_MODULE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
|
|
||||||
/* driverloader was caught wrongly pretending to be under GPL */
|
/* driverloader was caught wrongly pretending to be under GPL */
|
||||||
if (strcmp(mod->name, "driverloader") == 0)
|
if (strcmp(mod->name, "driverloader") == 0)
|
||||||
add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
|
add_taint_module(mod, TAINT_PROPRIETARY_MODULE,
|
||||||
|
LOCKDEP_NOW_UNRELIABLE);
|
||||||
|
|
||||||
/* lve claims to be GPL but upstream won't provide source */
|
/* lve claims to be GPL but upstream won't provide source */
|
||||||
if (strcmp(mod->name, "lve") == 0)
|
if (strcmp(mod->name, "lve") == 0)
|
||||||
add_taint_module(mod, TAINT_PROPRIETARY_MODULE);
|
add_taint_module(mod, TAINT_PROPRIETARY_MODULE,
|
||||||
|
LOCKDEP_NOW_UNRELIABLE);
|
||||||
|
|
||||||
#ifdef CONFIG_MODVERSIONS
|
#ifdef CONFIG_MODVERSIONS
|
||||||
if ((mod->num_syms && !mod->crcs)
|
if ((mod->num_syms && !mod->crcs)
|
||||||
@ -3141,12 +3145,72 @@ static int may_init_module(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We try to place it in the list now to make sure it's unique before
|
||||||
|
* we dedicate too many resources. In particular, temporary percpu
|
||||||
|
* memory exhaustion.
|
||||||
|
*/
|
||||||
|
static int add_unformed_module(struct module *mod)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct module *old;
|
||||||
|
|
||||||
|
mod->state = MODULE_STATE_UNFORMED;
|
||||||
|
|
||||||
|
again:
|
||||||
|
mutex_lock(&module_mutex);
|
||||||
|
if ((old = find_module_all(mod->name, true)) != NULL) {
|
||||||
|
if (old->state == MODULE_STATE_COMING
|
||||||
|
|| old->state == MODULE_STATE_UNFORMED) {
|
||||||
|
/* Wait in case it fails to load. */
|
||||||
|
mutex_unlock(&module_mutex);
|
||||||
|
err = wait_event_interruptible(module_wq,
|
||||||
|
finished_loading(mod->name));
|
||||||
|
if (err)
|
||||||
|
goto out_unlocked;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
err = -EEXIST;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
list_add_rcu(&mod->list, &modules);
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
out:
|
||||||
|
mutex_unlock(&module_mutex);
|
||||||
|
out_unlocked:
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int complete_formation(struct module *mod, struct load_info *info)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
mutex_lock(&module_mutex);
|
||||||
|
|
||||||
|
/* Find duplicate symbols (must be called under lock). */
|
||||||
|
err = verify_export_symbols(mod);
|
||||||
|
if (err < 0)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* This relies on module_mutex for list integrity. */
|
||||||
|
module_bug_finalize(info->hdr, info->sechdrs, mod);
|
||||||
|
|
||||||
|
/* Mark state as coming so strong_try_module_get() ignores us,
|
||||||
|
* but kallsyms etc. can see us. */
|
||||||
|
mod->state = MODULE_STATE_COMING;
|
||||||
|
|
||||||
|
out:
|
||||||
|
mutex_unlock(&module_mutex);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate and load the module: note that size of section 0 is always
|
/* Allocate and load the module: note that size of section 0 is always
|
||||||
zero, and we rely on this for optional sections. */
|
zero, and we rely on this for optional sections. */
|
||||||
static int load_module(struct load_info *info, const char __user *uargs,
|
static int load_module(struct load_info *info, const char __user *uargs,
|
||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
struct module *mod, *old;
|
struct module *mod;
|
||||||
long err;
|
long err;
|
||||||
|
|
||||||
err = module_sig_check(info);
|
err = module_sig_check(info);
|
||||||
@ -3164,36 +3228,20 @@ static int load_module(struct load_info *info, const char __user *uargs,
|
|||||||
goto free_copy;
|
goto free_copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Reserve our place in the list. */
|
||||||
* We try to place it in the list now to make sure it's unique
|
err = add_unformed_module(mod);
|
||||||
* before we dedicate too many resources. In particular,
|
|
||||||
* temporary percpu memory exhaustion.
|
|
||||||
*/
|
|
||||||
mod->state = MODULE_STATE_UNFORMED;
|
|
||||||
again:
|
|
||||||
mutex_lock(&module_mutex);
|
|
||||||
if ((old = find_module_all(mod->name, true)) != NULL) {
|
|
||||||
if (old->state == MODULE_STATE_COMING
|
|
||||||
|| old->state == MODULE_STATE_UNFORMED) {
|
|
||||||
/* Wait in case it fails to load. */
|
|
||||||
mutex_unlock(&module_mutex);
|
|
||||||
err = wait_event_interruptible(module_wq,
|
|
||||||
finished_loading(mod->name));
|
|
||||||
if (err)
|
if (err)
|
||||||
goto free_module;
|
goto free_module;
|
||||||
goto again;
|
|
||||||
}
|
|
||||||
err = -EEXIST;
|
|
||||||
mutex_unlock(&module_mutex);
|
|
||||||
goto free_module;
|
|
||||||
}
|
|
||||||
list_add_rcu(&mod->list, &modules);
|
|
||||||
mutex_unlock(&module_mutex);
|
|
||||||
|
|
||||||
#ifdef CONFIG_MODULE_SIG
|
#ifdef CONFIG_MODULE_SIG
|
||||||
mod->sig_ok = info->sig_ok;
|
mod->sig_ok = info->sig_ok;
|
||||||
if (!mod->sig_ok)
|
if (!mod->sig_ok) {
|
||||||
add_taint_module(mod, TAINT_FORCED_MODULE);
|
printk_once(KERN_NOTICE
|
||||||
|
"%s: module verification failed: signature and/or"
|
||||||
|
" required key missing - tainting kernel\n",
|
||||||
|
mod->name);
|
||||||
|
add_taint_module(mod, TAINT_FORCED_MODULE, LOCKDEP_STILL_OK);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Now module is in final location, initialize linked lists, etc. */
|
/* Now module is in final location, initialize linked lists, etc. */
|
||||||
@ -3236,21 +3284,11 @@ again:
|
|||||||
|
|
||||||
dynamic_debug_setup(info->debug, info->num_debug);
|
dynamic_debug_setup(info->debug, info->num_debug);
|
||||||
|
|
||||||
mutex_lock(&module_mutex);
|
/* Finally it's fully formed, ready to start executing. */
|
||||||
/* Find duplicate symbols (must be called under lock). */
|
err = complete_formation(mod, info);
|
||||||
err = verify_export_symbols(mod);
|
if (err)
|
||||||
if (err < 0)
|
|
||||||
goto ddebug_cleanup;
|
goto ddebug_cleanup;
|
||||||
|
|
||||||
/* This relies on module_mutex for list integrity. */
|
|
||||||
module_bug_finalize(info->hdr, info->sechdrs, mod);
|
|
||||||
|
|
||||||
/* Mark state as coming so strong_try_module_get() ignores us,
|
|
||||||
* but kallsyms etc. can see us. */
|
|
||||||
mod->state = MODULE_STATE_COMING;
|
|
||||||
|
|
||||||
mutex_unlock(&module_mutex);
|
|
||||||
|
|
||||||
/* Module is ready to execute: parsing args may do that. */
|
/* Module is ready to execute: parsing args may do that. */
|
||||||
err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
|
err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
|
||||||
-32768, 32767, &ddebug_dyndbg_module_param_cb);
|
-32768, 32767, &ddebug_dyndbg_module_param_cb);
|
||||||
@ -3274,8 +3312,8 @@ again:
|
|||||||
/* module_bug_cleanup needs module_mutex protection */
|
/* module_bug_cleanup needs module_mutex protection */
|
||||||
mutex_lock(&module_mutex);
|
mutex_lock(&module_mutex);
|
||||||
module_bug_cleanup(mod);
|
module_bug_cleanup(mod);
|
||||||
ddebug_cleanup:
|
|
||||||
mutex_unlock(&module_mutex);
|
mutex_unlock(&module_mutex);
|
||||||
|
ddebug_cleanup:
|
||||||
dynamic_debug_remove(info->debug);
|
dynamic_debug_remove(info->debug);
|
||||||
synchronize_sched();
|
synchronize_sched();
|
||||||
kfree(mod->args);
|
kfree(mod->args);
|
||||||
|
@ -259,26 +259,19 @@ unsigned long get_taint(void)
|
|||||||
return tainted_mask;
|
return tainted_mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_taint(unsigned flag)
|
/**
|
||||||
{
|
* add_taint: add a taint flag if not already set.
|
||||||
/*
|
* @flag: one of the TAINT_* constants.
|
||||||
* Can't trust the integrity of the kernel anymore.
|
* @lockdep_ok: whether lock debugging is still OK.
|
||||||
* We don't call directly debug_locks_off() because the issue
|
*
|
||||||
* is not necessarily serious enough to set oops_in_progress to 1
|
* If something bad has gone wrong, you'll want @lockdebug_ok = false, but for
|
||||||
* Also we want to keep up lockdep for staging/out-of-tree
|
* some notewortht-but-not-corrupting cases, it can be set to true.
|
||||||
* development and post-warning case.
|
|
||||||
*/
|
*/
|
||||||
switch (flag) {
|
void add_taint(unsigned flag, enum lockdep_ok lockdep_ok)
|
||||||
case TAINT_CRAP:
|
{
|
||||||
case TAINT_OOT_MODULE:
|
if (lockdep_ok == LOCKDEP_NOW_UNRELIABLE && __debug_locks_off())
|
||||||
case TAINT_WARN:
|
printk(KERN_WARNING
|
||||||
case TAINT_FIRMWARE_WORKAROUND:
|
"Disabling lock debugging due to kernel taint\n");
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (__debug_locks_off())
|
|
||||||
printk(KERN_WARNING "Disabling lock debugging due to kernel taint\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
set_bit(flag, &tainted_mask);
|
set_bit(flag, &tainted_mask);
|
||||||
}
|
}
|
||||||
@ -421,7 +414,8 @@ static void warn_slowpath_common(const char *file, int line, void *caller,
|
|||||||
print_modules();
|
print_modules();
|
||||||
dump_stack();
|
dump_stack();
|
||||||
print_oops_end_marker();
|
print_oops_end_marker();
|
||||||
add_taint(taint);
|
/* Just a warning, don't kill lockdep. */
|
||||||
|
add_taint(taint, LOCKDEP_STILL_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...)
|
void warn_slowpath_fmt(const char *file, int line, const char *fmt, ...)
|
||||||
|
@ -2796,7 +2796,7 @@ static noinline void __schedule_bug(struct task_struct *prev)
|
|||||||
if (irqs_disabled())
|
if (irqs_disabled())
|
||||||
print_irqtrace_events(prev);
|
print_irqtrace_events(prev);
|
||||||
dump_stack();
|
dump_stack();
|
||||||
add_taint(TAINT_WARN);
|
add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2018,7 +2018,7 @@ static int proc_taint(struct ctl_table *table, int write,
|
|||||||
int i;
|
int i;
|
||||||
for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) {
|
for (i = 0; i < BITS_PER_LONG && tmptaint >> i; i++) {
|
||||||
if ((tmptaint >> i) & 1)
|
if ((tmptaint >> i) & 1)
|
||||||
add_taint(i);
|
add_taint(i, LOCKDEP_STILL_OK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +166,8 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
|
|||||||
print_modules();
|
print_modules();
|
||||||
show_regs(regs);
|
show_regs(regs);
|
||||||
print_oops_end_marker();
|
print_oops_end_marker();
|
||||||
add_taint(BUG_GET_TAINT(bug));
|
/* Just a warning, don't kill lockdep. */
|
||||||
|
add_taint(BUG_GET_TAINT(bug), LOCKDEP_STILL_OK);
|
||||||
return BUG_TRAP_TYPE_WARN;
|
return BUG_TRAP_TYPE_WARN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -720,7 +720,7 @@ static void print_bad_pte(struct vm_area_struct *vma, unsigned long addr,
|
|||||||
print_symbol(KERN_ALERT "vma->vm_file->f_op->mmap: %s\n",
|
print_symbol(KERN_ALERT "vma->vm_file->f_op->mmap: %s\n",
|
||||||
(unsigned long)vma->vm_file->f_op->mmap);
|
(unsigned long)vma->vm_file->f_op->mmap);
|
||||||
dump_stack();
|
dump_stack();
|
||||||
add_taint(TAINT_BAD_PAGE);
|
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_cow_mapping(vm_flags_t flags)
|
static inline bool is_cow_mapping(vm_flags_t flags)
|
||||||
|
@ -333,7 +333,7 @@ static void bad_page(struct page *page)
|
|||||||
out:
|
out:
|
||||||
/* Leave bad fields for debug, except PageBuddy could make trouble */
|
/* Leave bad fields for debug, except PageBuddy could make trouble */
|
||||||
page_mapcount_reset(page); /* remove PageBuddy */
|
page_mapcount_reset(page); /* remove PageBuddy */
|
||||||
add_taint(TAINT_BAD_PAGE);
|
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -812,7 +812,7 @@ static void __slab_error(const char *function, struct kmem_cache *cachep,
|
|||||||
printk(KERN_ERR "slab error in %s(): cache `%s': %s\n",
|
printk(KERN_ERR "slab error in %s(): cache `%s': %s\n",
|
||||||
function, cachep->name, msg);
|
function, cachep->name, msg);
|
||||||
dump_stack();
|
dump_stack();
|
||||||
add_taint(TAINT_BAD_PAGE);
|
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -562,7 +562,7 @@ static void slab_bug(struct kmem_cache *s, char *fmt, ...)
|
|||||||
printk(KERN_ERR "----------------------------------------"
|
printk(KERN_ERR "----------------------------------------"
|
||||||
"-------------------------------------\n\n");
|
"-------------------------------------\n\n");
|
||||||
|
|
||||||
add_taint(TAINT_BAD_PAGE);
|
add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void slab_fix(struct kmem_cache *s, char *fmt, ...)
|
static void slab_fix(struct kmem_cache *s, char *fmt, ...)
|
||||||
|
@ -830,6 +830,8 @@ static const char *section_white_list[] =
|
|||||||
".toc*",
|
".toc*",
|
||||||
".xt.prop", /* xtensa */
|
".xt.prop", /* xtensa */
|
||||||
".xt.lit", /* xtensa */
|
".xt.lit", /* xtensa */
|
||||||
|
".arcextmap*", /* arc */
|
||||||
|
".gnu.linkonce.arcext*", /* arc : modules */
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,50 +2,44 @@
|
|||||||
#
|
#
|
||||||
# Sign a module file using the given key.
|
# Sign a module file using the given key.
|
||||||
#
|
#
|
||||||
# Format:
|
|
||||||
#
|
my $USAGE =
|
||||||
# ./scripts/sign-file [-v] <key> <x509> <module> [<dest>]
|
"Usage: scripts/sign-file [-v] <hash algo> <key> <x509> <module> [<dest>]\n" .
|
||||||
#
|
" scripts/sign-file [-v] -s <raw sig> <hash algo> <x509> <module> [<dest>]\n";
|
||||||
#
|
|
||||||
use strict;
|
use strict;
|
||||||
use FileHandle;
|
use FileHandle;
|
||||||
use IPC::Open2;
|
use IPC::Open2;
|
||||||
|
use Getopt::Std;
|
||||||
|
|
||||||
my $verbose = 0;
|
my %opts;
|
||||||
if ($#ARGV >= 0 && $ARGV[0] eq "-v") {
|
getopts('vs:', \%opts) or die $USAGE;
|
||||||
$verbose = 1;
|
my $verbose = $opts{'v'};
|
||||||
shift;
|
my $signature_file = $opts{'s'};
|
||||||
|
|
||||||
|
die $USAGE if ($#ARGV > 4);
|
||||||
|
die $USAGE if (!$signature_file && $#ARGV < 3 || $signature_file && $#ARGV < 2);
|
||||||
|
|
||||||
|
my $dgst = shift @ARGV;
|
||||||
|
my $private_key;
|
||||||
|
if (!$signature_file) {
|
||||||
|
$private_key = shift @ARGV;
|
||||||
|
}
|
||||||
|
my $x509 = shift @ARGV;
|
||||||
|
my $module = shift @ARGV;
|
||||||
|
my ($dest, $keep_orig);
|
||||||
|
if (@ARGV) {
|
||||||
|
$dest = $ARGV[0];
|
||||||
|
$keep_orig = 1;
|
||||||
|
} else {
|
||||||
|
$dest = $module . "~";
|
||||||
}
|
}
|
||||||
|
|
||||||
die "Format: ./scripts/sign-file [-v] <key> <x509> <module> [<dest>]\n"
|
die "Can't read private key\n" if (!$signature_file && !-r $private_key);
|
||||||
if ($#ARGV != 2 && $#ARGV != 3);
|
die "Can't read signature file\n" if ($signature_file && !-r $signature_file);
|
||||||
|
|
||||||
my $private_key = $ARGV[0];
|
|
||||||
my $x509 = $ARGV[1];
|
|
||||||
my $module = $ARGV[2];
|
|
||||||
my $dest = ($#ARGV == 3) ? $ARGV[3] : $ARGV[2] . "~";
|
|
||||||
|
|
||||||
die "Can't read private key\n" unless (-r $private_key);
|
|
||||||
die "Can't read X.509 certificate\n" unless (-r $x509);
|
die "Can't read X.509 certificate\n" unless (-r $x509);
|
||||||
die "Can't read module\n" unless (-r $module);
|
die "Can't read module\n" unless (-r $module);
|
||||||
|
|
||||||
#
|
|
||||||
# Read the kernel configuration
|
|
||||||
#
|
|
||||||
my %config = (
|
|
||||||
CONFIG_MODULE_SIG_SHA512 => 1
|
|
||||||
);
|
|
||||||
|
|
||||||
if (-r ".config") {
|
|
||||||
open(FD, "<.config") || die ".config";
|
|
||||||
while (<FD>) {
|
|
||||||
if ($_ =~ /^(CONFIG_.*)=[ym]/) {
|
|
||||||
$config{$1} = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
close(FD);
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Function to read the contents of a file into a variable.
|
# Function to read the contents of a file into a variable.
|
||||||
#
|
#
|
||||||
@ -321,55 +315,54 @@ my $id_type = 1; # Identifier type: X.509
|
|||||||
#
|
#
|
||||||
# Digest the data
|
# Digest the data
|
||||||
#
|
#
|
||||||
my ($dgst, $prologue) = ();
|
my $prologue;
|
||||||
if (exists $config{"CONFIG_MODULE_SIG_SHA1"}) {
|
if ($dgst eq "sha1") {
|
||||||
$prologue = pack("C*",
|
$prologue = pack("C*",
|
||||||
0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
|
0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
|
||||||
0x2B, 0x0E, 0x03, 0x02, 0x1A,
|
0x2B, 0x0E, 0x03, 0x02, 0x1A,
|
||||||
0x05, 0x00, 0x04, 0x14);
|
0x05, 0x00, 0x04, 0x14);
|
||||||
$dgst = "-sha1";
|
|
||||||
$hash = 2;
|
$hash = 2;
|
||||||
} elsif (exists $config{"CONFIG_MODULE_SIG_SHA224"}) {
|
} elsif ($dgst eq "sha224") {
|
||||||
$prologue = pack("C*",
|
$prologue = pack("C*",
|
||||||
0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
|
0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
|
||||||
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
|
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
|
||||||
0x05, 0x00, 0x04, 0x1C);
|
0x05, 0x00, 0x04, 0x1C);
|
||||||
$dgst = "-sha224";
|
|
||||||
$hash = 7;
|
$hash = 7;
|
||||||
} elsif (exists $config{"CONFIG_MODULE_SIG_SHA256"}) {
|
} elsif ($dgst eq "sha256") {
|
||||||
$prologue = pack("C*",
|
$prologue = pack("C*",
|
||||||
0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
|
0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
|
||||||
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
|
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
|
||||||
0x05, 0x00, 0x04, 0x20);
|
0x05, 0x00, 0x04, 0x20);
|
||||||
$dgst = "-sha256";
|
|
||||||
$hash = 4;
|
$hash = 4;
|
||||||
} elsif (exists $config{"CONFIG_MODULE_SIG_SHA384"}) {
|
} elsif ($dgst eq "sha384") {
|
||||||
$prologue = pack("C*",
|
$prologue = pack("C*",
|
||||||
0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
|
0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
|
||||||
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
|
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
|
||||||
0x05, 0x00, 0x04, 0x30);
|
0x05, 0x00, 0x04, 0x30);
|
||||||
$dgst = "-sha384";
|
|
||||||
$hash = 5;
|
$hash = 5;
|
||||||
} elsif (exists $config{"CONFIG_MODULE_SIG_SHA512"}) {
|
} elsif ($dgst eq "sha512") {
|
||||||
$prologue = pack("C*",
|
$prologue = pack("C*",
|
||||||
0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
|
0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
|
||||||
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
|
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
|
||||||
0x05, 0x00, 0x04, 0x40);
|
0x05, 0x00, 0x04, 0x40);
|
||||||
$dgst = "-sha512";
|
|
||||||
$hash = 6;
|
$hash = 6;
|
||||||
} else {
|
} else {
|
||||||
die "Can't determine hash algorithm";
|
die "Unknown hash algorithm: $dgst\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $signature;
|
||||||
|
if ($signature_file) {
|
||||||
|
$signature = read_file($signature_file);
|
||||||
|
} else {
|
||||||
#
|
#
|
||||||
# Generate the digest and read from openssl's stdout
|
# Generate the digest and read from openssl's stdout
|
||||||
#
|
#
|
||||||
my $digest;
|
my $digest;
|
||||||
$digest = readpipe("openssl dgst $dgst -binary $module") || die "openssl dgst";
|
$digest = readpipe("openssl dgst -$dgst -binary $module") || die "openssl dgst";
|
||||||
|
|
||||||
#
|
#
|
||||||
# Generate the binary signature, which will be just the integer that comprises
|
# Generate the binary signature, which will be just the integer that
|
||||||
# the signature with no metadata attached.
|
# comprises the signature with no metadata attached.
|
||||||
#
|
#
|
||||||
my $pid;
|
my $pid;
|
||||||
$pid = open2(*read_from, *write_to,
|
$pid = open2(*read_from, *write_to,
|
||||||
@ -380,13 +373,12 @@ print write_to $prologue . $digest || die "pipe to openssl rsautl";
|
|||||||
close(write_to) || die "pipe to openssl rsautl";
|
close(write_to) || die "pipe to openssl rsautl";
|
||||||
|
|
||||||
binmode read_from;
|
binmode read_from;
|
||||||
my $signature;
|
|
||||||
read(read_from, $signature, 4096) || die "pipe from openssl rsautl";
|
read(read_from, $signature, 4096) || die "pipe from openssl rsautl";
|
||||||
close(read_from) || die "pipe from openssl rsautl";
|
close(read_from) || die "pipe from openssl rsautl";
|
||||||
$signature = pack("n", length($signature)) . $signature,
|
|
||||||
|
|
||||||
waitpid($pid, 0) || die;
|
waitpid($pid, 0) || die;
|
||||||
die "openssl rsautl died: $?" if ($? >> 8);
|
die "openssl rsautl died: $?" if ($? >> 8);
|
||||||
|
}
|
||||||
|
$signature = pack("n", length($signature)) . $signature,
|
||||||
|
|
||||||
#
|
#
|
||||||
# Build the signed binary
|
# Build the signed binary
|
||||||
@ -424,6 +416,6 @@ print FD
|
|||||||
;
|
;
|
||||||
close FD || die $dest;
|
close FD || die $dest;
|
||||||
|
|
||||||
if ($#ARGV != 3) {
|
if (!$keep_orig) {
|
||||||
rename($dest, $module) || die $module;
|
rename($dest, $module) || die $module;
|
||||||
}
|
}
|
||||||
|
@ -251,7 +251,7 @@ static ssize_t codec_reg_write_file(struct file *file,
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Userspace has been fiddling around behind the kernel's back */
|
/* Userspace has been fiddling around behind the kernel's back */
|
||||||
add_taint(TAINT_USER);
|
add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE);
|
||||||
|
|
||||||
snd_soc_write(codec, reg, value);
|
snd_soc_write(codec, reg, value);
|
||||||
return buf_size;
|
return buf_size;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user