From: Zachary Amsden <zach@vmware.com>
To: linux-kernel@vger.kernel.org, ltp-list@lists.sourceforge.net
Subject: i386 / sysenter safety test case
Date: Tue, 08 Mar 2005 16:23:51 -0800 [thread overview]
Message-ID: <422E4217.10607@vmware.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1046 bytes --]
Code inspection of entry.S on i386 showed a potential problem - load
through segment without verifying "flatness" on the sysenter path.
Turns out this code is safe, but only by a thread ..
ENTRY(sysenter_entry)
movl TSS_sysenter_esp0(%esp),%esp
sysenter_past_esp:
sti
pushl $(__USER_DS)
pushl %ebp
pushfl
pushl $(__USER_CS)
pushl $SYSENTER_RETURN
/*
* Load the potential sixth argument from user stack.
* Careful about security.
*/
cmpl $__PAGE_OFFSET-3,%ebp
jae syscall_fault
1: movl (%ebp),%ebp
If it weren't for the fact that %ebp relative addresses default to using
the SS segment, we could have loaded through a user segment here to read
arbitrary memory (sysenter does nothing to DS segment). Perhaps this
was considered before, but because of the implications, I thought this
might be worth annotating in the source. Also provided a test case.
Obviously only works on sysenter capable processors. Tested on 2.6.8.
Zach Amsden
zach@vmware.com
[-- Attachment #2: sysenter.S --]
[-- Type: text/plain, Size: 804 bytes --]
#include <sys/syscall.h>
.text
.global sysenter_call
.global sysenter_call_2
/* void sysenter_call(pid_t pid, int signo, short ds, void *addr) */
sysenter_call:
push %ebx
push %edi
push %ebp
push %ds
movl %esp, %edi
movl 20(%esp), %ebx /* pid */
movl 24(%esp), %ecx /* signo */
movl 28(%esp), %ds /* exploit DS */
movl 32(%esp), %ebp
movl %ebp, %esp
push $sysenter_return
push %ecx
push %edx
subl $16, %ebp
push $0xbaadf00d
movl $SYS_kill, %eax
sysenter
/* vsyscall page will ret to us here */
sysenter_return:
mov %edi, %esp
pop %ds
pop %ebp
pop %edi
pop %ebx
ret
sysenter_call_2:
push %ebx
push %ebp
movl 20(%esp), %ebx /* pid */
movl 24(%esp), %ecx /* signo */
movl 28(%esp), %ebp
movl $SYS_kill, %eax
sysenter
.data
test: .long 0
[-- Attachment #3: sysenter.c --]
[-- Type: text/plain, Size: 1506 bytes --]
/*
* Copyright (c) 2005, Zachary Amsden (zach@vmware.com)
* This is licensed under the GPL.
*/
#include <stdio.h>
#include <signal.h>
#include <asm/ldt.h>
#include <asm/segment.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/mman.h>
#define __KERNEL__
#include <asm/page.h>
extern void sysenter_call(pid_t pid, int signo, short ds, void *addr);
extern void sysenter_call_2(pid_t pid, int signo, void *addr);
void catch_sig(int signo, struct sigcontext ctx)
{
__asm__ __volatile__("mov %0, %%ds" : : "r" (__USER_DS));
printf("interrupted %%ebp = 0x%x\n", ctx.ebp);
if (ctx.ebp == 0xbaadf00d)
printf("phew\n");
}
void main(void)
{
struct user_desc desc;
short ds;
unsigned long addr;
unsigned *stack;
unsigned long offset;
stack = (unsigned *)mmap(0, 4096, PROT_EXEC|PROT_READ|PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
stack = &stack[1024];
addr = 0xf0000; /* Try to read BIOS */
offset = __PAGE_OFFSET-(unsigned)stack+addr+16;
signal(SIGUSR1, catch_sig);
desc.entry_number = 0;
desc.base_addr = offset;
desc.limit = 0xffffff;
desc.seg_32bit = 1;
desc.contents = MODIFY_LDT_CONTENTS_DATA;
desc.read_exec_only = 0;
desc.limit_in_pages = 1;
desc.seg_not_present = 0;
desc.useable = 1;
if (modify_ldt(1, &desc, sizeof(desc)) != 0) {
perror("modify_ldt");
}
ds = 0x7; /* TI | RPL 3 */
sysenter_call(getpid(), SIGUSR1, ds, stack);
sysenter_call_2(getpid(), SIGSTOP, __PAGE_OFFSET+4096);
printf("not reached - core should show %%eax == -EFAULT\n");
}
reply other threads:[~2005-03-09 0:29 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=422E4217.10607@vmware.com \
--to=zach@vmware.com \
--cc=linux-kernel@vger.kernel.org \
--cc=ltp-list@lists.sourceforge.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox