Linux MIPS Architecture development
 help / color / mirror / Atom feed
* __access_ok
@ 2002-06-17 11:53 Carsten Langgaard
  2002-06-17 16:24 ` __access_ok Justin Carlson
  2002-06-17 19:55 ` __access_ok Jun Sun
  0 siblings, 2 replies; 6+ messages in thread
From: Carsten Langgaard @ 2002-06-17 11:53 UTC (permalink / raw)
  To: linux-mips

The __access_ok macro in include/asm-mips64/uaccess.h need to be changed
in order to work correctly, it's a copy from the 32-bit kernel.
It's not good enough to simply check for the "sign bit" of the address.
The area between USEG (XUSEG) and KSEG0 will in 64-bit addressing mode
generate an address error, if
accessed. The size of the area depend on the number of virtual
addressing bits, implemented in the CPU.

I have tried to come up with a patch, please see below. Any thought ?
I also changed the macro in arch/mips64/kernel/unaligned.c

/Carsten


Index: include/asm-mips64//uaccess.h
===================================================================
RCS file:
/home/repository/sw/linux-2.4.18/include/asm-mips64/uaccess.h,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 uaccess.h
--- include/asm-mips64//uaccess.h       4 Mar 2002 11:13:26 -0000
1.1.1.1
+++ include/asm-mips64//uaccess.h       17 Jun 2002 11:35:32 -0000
@@ -12,6 +12,8 @@
 #include <linux/errno.h>
 #include <linux/sched.h>

+#include <asm/addrspace.h>
+
 #define STR(x)  __STR(x)
 #define __STR(x)  #x

@@ -40,16 +42,23 @@
  * than tests.
  *
  * Address valid if:
- *  - "addr" doesn't have any high-bits set
- *  - AND "size" doesn't have any high-bits set
- *  - AND "addr+size" doesn't have any high-bits set
- *  - OR we are in kernel mode.
+ *  - In user mode and "addr" and "addr+size" in USEG (or XUSEG).
+ *  - OR we are in kernel mode and "addr" and "addr+size" isn't in the
+ *    area between USEG (XUSEG) and KSEG0.
  */
 #define
__ua_size(size)                                                       \
        (__builtin_constant_p(size) && (signed long) (size) > 0 ? 0 :
(size))

-#define __access_ok(addr,size,mask)
\
-       (((signed long)((mask)&(addr | (addr + size) |
__ua_size(size)))) >= 0)
+static inline int
+__access_ok(unsigned long addr, unsigned long size, long mask)
+{
+       if (((mask) && ((addr | (addr+size)) >= KUSIZE)) ||
+           (((addr | (addr+size)) < K0BASE) &&
+            ((addr | (addr+size)) >= KUSIZE)))
+               return 0;
+       else
+               return 1;
+}

 #define __access_mask ((long)(get_fs().seg))


Index: arch/mips64/kernel/unaligned.c
===================================================================
RCS file:
/home/repository/sw/linux-2.4.18/arch/mips64/kernel/unaligned.c,v
retrieving revision 1.2
diff -u -r1.2 unaligned.c
--- arch/mips64/kernel/unaligned.c      23 May 2002 11:11:45 -0000
1.2
+++ arch/mips64/kernel/unaligned.c      17 Jun 2002 11:51:30 -0000
@@ -89,11 +89,14 @@
 #define __STR(x)  #x

 /*
- * User code may only access USEG; kernel code may access the
- * entire address space.
+ * User code may only access USEG;
+ * Kernel code may access the entire address space, except the area
between
+ * USEG (XUSEG) and KSEG0.
  */
-#define check_axs(pc,a,s)                              \
-       if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0)      \
+#define check_axs(pc,a,s)
\
+        if (((pc < KUSIZE) && (((a) | ((a)+(s))) >= KUSIZE))
||               \
+           ((((a) | ((a)+(s))) < K0BASE) &&
\
+            (((a) | ((a)+(s))) >= KUSIZE)))
\
                goto sigbus;



