All of lore.kernel.org
 help / color / mirror / Atom feed
* [hppa-linux] Gateway instructions
@ 1999-03-18 14:35 Christopher Neufeld
  1999-03-18 16:55 ` Mike Shaver
  0 siblings, 1 reply; 10+ messages in thread
From: Christopher Neufeld @ 1999-03-18 14:35 UTC (permalink / raw)
  To: hppa-linux

   Hello folks,

   I'm wondering if anybody's got a handle on how gateway instructions
are supposed to work. The instruction is designed to allow jumps into the
kernel, with privilege promotion, without invoking the cost of an
interrupt, by branching into a page and then taking on the privilege
level of the page. The only safety check seems to be in the "B" bit,
which would appear to prohibit the target of such a jump being, itself,
another jump.
   How does this work, now? Is the target of the gateway instruction
intended to be simply a vector table of other jumps, preceded by some
non-branch instruction which forms the taget of the gateway? After all,
if I am permitted to choose my entry point into a kernel function, I can
do bad things, at the very least crash the kernel, but also probably
subvert it quite easily. Access control seems to be limited to the page,
not forbidding jumps into other parts of the code within the same page.
And what is the "B" bit in the processor status supposed to do in all
this?
   Is there a misprint in the book (or a misunderstanding on my part)? If
the "B" bit produces an exception when the target of the gateway is _not_
another jump, then I can see how this can be easily constructed into a
vector table into kernel functions without compromising security.


-- 
 Christopher Neufeld                   neufeld@physics.utoronto.ca
 Home page:  http://caliban.physics.utoronto.ca/neufeld/Intro.html
 "Don't edit reality for the sake of simplicity"

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [hppa-linux] Gateway instructions
  1999-03-18 14:35 Christopher Neufeld
@ 1999-03-18 16:55 ` Mike Shaver
  1999-03-18 18:05   ` Alan Cox
  0 siblings, 1 reply; 10+ messages in thread
From: Mike Shaver @ 1999-03-18 16:55 UTC (permalink / raw)
  To: hppa-linux

Christopher Neufeld wrote:
>    How does this work, now? Is the target of the gateway instruction
> intended to be simply a vector table of other jumps, preceded by some
> non-branch instruction which forms the taget of the gateway?

I suspected so, but was confounded by the same issues you bring up....

OpenBSD has this:
#define SYSCALLGATE     0xC0000000              /* syscall gateway page
*/
but I can't find it used anywhere else in the hppa-specific code, or
indeed the rest of the sys/ tree.

Here's how I think it works:
The GATE completer takes its privilege from the TLB entry for the page
_containing_ the BRANCH-with-GATE (see 4-5 in the PARISC 2.0 book).  So
what we do is have a page (at 0xC0000000, probably) that has
appropriately high privilege level in the TLB, and yet is executable by
the user-space process.  I think that means that the TLB access rights
field is [100,11,11]:
- execute: promote to privilege 0
- minimum privilege 3
- maximum privilege 3 (or do we care?)

The page contains:
???
B,GATE to syscall 0
???
B,GATE to syscall 1
???
B,GATE to syscall 2
etc.

I don't know what goes in ???, but clearly something is required so that
we don't get nailed by PSW[B].  Maybe a NOP, but probably something more
useful is required (set up space and other registers?).  The access ID
for that page should probably be 0, to make it universally accessible.

Questions:
- how many privilege levels do we care about?
- is it sufficient to mark kernel data as [001,00,00] with an access ID
of 0 so that all processes can get at it (when they've become
beprivileged enough!) ?  (With variants for code [100,00,00] and
read-only [000,00,00], of course.)
- what should go in ``???''?  Just something that sets PSW[C]?
- am I totally on crack?

Mike

-- 
345127.74 293957.05

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [hppa-linux] Gateway instructions
@ 1999-03-18 17:34 Bjorn Helgaas
  0 siblings, 0 replies; 10+ messages in thread
From: Bjorn Helgaas @ 1999-03-18 17:34 UTC (permalink / raw)
  To: hppa-linux

>   I'm wondering if anybody's got a handle on how gateway instructions
>are supposed to work.

The important thing about the gateway instruction is how the page
containing the instruction is mapped in the TLB.  A gateway can only
promote your privilege if the access type of the page containing the
gateway instruction is 4, 5, 6, or 7, i.e., "execute and promote to
privilege level 0, 1, 2, or 3".

The kernel controls the TLB mappings, so while a user can easily generate
gateway instructions, they won't do anything useful unless he can convince
the kernel to map them with the special access rights.

HP-UX maps only a few pages in the whole system with the magic gateway
access rights.  Syscalls work by branching to specific entry points on
these pages.  For 32-bit apps, the entry address is fixed and is hard-
coded into libc.  I think HP-UX supplies the syscall entry point to
64-bit apps in a register, and crt0.s stashes it somewhere.

Since the pages are execute only (not readable or writable), users can't
change the target of the gateway instructions.  The gateway pages contain
things other than gateway instructions, of course, but if you branch to
a non-gateway instruction, you stay at user privilege level and basically
execute some random (from the user's point of view) code.

When you branch to the defined entry point, your privilege level is
promoted, a couple registers are set up for running in the kernel, and you
branch to the the kernel proper, which is mapped with normal read/execute
or read/write/execute access rights.  The privilege levels in kernel
text access rights are set to allow access only at privilege level 0,
so even though a user can address the kernel, he can't read or execute
it without going through the gateway page.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [hppa-linux] Gateway instructions
  1999-03-18 16:55 ` Mike Shaver
