Merge branch 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6
* 'for-linus' of git://one.firstfloor.org/home/andi/git/linux-2.6: (225 commits) [PATCH] Don't set calgary iommu as default y [PATCH] i386/x86-64: New Intel feature flags [PATCH] x86: Add a cumulative thermal throttle event counter. [PATCH] i386: Make the jiffies compares use the 64bit safe macros. [PATCH] x86: Refactor thermal throttle processing [PATCH] Add 64bit jiffies compares (for use with get_jiffies_64) [PATCH] Fix unwinder warning in traps.c [PATCH] x86: Allow disabling early pci scans with pci=noearly or disallowing conf1 [PATCH] x86: Move direct PCI scanning functions out of line [PATCH] i386/x86-64: Make all early PCI scans dependent on CONFIG_PCI [PATCH] Don't leak NT bit into next task [PATCH] i386/x86-64: Work around gcc bug with noreturn functions in unwinder [PATCH] Fix some broken white space in ia32_signal.c [PATCH] Initialize argument registers for 32bit signal handlers. [PATCH] Remove all traces of signal number conversion [PATCH] Don't synchronize time reading on single core AMD systems [PATCH] Remove outdated comment in x86-64 mmconfig code [PATCH] Use string instructions for Core2 copy/clear [PATCH] x86: - restore i8259A eoi status on resume [PATCH] i386: Split multi-line printk in oops output. ...
此提交包含在:
@@ -45,6 +45,7 @@
|
||||
#include <linux/cn_proc.h>
|
||||
#include <linux/delayacct.h>
|
||||
#include <linux/taskstats_kern.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/pgalloc.h>
|
||||
@@ -175,6 +176,10 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
|
||||
tsk->thread_info = ti;
|
||||
setup_thread_stack(tsk, orig);
|
||||
|
||||
#ifdef CONFIG_CC_STACKPROTECTOR
|
||||
tsk->stack_canary = get_random_int();
|
||||
#endif
|
||||
|
||||
/* One for us, one for whoever does the "release_task()" (usually parent) */
|
||||
atomic_set(&tsk->usage,2);
|
||||
atomic_set(&tsk->fs_excl, 0);
|
||||
|
@@ -224,7 +224,14 @@ static int save_trace(struct stack_trace *trace)
|
||||
trace->max_entries = MAX_STACK_TRACE_ENTRIES - nr_stack_trace_entries;
|
||||
trace->entries = stack_trace + nr_stack_trace_entries;
|
||||
|
||||
save_stack_trace(trace, NULL, 0, 3);
|
||||
trace->skip = 3;
|
||||
trace->all_contexts = 0;
|
||||
|
||||
/* Make sure to not recurse in case the the unwinder needs to tak
|
||||
e locks. */
|
||||
lockdep_off();
|
||||
save_stack_trace(trace, NULL);
|
||||
lockdep_on();
|
||||
|
||||
trace->max_entries = trace->nr_entries;
|
||||
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <linux/debug_locks.h>
|
||||
|
||||
int panic_on_oops;
|
||||
int panic_on_unrecovered_nmi;
|
||||
int tainted;
|
||||
static int pause_on_oops;
|
||||
static int pause_on_oops_flag;
|
||||
@@ -270,3 +271,15 @@ void oops_exit(void)
|
||||
{
|
||||
do_oops_enter_exit();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CC_STACKPROTECTOR
|
||||
/*
|
||||
* Called when gcc's -fstack-protector feature is used, and
|
||||
* gcc detects corruption of the on-stack canary value
|
||||
*/
|
||||
void __stack_chk_fail(void)
|
||||
{
|
||||
panic("stack-protector: Kernel stack is corrupted");
|
||||
}
|
||||
EXPORT_SYMBOL(__stack_chk_fail);
|
||||
#endif
|
||||
|
@@ -7,6 +7,11 @@
|
||||
*
|
||||
* This file contains the spinlock/rwlock implementations for the
|
||||
* SMP and the DEBUG_SPINLOCK cases. (UP-nondebug inlines them)
|
||||
*
|
||||
* Note that some architectures have special knowledge about the
|
||||
* stack frames of these functions in their profile_pc. If you
|
||||
* change anything significant here that could change the stack
|
||||
* frame contact the architecture maintainers.
|
||||
*/
|
||||
|
||||
#include <linux/linkage.h>
|
||||
|
31
kernel/sys.c
31
kernel/sys.c
@@ -28,6 +28,7 @@
|
||||
#include <linux/tty.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/cn_proc.h>
|
||||
#include <linux/getcpu.h>
|
||||
|
||||
#include <linux/compat.h>
|
||||
#include <linux/syscalls.h>
|
||||
@@ -2062,3 +2063,33 @@ asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
asmlinkage long sys_getcpu(unsigned __user *cpup, unsigned __user *nodep,
|
||||
struct getcpu_cache __user *cache)
|
||||
{
|
||||
int err = 0;
|
||||
int cpu = raw_smp_processor_id();
|
||||
if (cpup)
|
||||
err |= put_user(cpu, cpup);
|
||||
if (nodep)
|
||||
err |= put_user(cpu_to_node(cpu), nodep);
|
||||
if (cache) {
|
||||
/*
|
||||
* The cache is not needed for this implementation,
|
||||
* but make sure user programs pass something
|
||||
* valid. vsyscall implementations can instead make
|
||||
* good use of the cache. Only use t0 and t1 because
|
||||
* these are available in both 32bit and 64bit ABI (no
|
||||
* need for a compat_getcpu). 32bit has enough
|
||||
* padding
|
||||
*/
|
||||
unsigned long t0, t1;
|
||||
get_user(t0, &cache->t0);
|
||||
get_user(t1, &cache->t1);
|
||||
t0++;
|
||||
t1++;
|
||||
put_user(t0, &cache->t0);
|
||||
put_user(t1, &cache->t1);
|
||||
}
|
||||
return err ? -EFAULT : 0;
|
||||
}
|
||||
|
@@ -76,8 +76,9 @@ extern int compat_log;
|
||||
|
||||
#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86)
|
||||
int unknown_nmi_panic;
|
||||
extern int proc_unknown_nmi_panic(ctl_table *, int, struct file *,
|
||||
void __user *, size_t *, loff_t *);
|
||||
int nmi_watchdog_enabled;
|
||||
extern int proc_nmi_enabled(struct ctl_table *, int , struct file *,
|
||||
void __user *, size_t *, loff_t *);
|
||||
#endif
|
||||
|
||||
/* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
|
||||
@@ -628,10 +629,26 @@ static ctl_table kern_table[] = {
|
||||
.data = &unknown_nmi_panic,
|
||||
.maxlen = sizeof (int),
|
||||
.mode = 0644,
|
||||
.proc_handler = &proc_unknown_nmi_panic,
|
||||
.proc_handler = &proc_dointvec,
|
||||
},
|
||||
{
|
||||
.ctl_name = KERN_NMI_WATCHDOG,
|
||||
.procname = "nmi_watchdog",
|
||||
.data = &nmi_watchdog_enabled,
|
||||
.maxlen = sizeof (int),
|
||||
.mode = 0644,
|
||||
.proc_handler = &proc_nmi_enabled,
|
||||
},
|
||||
#endif
|
||||
#if defined(CONFIG_X86)
|
||||
{
|
||||
.ctl_name = KERN_PANIC_ON_NMI,
|
||||
.procname = "panic_on_unrecovered_nmi",
|
||||
.data = &panic_on_unrecovered_nmi,
|
||||
.maxlen = sizeof(int),
|
||||
.mode = 0644,
|
||||
.proc_handler = &proc_dointvec,
|
||||
},
|
||||
{
|
||||
.ctl_name = KERN_BOOTLOADER_TYPE,
|
||||
.procname = "bootloader_type",
|
||||
|
@@ -603,6 +603,7 @@ int unwind(struct unwind_frame_info *frame)
|
||||
#define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs])
|
||||
const u32 *fde = NULL, *cie = NULL;
|
||||
const u8 *ptr = NULL, *end = NULL;
|
||||
unsigned long pc = UNW_PC(frame) - frame->call_frame;
|
||||
unsigned long startLoc = 0, endLoc = 0, cfa;
|
||||
unsigned i;
|
||||
signed ptrType = -1;
|
||||
@@ -612,7 +613,7 @@ int unwind(struct unwind_frame_info *frame)
|
||||
|
||||
if (UNW_PC(frame) == 0)
|
||||
return -EINVAL;
|
||||
if ((table = find_table(UNW_PC(frame))) != NULL
|
||||
if ((table = find_table(pc)) != NULL
|
||||
&& !(table->size & (sizeof(*fde) - 1))) {
|
||||
unsigned long tableSize = table->size;
|
||||
|
||||
@@ -647,7 +648,7 @@ int unwind(struct unwind_frame_info *frame)
|
||||
ptrType & DW_EH_PE_indirect
|
||||
? ptrType
|
||||
: ptrType & (DW_EH_PE_FORM|DW_EH_PE_signed));
|
||||
if (UNW_PC(frame) >= startLoc && UNW_PC(frame) < endLoc)
|
||||
if (pc >= startLoc && pc < endLoc)
|
||||
break;
|
||||
cie = NULL;
|
||||
}
|
||||
@@ -657,16 +658,28 @@ int unwind(struct unwind_frame_info *frame)
|
||||
state.cieEnd = ptr; /* keep here temporarily */
|
||||
ptr = (const u8 *)(cie + 2);
|
||||
end = (const u8 *)(cie + 1) + *cie;
|
||||
frame->call_frame = 1;
|
||||
if ((state.version = *ptr) != 1)
|
||||
cie = NULL; /* unsupported version */
|
||||
else if (*++ptr) {
|
||||
/* check if augmentation size is first (and thus present) */
|
||||
if (*ptr == 'z') {
|
||||
/* check for ignorable (or already handled)
|
||||
* nul-terminated augmentation string */
|
||||
while (++ptr < end && *ptr)
|
||||
if (strchr("LPR", *ptr) == NULL)
|
||||
while (++ptr < end && *ptr) {
|
||||
switch(*ptr) {
|
||||
/* check for ignorable (or already handled)
|
||||
* nul-terminated augmentation string */
|
||||
case 'L':
|
||||
case 'P':
|
||||
case 'R':
|
||||
continue;
|
||||
case 'S':
|
||||
frame->call_frame = 0;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ptr >= end || *ptr)
|
||||
cie = NULL;
|
||||
@@ -755,7 +768,7 @@ int unwind(struct unwind_frame_info *frame)
|
||||
state.org = startLoc;
|
||||
memcpy(&state.cfa, &badCFA, sizeof(state.cfa));
|
||||
/* process instructions */
|
||||
if (!processCFI(ptr, end, UNW_PC(frame), ptrType, &state)
|
||||
if (!processCFI(ptr, end, pc, ptrType, &state)
|
||||
|| state.loc > endLoc
|
||||
|| state.regs[retAddrReg].where == Nowhere
|
||||
|| state.cfa.reg >= ARRAY_SIZE(reg_info)
|
||||
@@ -763,6 +776,11 @@ int unwind(struct unwind_frame_info *frame)
|
||||
|| state.cfa.offs % sizeof(unsigned long))
|
||||
return -EIO;
|
||||
/* update frame */
|
||||
#ifndef CONFIG_AS_CFI_SIGNAL_FRAME
|
||||
if(frame->call_frame
|
||||
&& !UNW_DEFAULT_RA(state.regs[retAddrReg], state.dataAlign))
|
||||
frame->call_frame = 0;
|
||||
#endif
|
||||
cfa = FRAME_REG(state.cfa.reg, unsigned long) + state.cfa.offs;
|
||||
startLoc = min((unsigned long)UNW_SP(frame), cfa);
|
||||
endLoc = max((unsigned long)UNW_SP(frame), cfa);
|
||||
@@ -866,6 +884,7 @@ int unwind_init_frame_info(struct unwind_frame_info *info,
|
||||
/*const*/ struct pt_regs *regs)
|
||||
{
|
||||
info->task = tsk;
|
||||
info->call_frame = 0;
|
||||
arch_unw_init_frame_info(info, regs);
|
||||
|
||||
return 0;
|
||||
@@ -879,6 +898,7 @@ int unwind_init_blocked(struct unwind_frame_info *info,
|
||||
struct task_struct *tsk)
|
||||
{
|
||||
info->task = tsk;
|
||||
info->call_frame = 0;
|
||||
arch_unw_init_blocked(info);
|
||||
|
||||
return 0;
|
||||
@@ -894,6 +914,7 @@ int unwind_init_running(struct unwind_frame_info *info,
|
||||
void *arg)
|
||||
{
|
||||
info->task = current;
|
||||
info->call_frame = 0;
|
||||
|
||||
return arch_unwind_init_running(info, callback, arg);
|
||||
}
|
||||
|
新增問題並參考
封鎖使用者