--
_    _ ____  ___   Carsten Langgaard   Mailto:carstenl@mips.com
|\  /|||___)(___   MIPS Denmark        Direct: +45 4486 5527
| \/ |||    ____)  Lautrupvang 4B      Switch: +45 4486 5555
  TECHNOLOGIES     2750 Ballerup       Fax...: +45 4486 5556
                   Denmark             http://www.mips.com

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

* Re: __access_ok
  2002-06-17 11:53 __access_ok Carsten Langgaard
@ 2002-06-17 16:24 ` Justin Carlson
  2002-06-18  7:44   ` __access_ok Carsten Langgaard
  2002-06-17 19:55 ` __access_ok Jun Sun
  1 sibling, 1 reply; 6+ messages in thread
From: Justin Carlson @ 2002-06-17 16:24 UTC (permalink / raw)
  To: Carsten Langgaard; +Cc: linux-mips

On Mon, 2002-06-17 at 04:53, Carsten Langgaard wrote:

>   * Address valid if:
> - *  - "addr" doesn't have any high-bits set
> - *  - AND "size" doesn't have any high-bits set
> - *  - AND "addr+size" doesn't have any high-bits set
> - *  - OR we are in kernel mode.
> + *  - In user mode and "addr" and "addr+size" in USEG (or XUSEG).
> + *  - OR we are in kernel mode and "addr" and "addr+size" isn't in the
> + *    area between USEG (XUSEG) and KSEG0.

You also need to test for high bit set in size.  Otherwise, for example,
if a process was ok to access range 0x40000000-0x40003fff, 
access_ok(0x40001000, 0xfffff100) would return 1.  The addition will
wrap around, leading to all sorts of fun havoc.

-Justin

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

* Re: __access_ok
  2002-06-17 11:53 __access_ok Carsten Langgaard
  2002-06-17 16:24 ` __access_ok Justin Carlson