@ 1999-03-18 18:05   ` Alan Cox
  0 siblings, 0 replies; 10+ messages in thread
From: Alan Cox @ 1999-03-18 18:05 UTC (permalink / raw)
  To: hppa-linux

> Here's how I think it works:
> The GATE completer takes its privilege from the TLB entry for the page
> _containing_ the BRANCH-with-GATE (see 4-5 in the PARISC 2.0 book).  So
> what we do is have a page (at 0xC0000000, probably) that has
> appropriately high privilege level in the TLB, and yet is executable by
> the user-space process.  I think that means that the TLB access rights
> field is [100,11,11]:

Oh man its a vax  8)

Yeah that would be fairly believable. VMS actually does this sort of stuff
with the vax architecture equivalent for libraries - think  setuid mmap 8)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [hppa-linux] Gateway instructions
@ 1999-03-18 18:43 Cary Coutant
  1999-03-18 21:51 ` Mike Shaver
  0 siblings, 1 reply; 10+ messages in thread
From: Cary Coutant @ 1999-03-18 18:43 UTC (permalink / raw)
  To: hppa-linux

The PSW B bit is set to indicate that an instruction is executing in the 
delay slot of another branch. Gateway instructions trap if the B bit is 
set to prevent a malicious process from using sequence like the following 
to gain a higher privilege level:

     B    gateway
     B    my_routine

Without this protection, the first branch to the gateway instruction 
would promote the privilege level, but control would immediately be 
transferred to the user's own code. 

Branches in delay slots are tricky; here's what's really happening in the 
hardware:

                                       PC offset queue after instruction
    PC           Instruction           head         tail

    user+0       ...                   user+4       user+8
    user+4       B gateway             user+8       gateway
    user+8       B my_routine          gateway      my_routine
    gateway      B,GATE syscall        my_routine   syscall
    my_routine   B my_routine+4        syscall      my_routine+4
    syscall      ...                   my_routine+4 my_routine+8
    my_routine+4 ...

When a page's access rights are 4, 5, 6, or 7, a gateway instruction on 
that page causes the privilege promotion. Most HP-UX system calls are 
branches to a common gateway instruction on a gateway page in the fourth 
quadrant. This gateway instruction then branches to a common syscall 
entry sequence that ultimately switches on the syscall number passed in a 
GR. Some "lightweight" syscalls may be implemented with their own 
gateways.

The B bit is not a problem as long as the delay slot of the branch to the 
gateway is either nullified or filled in with a non-branch instruction. 
For example,

    LDIL L'GATEWAY,%r1
    BLE  R'GATEWAY(%sr7,%r1)
    LDO  sycallnum,%r22



Cary Coutant
Hewlett-Packard Co.
Application Delivery Lab

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [hppa-linux] Gateway instructions
  1999-03-18 18:43 Cary Coutant
@ 1999-03-18 21:51 ` Mike Shaver
  1999-03-19 15:40   ` Kumar
  0 siblings, 1 reply; 10+ messages in thread
From: Mike Shaver @ 1999-03-18 21:51 UTC (permalink / raw)
  To: hppa-linux

Cary Coutant wrote:
> When a page's access rights are 4, 5, 6, or 7, a gateway instruction on
> that page causes the privilege promotion. Most HP-UX system calls are
> branches to a common gateway instruction on a gateway page in the fourth
> quadrant. This gateway instruction then branches to a common syscall
> entry sequence that ultimately switches on the syscall number passed in a
> GR. Some "lightweight" syscalls may be implemented with their own
> gateways.

OK, so you don't have a spot on the page for each syscall?  I was
thinking that we'd want to do that, since we're going to use the whole
page anyway and it would make things a little quicker by eliminating the
later dispatch-by-syscall step.

I presume that the syscall gateway page layout is part of the HP-UX
kernel/user ABI though, so we'll be following your lead for SOM/HP-ELF
binaries anyway.

> The B bit is not a problem as long as the delay slot of the branch to the
> gateway is either nullified or filled in with a non-branch instruction.
> For example,
> 
>     LDIL L'GATEWAY,%r1
>     BLE  R'GATEWAY(%sr7,%r1)
>     LDO  sycallnum,%r22

Someday (maybe today, if I get all my work done =) ), I'll learn to read
that.

Mike

