mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 07:38:10 +00:00
[PATCH] x86: privilege cleanup
Privilege checking cleanup. Originally, these diffs were much greater, but recent cleanups in Linux have already done much of the cleanup. I added some explanatory comments in places where the reasoning behind certain tests is rather subtle. Also, in traps.c, we can skip the user_mode check in handle_BUG(). The reason is, there are only two call chains - one via die_if_kernel() and one via do_page_fault(), both entering from die(). Both of these paths already ensure that a kernel mode failure has happened. Also, the original check here, if (user_mode(regs)) was insufficient anyways, since it would not rule out BUG faults from V8086 mode execution. Saving the %ss segment in show_regs() rather than assuming a fixed value also gives better information about the current kernel state in the register dump. Signed-off-by: Zachary Amsden <zach@vmware.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
f2ab446124
commit
0998e4228a
3 changed files with 11 additions and 5 deletions
|
@ -604,7 +604,9 @@ int fastcall do_signal(struct pt_regs *regs, sigset_t *oldset)
|
||||||
* We want the common case to go fast, which
|
* We want the common case to go fast, which
|
||||||
* is why we may in certain cases get here from
|
* is why we may in certain cases get here from
|
||||||
* kernel mode. Just return without doing anything
|
* kernel mode. Just return without doing anything
|
||||||
* if so.
|
* if so. vm86 regs switched out by assembly code
|
||||||
|
* before reaching here, so testing against kernel
|
||||||
|
* CS suffices.
|
||||||
*/
|
*/
|
||||||
if (!user_mode(regs))
|
if (!user_mode(regs))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -210,7 +210,7 @@ void show_registers(struct pt_regs *regs)
|
||||||
unsigned short ss;
|
unsigned short ss;
|
||||||
|
|
||||||
esp = (unsigned long) (®s->esp);
|
esp = (unsigned long) (®s->esp);
|
||||||
ss = __KERNEL_DS;
|
savesegment(ss, ss);
|
||||||
if (user_mode(regs)) {
|
if (user_mode(regs)) {
|
||||||
in_kernel = 0;
|
in_kernel = 0;
|
||||||
esp = regs->esp;
|
esp = regs->esp;
|
||||||
|
@ -267,9 +267,6 @@ static void handle_BUG(struct pt_regs *regs)
|
||||||
char c;
|
char c;
|
||||||
unsigned long eip;
|
unsigned long eip;
|
||||||
|
|
||||||
if (user_mode(regs))
|
|
||||||
goto no_bug; /* Not in kernel */
|
|
||||||
|
|
||||||
eip = regs->eip;
|
eip = regs->eip;
|
||||||
|
|
||||||
if (eip < PAGE_OFFSET)
|
if (eip < PAGE_OFFSET)
|
||||||
|
|
|
@ -61,6 +61,13 @@ struct pt_regs {
|
||||||
struct task_struct;
|
struct task_struct;
|
||||||
extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
|
extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* user_mode_vm(regs) determines whether a register set came from user mode.
|
||||||
|
* This is true if V8086 mode was enabled OR if the register set was from
|
||||||
|
* protected mode with RPL-3 CS value. This tricky test checks that with
|
||||||
|
* one comparison. Many places in the kernel can bypass this full check
|
||||||
|
* if they have already ruled out V8086 mode, so user_mode(regs) can be used.
|
||||||
|
*/
|
||||||
static inline int user_mode(struct pt_regs *regs)
|
static inline int user_mode(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
return (regs->xcs & 3) != 0;
|
return (regs->xcs & 3) != 0;
|
||||||
|
|
Loading…
Reference in a new issue