@ 2002-06-17 19:55 ` Jun Sun
  2002-06-18  7:38   ` __access_ok Carsten Langgaard
  2002-06-19  9:17   ` __access_ok Ralf Baechle
  1 sibling, 2 replies; 6+ messages in thread
From: Jun Sun @ 2002-06-17 19:55 UTC (permalink / raw)
  To: Carsten Langgaard; +Cc: linux-mips

Just to be nit-picking, the end point should be (addr + size - 1).

Jun

Carsten Langgaard wrote:

> The __access_ok macro in include/asm-mips64/uaccess.h need to be changed
> in order to work correctly, it's a copy from the 32-bit kernel.
> It's not good enough to simply check for the "sign bit" of the address.
> The area between USEG (XUSEG) and KSEG0 will in 64-bit addressing mode
> generate an address error, if
> accessed. The size of the area depend on the number of virtual
> addressing bits, implemented in the CPU.
> 
> I have tried to come up with a patch, please see below. Any thought ?
> I also changed the macro in arch/mips64/kernel/unaligned.c
> 
> /Carsten
> 
> 
> Index: include/asm-mips64//uaccess.h
> ===================================================================
> RCS file:
> /home/repository/sw/linux-2.4.18/include/asm-mips64/uaccess.h,v
> retrieving revision 1.1.1.1
> diff -u -r1.1.1.1 uaccess.h
> --- include/asm-mips64//uaccess.h       4 Mar 2002 11:13:26 -0000
> 1.1.1.1
> +++ include/asm-mips64//uaccess.h       17 Jun 2002 11:35:32 -0000
> @@ -12,6 +12,8 @@
>  #include <linux/errno.h>
>  #include <linux/sched.h>
> 
> +#include <asm/addrspace.h>
> +
>  #define STR(x)  __STR(x)
>  #define __STR(x)  #x
> 
> @@ -40,16 +42,23 @@
>   * than tests.
>   *
>   * Address valid if:
> - *  - "addr" doesn't have any high-bits set
> - *  - AND "size" doesn't have any high-bits set
> - *  - AND "addr+size" doesn't have any high-bits set
> - *  - OR we are in kernel mode.
> + *  - In user mode and "addr" and "addr+size" in USEG (or XUSEG).
> + *  - OR we are in kernel mode and "addr" and "addr+size" isn't in the
> + *    area between USEG (XUSEG) and KSEG0.
>   */
>  #define
> __ua_size(size)                                                       \
>         (__builtin_constant_p(size) && (signed long) (size) > 0 ? 0 :
> (size))
> 
> -#define __access_ok(addr,size,mask)
> \
> -       (((signed long)((mask)&(addr | (addr + size) |
> __ua_size(size)))) >= 0)
> +static inline int
> +__access_ok(unsigned long addr, unsigned long size, long mask)
> +{
> +       if (((mask) && ((addr | (addr+size)) >= KUSIZE)) ||
> +           (((addr | (addr+size)) < K0BASE) &&
> +            ((addr | (addr+size)) >= KUSIZE)))
> +               return 0;
> +       else
> +               return 1;
> +}
> 
>  #define __access_mask ((long)(get_fs().seg))
> 
> 
> Index: arch/mips64/kernel/unaligned.c
> ===================================================================
> RCS file:
> /home/repository/sw/linux-2.4.18/arch/mips64/kernel/unaligned.c,v
> retrieving revision 1.2
> diff -u -r1.2 unaligned.c
> --- arch/mips64/kernel/unaligned.c      23 May 2002 11:11:45 -0000
> 1.2
> +++ arch/mips64/kernel/unaligned.c      17 Jun 2002 11:51:30 -0000
> @@ -89,11 +89,14 @@
>  #define __STR(x)  #x
> 
>  /*
> - * User code may only access USEG; kernel code may access the
> - * entire address space.
> + * User code may only access USEG;
> + * Kernel code may access the entire address space, except the area
> between
> + * USEG (XUSEG) and KSEG0.
>   */
> -#define check_axs(pc,a,s)                              \
> -       if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0)      \
> +#define check_axs(pc,a,s)
> \
> +        if (((pc < KUSIZE) && (((a) | ((a)+(s))) >= KUSIZE))
> ||               \
> +           ((((a) | ((a)+(s))) < K0BASE) &&
> \
> +            (((a) | ((a)+(s))) >= KUSIZE)))
> \
>                 goto sigbus;
> 
> 
> 
> --
> _    _ ____  ___   Carsten Langgaard   Mailto:carstenl@mips.com
> |\  /|||___)(___   MIPS Denmark        Direct: +45 4486 5527
> | \/ |||    ____)  Lautrupvang 4B      Switch: +45 4486 5555
>   TECHNOLOGIES     2750 Ballerup       Fax...: +45 4486 5556
>                    Denmark             http://www.mips.com
> 
> 
> 
> 

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

* Re: __access_ok
  2002-06-17 19:55 ` __access_ok Jun Sun
@ 2002-06-18  7:38   ` Carsten Langgaard
  2002-06-19  9:17   ` __access_ok Ralf Baechle
  1 sibling, 0 replies; 6+ messages in thread
From: Carsten Langgaard @ 2002-06-18  7:38 UTC (permalink / raw)
  To: Jun Sun; +Cc: linux-mips

That's true, lets do it right, thanks.

/Carsten


Jun Sun wrote:

