linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Brian Gerst <bgerst@didntduck.org>
To: root@chaos.analogic.com
Cc: dvorak <dvorak@xs4all.nl>, linux-kernel@vger.kernel.org
Subject: Re: Syscall changes registers beyond %eax, on linux-i386
Date: Thu, 19 Sep 2002 13:51:12 -0400	[thread overview]
Message-ID: <3D8A0E90.9000005@didntduck.org> (raw)
In-Reply-To: Pine.LNX.3.95.1020919131927.15141A-100000@chaos.analogic.com

Richard B. Johnson wrote:
> On Thu, 19 Sep 2002, Brian Gerst wrote:
>>Richard B. Johnson wrote:
>>>There is a bug in some other code. Try this. It will show
>>>that ebx is not being killed in a syscall. You can prove
>>>that this code works by changing ebx to eax, which will
>>>get destroyed and print "Broken" before exit.
>>
>>The bug is only with _some_ syscalls, and getpid() is not one of them, 
>>so your example is flawed.  It happens when a syscall modifies one of 
>>it's parameter values.  The solution is to assign the parameter to a 
>>local variable before modifying it.
>>
> 
> 
> Well which one?  Here is an ioctl(). It certainly modifies one
> of its parameter values.
> 
> #include <stdio.h>
> #include <unistd.h>
> #include <sys/ioctl.h>
> #include <termios.h>
> 
> void barf(void);
> void barf()
> {
>     puts("Broken\n");
>     exit(0);
> }
> int main()
> {
>     struct termios t;
> 
>     __asm__ __volatile__("movl	$0xdeadface, %ebx\n");
>     (void)ioctl(0, TCGETS, &t); 
>     (void)getpid();
>     __asm__ __volatile__("cmpl	$0xdeadface, %ebx\n"
>                          "jnz   barf\n");
> 
>     return 0;
> }
> 
> 
> Until you can show the syscall that doesn't follow the correct
> rules, then my example is not flawed. In fact a modified example can
> be used to find any broken calls.

Well the original poster gave one valid example: sys_poll().  We're not 
talking about it modifying userspace though a pointer.  We're talking 
about it taking it's parameter on the kernel stack (which is really the 
pt_regs structure saved from user space) and modifying it.  Which then 
gets restored to the user registers upon syscall exit.

This is how the kernel stack looks like inside a syscall (x86):
OLDSS
OLDESP
EFLAGS
CS
EIP
ORIG_EAX
ES
DS
EAX	<- syscall number
EBP	<- syscall arg6
EDI	<- syscall arg5
ESI	<- syscall arg4
EDX	<- syscall arg3
ECX	<- syscall arg2
EBX	<- syscall arg1
(return address)
(local variables)

Everything above the return address is the pt_regs struct that gets 
restored to user space.  If the syscall modifies any of its args (*not 
memory pointed to by the args*), they get written back to the stack in 
the pt_regs area, and then get restored to userspace modified. 
Understand now?

--
				Brian Gerst


  reply	other threads:[~2002-09-19 17:46 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-09-19 14:45 Syscall changes registers beyond %eax, on linux-i386 dvorak
2002-09-19 16:11 ` Richard B. Johnson
2002-09-19 17:09   ` Brian Gerst
2002-09-19 17:22     ` Richard B. Johnson
2002-09-19 17:51       ` Brian Gerst [this message]
2002-09-19 18:30         ` Richard B. Johnson
2002-09-19 17:59       ` dvorak
2002-09-19 18:32         ` Richard B. Johnson
2002-09-19 17:44 Petr Vandrovec
2002-09-19 18:04 ` Brian Gerst
2002-09-19 18:30   ` Richard Henderson
2002-09-19 18:51     ` Brian Gerst
2002-09-19 18:57       ` Richard Henderson
2002-09-19 19:40         ` Richard B. Johnson
2002-09-19 19:41           ` Richard Henderson
2002-09-19 19:53             ` Richard B. Johnson
2002-09-19 22:46               ` J.A. Magallon
2002-09-20 12:27                 ` Richard B. Johnson
2002-09-20 17:16                   ` Richard Henderson
2002-09-22  1:33               ` Pavel Machek
2002-09-23 13:11                 ` Richard B. Johnson
2002-09-23 18:31                   ` Pavel Machek
2002-09-19 19:18       ` Richard B. Johnson
2002-09-19 19:24   ` Daniel Jacobowitz
2002-09-19 20:25     ` Mikael Pettersson
2002-09-20  8:32       ` george anzinger
2002-09-21  6:19         ` Richard Henderson
2002-09-21  8:09           ` george anzinger
2002-09-21 15:08             ` Richard Henderson

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=3D8A0E90.9000005@didntduck.org \
    --to=bgerst@didntduck.org \
    --cc=dvorak@xs4all.nl \
    --cc=linux-kernel@vger.kernel.org \
    --cc=root@chaos.analogic.com \
    /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;
as well as URLs for NNTP newsgroup(s).