-- 
368177.00 314980.91

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [hppa-linux] Gateway instructions
@ 1999-03-19  1:38 Cary Coutant
  1999-03-19  6:10 ` Mike Shaver
  0 siblings, 1 reply; 10+ messages in thread
From: Cary Coutant @ 1999-03-19  1:38 UTC (permalink / raw)
  To: hppa-linux

>OK, so you don't have a spot on the page for each syscall?  I was
>thinking that we'd want to do that, since we're going to use the whole
>page anyway and it would make things a little quicker by eliminating the
>later dispatch-by-syscall step.

There's a fair amount of setup code common to all syscalls before the 
dispatch to individual kernel entry points, and there are a lot of 
syscalls in HP-UX, so we use a single gateway.

For the 64-bit ABI, the gateway address is not hardcoded; when the 
program is loaded, the kernel passes it the address of a syscall vector 
table, which has one pointer per syscall. Most of the syscalls still 
vector to the one common gateway, but the lightweight syscalls can now be 
vectored off to a special gateway that has less overhead.

The 32-bit syscall convention is documented in (of all places) the 
Assembler manual; the 64-bit convention is documented in the PA-64 
runtime supplement (program startup chapter). These documents are 
available from

    http://www.software.hp.com/STK


Cary Coutant
Hewlett-Packard Co.
Application Delivery Lab

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [hppa-linux] Gateway instructions
  1999-03-19  1:38 [hppa-linux] Gateway instructions Cary Coutant
@ 1999-03-19  6:10 ` Mike Shaver
  1999-03-19  6:58   ` Mike Shaver
  0 siblings, 1 reply; 10+ messages in thread
From: Mike Shaver @ 1999-03-19  6:10 UTC (permalink / raw)
  To: hppa-linux

Cary Coutant wrote:
> The 32-bit syscall convention is documented in (of all places) the
> Assembler manual; the 64-bit convention is documented in the PA-64
> runtime supplement (program startup chapter). These documents are
> available from
> 
>     http://www.software.hp.com/STK

When I click on
http://docs.hp.com:80/dynaweb/hpux11/dtdcen1a/b541/@Generic__BookView
(the Assembler Reference Manual from
http://www.software.hp.com/STK/toc.html#Assembly ) I get an error:

No item b541 exists in collection dtdcen1a (fbebtcol.cc:1120)

Is there another place to find it?

Mike

-- 
399279.02 342330.84

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [hppa-linux] Gateway instructions
  1999-03-19  6:10 ` Mike Shaver
@ 1999-03-19  6:58   ` Mike Shaver
  0 siblings, 0 replies; 10+ messages in thread
From: Mike Shaver @ 1999-03-19  6:58 UTC (permalink / raw)
  To: hppa-linux

Mike Shaver wrote:
> When I click on
> http://docs.hp.com:80/dynaweb/hpux11/dtdcen1a/b541/@Generic__BookView
> (the Assembler Reference Manual from
> http://www.software.hp.com/STK/toc.html#Assembly ) I get an error:
> 
> No item b541 exists in collection dtdcen1a (fbebtcol.cc:1120)
> 
> Is there another place to find it?

Hey look -- there is!
http://docs.hp.com:80/dynaweb/hpux11/dtdcen1a/b821/@Generic__BookView

Thanks to Pablo for pointing it out.

Mike

-- 
402266.28 345101.43

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [hppa-linux] Gateway instructions
  1999-03-18 21:51 ` Mike Shaver
@ 1999-03-19 15:40   ` Kumar
  0 siblings, 0 replies; 10+ messages in thread
From: Kumar @ 1999-03-19 15:40 UTC (permalink / raw)
  To: hppa-linux


> > The B bit is not a problem as long as the delay slot of the branch to the
> > gateway is either nullified or filled in with a non-branch instruction.
> > For example,
> > 
> >     LDIL L'GATEWAY,%r1
> >     BLE  R'GATEWAY(%sr7,%r1)
> >     LDO  sycallnum,%r22

	Branch to space in %sr7 and offset contained in %r1,
	also load the syscall number in %r22 in the delay slot of BLE.
	I guess the assumption here is that %sr7 points to system space.
	Value of GATEWAY can be replaced by 0xc0000000 or whatever.	
	
	A equivalent 80386 sequence to make syscall:

	movl	$1, %eax	; load syscall num in %eax. in this case
						"exit"
	int	$0x80		; syscall trap in to kernel

	The number 80 is OS dependent and no magic number. Its just that
	Linux 80386 goes through trap gate 128 (0x80) for syscalls.


						pkd
> 
> Someday (maybe today, if I get all my work done =) ), I'll learn to read
> that.
> 
> Mike
> 
> -- 

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~1999-03-19 15:39 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
1999-03-19  1:38 [hppa-linux] Gateway instructions Cary Coutant
1999-03-19  6:10 ` Mike Shaver
1999-03-19  6:58   ` Mike Shaver
  -- strict thread matches above, loose matches on Subject: below --
1999-03-18 18:43 Cary Coutant
1999-03-18 21:51 ` Mike Shaver
1999-03-19 15:40   ` Kumar
1999-03-18 17:34 Bjorn Helgaas
1999-03-18 14:35 Christopher Neufeld
1999-03-18 16:55 ` Mike Shaver
1999-03-18 18:05   ` Alan Cox

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.