> Just to be nit-picking, the end point should be (addr + size - 1).
>
> Jun
>
> Carsten Langgaard wrote:
>
> > The __access_ok macro in include/asm-mips64/uaccess.h need to be changed
> > in order to work correctly, it's a copy from the 32-bit kernel.
> > It's not good enough to simply check for the "sign bit" of the address.
> > The area between USEG (XUSEG) and KSEG0 will in 64-bit addressing mode
> > generate an address error, if
> > accessed. The size of the area depend on the number of virtual
> > addressing bits, implemented in the CPU.
> >
> > I have tried to come up with a patch, please see below. Any thought ?
> > I also changed the macro in arch/mips64/kernel/unaligned.c
> >
> > /Carsten
> >
> >
> > Index: include/asm-mips64//uaccess.h
> > ===================================================================
> > RCS file:
> > /home/repository/sw/linux-2.4.18/include/asm-mips64/uaccess.h,v
> > retrieving revision 1.1.1.1
> > diff -u -r1.1.1.1 uaccess.h
> > --- include/asm-mips64//uaccess.h       4 Mar 2002 11:13:26 -0000
> > 1.1.1.1
> > +++ include/asm-mips64//uaccess.h       17 Jun 2002 11:35:32 -0000
> > @@ -12,6 +12,8 @@
> >  #include <linux/errno.h>
> >  #include <linux/sched.h>
> >
> > +#include <asm/addrspace.h>
> > +
> >  #define STR(x)  __STR(x)
> >  #define __STR(x)  #x
> >
> > @@ -40,16 +42,23 @@
> >   * than tests.
> >   *
> >   * Address valid if:
> > - *  - "addr" doesn't have any high-bits set
> > - *  - AND "size" doesn't have any high-bits set
> > - *  - AND "addr+size" doesn't have any high-bits set
> > - *  - OR we are in kernel mode.
> > + *  - In user mode and "addr" and "addr+size" in USEG (or XUSEG).
> > + *  - OR we are in kernel mode and "addr" and "addr+size" isn't in the
> > + *    area between USEG (XUSEG) and KSEG0.
> >   */
> >  #define
> > __ua_size(size)                                                       \
> >         (__builtin_constant_p(size) && (signed long) (size) > 0 ? 0 :
> > (size))
> >
> > -#define __access_ok(addr,size,mask)
> > \
> > -       (((signed long)((mask)&(addr | (addr + size) |
> > __ua_size(size)))) >= 0)
> > +static inline int
> > +__access_ok(unsigned long addr, unsigned long size, long mask)
> > +{
> > +       if (((mask) && ((addr | (addr+size)) >= KUSIZE)) ||
> > +           (((addr | (addr+size)) < K0BASE) &&
> > +            ((addr | (addr+size)) >= KUSIZE)))
> > +               return 0;
> > +       else
> > +               return 1;
> > +}
> >
> >  #define __access_mask ((long)(get_fs().seg))
> >
> >
> > Index: arch/mips64/kernel/unaligned.c
> > ===================================================================
> > RCS file:
> > /home/repository/sw/linux-2.4.18/arch/mips64/kernel/unaligned.c,v
> > retrieving revision 1.2
> > diff -u -r1.2 unaligned.c
> > --- arch/mips64/kernel/unaligned.c      23 May 2002 11:11:45 -0000
> > 1.2
> > +++ arch/mips64/kernel/unaligned.c      17 Jun 2002 11:51:30 -0000
> > @@ -89,11 +89,14 @@
> >  #define __STR(x)  #x
> >
> >  /*
> > - * User code may only access USEG; kernel code may access the
> > - * entire address space.
> > + * User code may only access USEG;
> > + * Kernel code may access the entire address space, except the area
> > between
> > + * USEG (XUSEG) and KSEG0.
> >   */
> > -#define check_axs(pc,a,s)                              \
> > -       if ((long)(~(pc) & ((a) | ((a)+(s)))) < 0)      \
> > +#define check_axs(pc,a,s)
> > \
> > +        if (((pc < KUSIZE) && (((a) | ((a)+(s))) >= KUSIZE))
> > ||               \
> > +           ((((a) | ((a)+(s))) < K0BASE) &&
> > \
> > +            (((a) | ((a)+(s))) >= KUSIZE)))
> > \
> >                 goto sigbus;
> >
> >
> >
> > --
> > _    _ ____  ___   Carsten Langgaard  Mailto:carstenl@mips.com
> > |\  /|||___)(___   MIPS Denmark        Direct: +45 4486 5527
> > | \/ |||    ____)  Lautrupvang 4B      Switch: +45 4486 5555
> >   TECHNOLOGIES     2750 Ballerup       Fax...: +45 4486 5556
> >                    Denmark            http://www.mips.com
> >
> >
> >
> >

