From: Denys Vlasenko <dvlasenk@redhat.com>
To: Brian Gerst <brgerst@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>,
Denys Vlasenko <vda.linux@googlemail.com>,
Andy Lutomirski <luto@amacapital.net>,
Linus Torvalds <torvalds@linux-foundation.org>,
Steven Rostedt <rostedt@goodmis.org>,
Borislav Petkov <bp@alien8.de>, "H. Peter Anvin" <hpa@zytor.com>,
Oleg Nesterov <oleg@redhat.com>,
Frederic Weisbecker <fweisbec@gmail.com>,
Alexei Starovoitov <ast@plumgrid.com>,
Will Drewry <wad@chromium.org>, Kees Cook <keescook@chromium.org>,
X86 ML <x86@kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] x86: vdso32/syscall.S: do not load __USER32_DS to %ss
Date: Tue, 24 Mar 2015 21:17:05 +0100 [thread overview]
Message-ID: <5511C641.7000700@redhat.com> (raw)
In-Reply-To: <CAMzpN2huVk1nNGLYsYXCOyCvpYBTwKYCyn29JQWZ+r8ZZmyskA@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1117 bytes --]
On 03/24/2015 05:55 PM, Brian Gerst wrote:
>>> Might be nice to place a more generic description there, which
>>> registers are expected to be saved by user-space calling in here, etc.
>>
>> __kernel_vsyscall entry point has the same ABI in any 32-bit vDSO,
>> the good old int 0x80 calling convention:
>>
>> syscall# in eax,
>> params in ebx/ecx/edx/esi/edi/ebp,
>> all registers are preserved by the syscall.
>>
>> (I think we don't guarantee that all flags are preserved:
>> I have a testcase where DF gets cleared).
>
> DF should always be clear on any function call per the C ABI. But,
> eflags should be preserved, at least the non-privileged bits. I'd
> like to see that testcase.
The testcase is a simplistic example of how to find and use
32-bit vDSO to perform system calls.
It also sets flags.DF before syscall, and checks whether registers
are preserved, including flags.DF.
On 32-bit kernel (on Intel CPU, where vDSO uses SYSENTER), I see this:
$ ./test32_syscall_vdso
Result:1
whereas on 64-bit it is
./test32_syscall_vdso
Result:0
"Result:1" means that DF was cleared.
See attached source.
[-- Attachment #2: test32_syscall_vdso.c --]
[-- Type: text/x-csrc, Size: 2919 bytes --]
// (Assuming that int 80 works,) test that syscall32/sysenter32 works
//
// i686-gcc -Os -Wall -static
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <elf.h>
long syscall_addr;
long get_syscall(char **envp)
{
Elf32_auxv_t *auxv;
while (*envp++ != NULL)
continue;
for (auxv = (void *)envp; auxv->a_type != AT_NULL; auxv++)
if( auxv->a_type == AT_SYSINFO)
return auxv->a_un.a_val;
fprintf(stderr, "AT_SYSINFO not supplied, can't test\n");
exit(0); /* this is not a failure */
}
int nfds;
fd_set rfds;
fd_set wfds;
fd_set efds;
struct timespec timeout;
sigset_t sigmask;
struct {
sigset_t *sp;
int sz;
} sigmask_desc;
char RES[] = "Result:0\n";
void prep_args()
{
nfds = 42;
FD_ZERO(&rfds);
FD_ZERO(&wfds);
FD_ZERO(&efds);
FD_SET(0, &rfds);
FD_SET(1, &wfds);
FD_SET(2, &efds);
timeout.tv_sec = 0;
timeout.tv_nsec = 123;
sigemptyset(&sigmask);
sigaddset(&sigmask, SIGINT);
sigaddset(&sigmask, SIGUSR2);
sigaddset(&sigmask, SIGRTMAX);
sigmask_desc.sp = &sigmask;
sigmask_desc.sz = 8; /* bytes */
}
#define PSELECT 308
// pselect(nfds,rfds,wfds,efds,timeout,sigmask)
int main(int argc, char **argv, char **envp)
{
// This only works for non-static builds:
//syscall_addr = dlsym(dlopen("linux-gate.so.1", RTLD_NOW), "__kernel_vsyscall");
syscall_addr = get_syscall(envp);
prep_args();
asm("\n"
// Try 6-arg syscall: pselect. It should return quickly
" mov $308,%eax\n" // PSELECT
" mov nfds,%ebx\n" // ebx arg1
" mov $rfds,%ecx\n" // ecx arg2
" mov $wfds,%edx\n" // edx arg3
" mov $efds,%esi\n" // esi arg4
" mov $timeout,%edi\n" // edi arg5
" mov $sigmask_desc,%ebp\n" // %ebp arg6
" std\n"
" call *syscall_addr\n"
// Check that registers are not clobbered
" pushf\n"
" pop %eax\n"
" cmp nfds,%ebx\n" // ebx arg1
" movb $0x32,RES+7\n"
" jne end\n"
" cmp $rfds,%ecx\n" // ecx arg2
" movb $0x33,RES+7\n"
" jne end\n"
" cmp $wfds,%edx\n" // edx arg3
" movb $0x34,RES+7\n"
" jne end\n"
" cmp $efds,%esi\n" // esi arg4
" movb $0x35,RES+7\n"
" jne end\n"
" cmp $timeout,%edi\n" // edi arg5
" movb $0x36,RES+7\n"
" jne end\n"
" cmpl $sigmask_desc,%ebp\n" // %ebp arg6
" movb $0x37,RES+7\n"
" jne end\n"
// This fails (DF is not preserved)
// on 32-bit kernels. 64-bit ones worked:
" bt $10,%eax\n" //flags.DF still set?
" movb $0x31,RES+7\n"
" jnc end\n"
" movb $0x30,RES+7\n"
"end:\n"
" mov $4,%eax\n" // WRITE
" mov $1,%ebx\n" // ebx arg1
" mov $RES,%ecx\n" // ecx arg2
" mov $9,%edx\n" // edx arg3
" int $0x80\n"
// Error if result is not 0 or 1
// (result:1 means DF was clobbered)
" mov $1,%eax\n" // EXIT
" xor %ebx,%ebx\n" // ebx arg1
" cmpb $0x31,RES+7\n"
" ja 1f\n"
" int $0x80\n"
"1: inc %ebx\n"
" int $0x80\n"
);
return 42; /* not reached */
}
next prev parent reply other threads:[~2015-03-24 20:17 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-23 16:47 [PATCH] x86: vdso32/syscall.S: do not load __USER32_DS to %ss Denys Vlasenko
2015-03-23 19:37 ` Andy Lutomirski
2015-03-23 20:38 ` Andy Lutomirski
2015-03-23 21:55 ` Denys Vlasenko
2015-03-24 6:34 ` Ingo Molnar
2015-03-24 14:08 ` Denys Vlasenko
2015-03-24 15:50 ` Ingo Molnar
2015-03-24 16:55 ` Brian Gerst
2015-03-24 20:17 ` Denys Vlasenko [this message]
2015-03-24 21:40 ` Andy Lutomirski
2015-03-25 9:28 ` Ingo Molnar
2015-03-25 15:03 ` Denys Vlasenko
2015-03-25 15:17 ` Andy Lutomirski
2015-03-25 14:55 ` Denys Vlasenko
2015-03-25 15:12 ` Andy Lutomirski
2015-03-25 0:59 ` Brian Gerst
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=5511C641.7000700@redhat.com \
--to=dvlasenk@redhat.com \
--cc=ast@plumgrid.com \
--cc=bp@alien8.de \
--cc=brgerst@gmail.com \
--cc=fweisbec@gmail.com \
--cc=hpa@zytor.com \
--cc=keescook@chromium.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luto@amacapital.net \
--cc=mingo@kernel.org \
--cc=oleg@redhat.com \
--cc=rostedt@goodmis.org \
--cc=torvalds@linux-foundation.org \
--cc=vda.linux@googlemail.com \
--cc=wad@chromium.org \
--cc=x86@kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.