--
_    _ ____  ___   Carsten Langgaard   Mailto:carstenl@mips.com
|\  /|||___)(___   MIPS Denmark        Direct: +45 4486 5527
| \/ |||    ____)  Lautrupvang 4B      Switch: +45 4486 5555
  TECHNOLOGIES     2750 Ballerup       Fax...: +45 4486 5556
                   Denmark             http://www.mips.com

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

* Re: __access_ok
  2002-06-17 16:24 ` __access_ok Justin Carlson
@ 2002-06-18  7:44   ` Carsten Langgaard
  0 siblings, 0 replies; 6+ messages in thread
From: Carsten Langgaard @ 2002-06-18  7:44 UTC (permalink / raw)
  To: Justin Carlson; +Cc: linux-mips

Note, that this is in the 64-bit kernel, a size there the high bit is set,
will be astronomical and not a true value.

/Carsten

Justin Carlson wrote:

> On Mon, 2002-06-17 at 04:53, Carsten Langgaard wrote:
>
> >   * Address valid if:
> > - *  - "addr" doesn't have any high-bits set
> > - *  - AND "size" doesn't have any high-bits set
> > - *  - AND "addr+size" doesn't have any high-bits set
> > - *  - OR we are in kernel mode.
> > + *  - In user mode and "addr" and "addr+size" in USEG (or XUSEG).
> > + *  - OR we are in kernel mode and "addr" and "addr+size" isn't in the
> > + *    area between USEG (XUSEG) and KSEG0.
>
> You also need to test for high bit set in size.  Otherwise, for example,
> if a process was ok to access range 0x40000000-0x40003fff,
> access_ok(0x40001000, 0xfffff100) would return 1.  The addition will
> wrap around, leading to all sorts of fun havoc.
>
> -Justin

--
_    _ ____  ___   Carsten Langgaard   Mailto:carstenl@mips.com
|\  /|||___)(___   MIPS Denmark        Direct: +45 4486 5527
| \/ |||    ____)  Lautrupvang 4B      Switch: +45 4486 5555
  TECHNOLOGIES     2750 Ballerup       Fax...: +45 4486 5556
                   Denmark             http://www.mips.com

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

* Re: __access_ok
  2002-06-17 19:55 ` __access_ok Jun Sun
  2002-06-18  7:38   ` __access_ok Carsten Langgaard
@ 2002-06-19  9:17   ` Ralf Baechle
  1 sibling, 0 replies; 6+ messages in thread
From: Ralf Baechle @ 2002-06-19  9:17 UTC (permalink / raw)
  To: Jun Sun; +Cc: Carsten Langgaard, linux-mips

On Mon, Jun 17, 2002 at 12:55:08PM -0700, Jun Sun wrote:

> Just to be nit-picking, the end point should be (addr + size - 1).

You better don't use the last bit of userspace and make that (addr + size).
Saves several kB on the entire kernel.

  Ralf

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

end of thread, other threads:[~2002-06-19  9:17 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-06-17 11:53 __access_ok Carsten Langgaard
2002-06-17 16:24 ` __access_ok Justin Carlson
2002-06-18  7:44   ` __access_ok Carsten Langgaard
2002-06-17 19:55 ` __access_ok Jun Sun
2002-06-18  7:38   ` __access_ok Carsten Langgaard
2002-06-19  9:17   ` __access_ok Ralf Baechle

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox