Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
3817da13
Commit
3817da13
authored
Nov 21, 2002
by
Jeff Dike
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added the uaccess changes from the skas merge.
parent
eda5c15d
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
434 additions
and
99 deletions
+434
-99
arch/um/include/um_uaccess.h
arch/um/include/um_uaccess.h
+73
-0
arch/um/kernel/skas/include/uaccess.h
arch/um/kernel/skas/include/uaccess.h
+239
-0
arch/um/kernel/tt/Makefile
arch/um/kernel/tt/Makefile
+1
-1
arch/um/kernel/tt/include/uaccess.h
arch/um/kernel/tt/include/uaccess.h
+119
-0
arch/um/kernel/tt/uaccess_user.c
arch/um/kernel/tt/uaccess_user.c
+0
-0
include/asm-um/uaccess.h
include/asm-um/uaccess.h
+2
-98
No files found.
arch/um/include/um_uaccess.h
0 → 100644
View file @
3817da13
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#ifndef __ARCH_UM_UACCESS_H
#define __ARCH_UM_UACCESS_H
#include "linux/config.h"
#include "choose-mode.h"
#ifdef CONFIG_MODE_TT
#include "../kernel/tt/include/uaccess.h"
#endif
#ifdef CONFIG_MODE_SKAS
#include "../kernel/skas/include/uaccess.h"
#endif
#define access_ok(type, addr, size) \
CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)
static
inline
int
verify_area
(
int
type
,
const
void
*
addr
,
unsigned
long
size
)
{
return
(
CHOOSE_MODE_PROC
(
verify_area_tt
,
verify_area_skas
,
type
,
addr
,
size
));
}
static
inline
int
copy_from_user
(
void
*
to
,
const
void
*
from
,
int
n
)
{
return
(
CHOOSE_MODE_PROC
(
copy_from_user_tt
,
copy_from_user_skas
,
to
,
from
,
n
));
}
static
inline
int
copy_to_user
(
void
*
to
,
const
void
*
from
,
int
n
)
{
return
(
CHOOSE_MODE_PROC
(
copy_to_user_tt
,
copy_to_user_skas
,
to
,
from
,
n
));
}
static
inline
int
strncpy_from_user
(
char
*
dst
,
const
char
*
src
,
int
count
)
{
return
(
CHOOSE_MODE_PROC
(
strncpy_from_user_tt
,
strncpy_from_user_skas
,
dst
,
src
,
count
));
}
static
inline
int
__clear_user
(
void
*
mem
,
int
len
)
{
return
(
CHOOSE_MODE_PROC
(
__clear_user_tt
,
__clear_user_skas
,
mem
,
len
));
}
static
inline
int
clear_user
(
void
*
mem
,
int
len
)
{
return
(
CHOOSE_MODE_PROC
(
clear_user_tt
,
clear_user_skas
,
mem
,
len
));
}
static
inline
int
strnlen_user
(
void
*
str
,
int
len
)
{
return
(
CHOOSE_MODE_PROC
(
strnlen_user_tt
,
strnlen_user_skas
,
str
,
len
));
}
#endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
arch/um/kernel/skas/include/uaccess.h
0 → 100644
View file @
3817da13
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#ifndef __SKAS_UACCESS_H
#define __SKAS_UACCESS_H
#include "linux/string.h"
#include "linux/sched.h"
#include "asm/processor.h"
#include "asm/pgtable.h"
#include "asm/errno.h"
#include "asm/current.h"
#include "asm/a.out.h"
#include "kern_util.h"
#define access_ok_skas(type, addr, size) \
((segment_eq(get_fs(), KERNEL_DS)) || \
(((unsigned long) (addr) < TASK_SIZE) && \
((unsigned long) (addr) + (size) < TASK_SIZE)))
static
inline
int
verify_area_skas
(
int
type
,
const
void
*
addr
,
unsigned
long
size
)
{
return
(
access_ok_skas
(
type
,
addr
,
size
)
?
0
:
-
EFAULT
);
}
extern
unsigned
long
handle_page_fault
(
unsigned
long
address
,
unsigned
long
ip
,
int
is_write
,
int
is_user
,
int
*
code_out
);
extern
void
*
um_virt_to_phys
(
struct
task_struct
*
task
,
unsigned
long
virt
,
pte_t
*
pte_out
);
static
inline
unsigned
long
maybe_map
(
unsigned
long
virt
,
int
is_write
)
{
pte_t
pte
;
void
*
phys
=
um_virt_to_phys
(
current
,
virt
,
&
pte
);
int
dummy_code
;
if
(
IS_ERR
(
phys
)
||
(
is_write
&&
!
pte_write
(
pte
))){
if
(
!
handle_page_fault
(
virt
,
0
,
is_write
,
0
,
&
dummy_code
))
return
(
0
);
phys
=
um_virt_to_phys
(
current
,
virt
,
NULL
);
}
return
((
unsigned
long
)
__va
((
unsigned
long
)
phys
));
}
static
inline
int
buffer_op
(
unsigned
long
addr
,
int
len
,
int
(
*
op
)(
unsigned
long
addr
,
int
len
,
void
*
arg
),
void
*
arg
)
{
int
size
=
min
(
PAGE_ALIGN
(
addr
)
-
addr
,
(
unsigned
long
)
len
);
int
remain
=
len
,
n
;
n
=
(
*
op
)(
addr
,
size
,
arg
);
if
(
n
!=
0
)
return
(
n
<
0
?
remain
:
0
);
addr
+=
size
;
remain
-=
size
;
if
(
remain
==
0
)
return
(
0
);
while
(
addr
<
((
addr
+
remain
)
&
PAGE_MASK
)){
n
=
(
*
op
)(
addr
,
PAGE_SIZE
,
arg
);
if
(
n
!=
0
)
return
(
n
<
0
?
remain
:
0
);
addr
+=
PAGE_SIZE
;
remain
-=
PAGE_SIZE
;
}
if
(
remain
==
0
)
return
(
0
);
n
=
(
*
op
)(
addr
,
remain
,
arg
);
if
(
n
!=
0
)
return
(
n
<
0
?
remain
:
0
);
return
(
0
);
}
static
inline
int
copy_chunk_from_user
(
unsigned
long
from
,
int
len
,
void
*
arg
)
{
unsigned
long
*
to_ptr
=
arg
,
to
=
*
to_ptr
;
from
=
maybe_map
(
from
,
0
);
if
(
from
==
0
)
return
(
-
1
);
memcpy
((
void
*
)
to
,
(
void
*
)
from
,
len
);
*
to_ptr
+=
len
;
return
(
0
);
}
static
inline
int
copy_from_user_skas
(
void
*
to
,
const
void
*
from
,
int
n
)
{
if
(
segment_eq
(
get_fs
(),
KERNEL_DS
)){
memcpy
(
to
,
from
,
n
);
return
(
0
);
}
return
(
access_ok_skas
(
VERIFY_READ
,
from
,
n
)
?
buffer_op
((
unsigned
long
)
from
,
n
,
copy_chunk_from_user
,
&
to
)
:
n
);
}
static
inline
int
copy_chunk_to_user
(
unsigned
long
to
,
int
len
,
void
*
arg
)
{
unsigned
long
*
from_ptr
=
arg
,
from
=
*
from_ptr
;
to
=
maybe_map
(
to
,
1
);
if
(
to
==
0
)
return
(
-
1
);
memcpy
((
void
*
)
to
,
(
void
*
)
from
,
len
);
*
from_ptr
+=
len
;
return
(
0
);
}
static
inline
int
copy_to_user_skas
(
void
*
to
,
const
void
*
from
,
int
n
)
{
if
(
segment_eq
(
get_fs
(),
KERNEL_DS
)){
memcpy
(
to
,
from
,
n
);
return
(
0
);
}
return
(
access_ok_skas
(
VERIFY_WRITE
,
to
,
n
)
?
buffer_op
((
unsigned
long
)
to
,
n
,
copy_chunk_to_user
,
&
from
)
:
n
);
}
static
inline
int
strncpy_chunk_from_user
(
unsigned
long
from
,
int
len
,
void
*
arg
)
{
char
**
to_ptr
=
arg
,
*
to
=
*
to_ptr
;
int
n
;
from
=
maybe_map
(
from
,
0
);
if
(
from
==
0
)
return
(
-
1
);
strncpy
(
to
,
(
void
*
)
from
,
len
);
n
=
strnlen
(
to
,
len
);
*
to_ptr
+=
n
;
if
(
n
<
len
)
return
(
1
);
return
(
0
);
}
static
inline
int
strncpy_from_user_skas
(
char
*
dst
,
const
char
*
src
,
int
count
)
{
int
n
;
char
*
ptr
=
dst
;
if
(
segment_eq
(
get_fs
(),
KERNEL_DS
)){
strncpy
(
dst
,
src
,
count
);
return
(
strnlen
(
dst
,
count
));
}
if
(
!
access_ok_skas
(
VERIFY_READ
,
src
,
1
))
return
(
-
EFAULT
);
n
=
buffer_op
((
unsigned
long
)
src
,
count
,
strncpy_chunk_from_user
,
&
ptr
);
if
(
n
!=
0
)
return
(
-
EFAULT
);
return
(
strnlen
(
dst
,
count
));
}
static
inline
int
clear_chunk
(
unsigned
long
addr
,
int
len
,
void
*
unused
)
{
addr
=
maybe_map
(
addr
,
1
);
if
(
addr
==
0
)
return
(
-
1
);
memset
((
void
*
)
addr
,
0
,
len
);
return
(
0
);
}
static
inline
int
__clear_user_skas
(
void
*
mem
,
int
len
)
{
return
(
buffer_op
((
unsigned
long
)
mem
,
len
,
clear_chunk
,
NULL
));
}
static
inline
int
clear_user_skas
(
void
*
mem
,
int
len
)
{
if
(
segment_eq
(
get_fs
(),
KERNEL_DS
)){
memset
(
mem
,
0
,
len
);
return
(
0
);
}
return
(
access_ok_skas
(
VERIFY_WRITE
,
mem
,
len
)
?
buffer_op
((
unsigned
long
)
mem
,
len
,
clear_chunk
,
NULL
)
:
len
);
}
static
inline
int
strnlen_chunk
(
unsigned
long
str
,
int
len
,
void
*
arg
)
{
int
*
len_ptr
=
arg
,
n
;
str
=
maybe_map
(
str
,
0
);
if
(
str
==
0
)
return
(
-
1
);
n
=
strnlen
((
void
*
)
str
,
len
);
*
len_ptr
+=
n
;
if
(
n
<
len
)
return
(
1
);
return
(
0
);
}
static
inline
int
strnlen_user_skas
(
void
*
str
,
int
len
)
{
int
count
=
0
,
n
;
if
(
segment_eq
(
get_fs
(),
KERNEL_DS
))
return
(
strnlen
(
str
,
len
)
+
1
);
n
=
buffer_op
((
unsigned
long
)
str
,
len
,
strnlen_chunk
,
&
count
);
if
(
n
==
0
)
return
(
count
+
1
);
return
(
-
EFAULT
);
}
#endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
arch/um/kernel/tt/Makefile
View file @
3817da13
...
...
@@ -4,7 +4,7 @@
#
obj-y
=
exec_kern.o exec_user.o gdb.o gdb_kern.o mem.o process_kern.o
\
syscall_user.o tracer.o
syscall_user.o tracer.o
uaccess_user.o
obj-$(CONFIG_PT_PROXY)
+=
ptproxy/
...
...
arch/um/kernel/tt/include/uaccess.h
0 → 100644
View file @
3817da13
/*
* Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#ifndef __TT_UACCESS_H
#define __TT_UACCESS_H
#include "linux/string.h"
#include "linux/sched.h"
#include "asm/processor.h"
#include "asm/errno.h"
#include "asm/current.h"
#include "asm/a.out.h"
#define ABOVE_KMEM (16 * 1024 * 1024)
extern
unsigned
long
end_vm
;
extern
unsigned
long
uml_physmem
;
#define under_task_size(addr, size) \
(((unsigned long) (addr) < TASK_SIZE) && \
(((unsigned long) (addr) + (size)) < TASK_SIZE))
#define is_stack(addr, size) \
(((unsigned long) (addr) < STACK_TOP) && \
((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
(((unsigned long) (addr) + (size)) <= STACK_TOP))
#define access_ok_tt(type, addr, size) \
((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \
(((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
(under_task_size(addr, size) || is_stack(addr, size))))
static
inline
int
verify_area_tt
(
int
type
,
const
void
*
addr
,
unsigned
long
size
)
{
return
(
access_ok_tt
(
type
,
addr
,
size
)
?
0
:
-
EFAULT
);
}
extern
unsigned
long
get_fault_addr
(
void
);
extern
int
__do_copy_from_user
(
void
*
to
,
const
void
*
from
,
int
n
,
void
**
fault_addr
,
void
**
fault_catcher
);
static
inline
int
copy_from_user_tt
(
void
*
to
,
const
void
*
from
,
int
n
)
{
return
(
access_ok_tt
(
VERIFY_READ
,
from
,
n
)
?
__do_copy_from_user
(
to
,
from
,
n
,
&
current
->
thread
.
fault_addr
,
&
current
->
thread
.
fault_catcher
)
:
n
);
}
extern
int
__do_copy_to_user
(
void
*
to
,
const
void
*
from
,
int
n
,
void
**
fault_addr
,
void
**
fault_catcher
);
static
inline
int
copy_to_user_tt
(
void
*
to
,
const
void
*
from
,
int
n
)
{
return
(
access_ok_tt
(
VERIFY_WRITE
,
to
,
n
)
?
__do_copy_to_user
(
to
,
from
,
n
,
&
current
->
thread
.
fault_addr
,
&
current
->
thread
.
fault_catcher
)
:
n
);
}
extern
int
__do_strncpy_from_user
(
char
*
dst
,
const
char
*
src
,
size_t
n
,
void
**
fault_addr
,
void
**
fault_catcher
);
static
inline
int
strncpy_from_user_tt
(
char
*
dst
,
const
char
*
src
,
int
count
)
{
int
n
;
if
(
!
access_ok_tt
(
VERIFY_READ
,
src
,
1
))
return
(
-
EFAULT
);
n
=
__do_strncpy_from_user
(
dst
,
src
,
count
,
&
current
->
thread
.
fault_addr
,
&
current
->
thread
.
fault_catcher
);
if
(
n
<
0
)
return
(
-
EFAULT
);
return
(
n
);
}
extern
int
__do_clear_user
(
void
*
mem
,
size_t
len
,
void
**
fault_addr
,
void
**
fault_catcher
);
static
inline
int
__clear_user_tt
(
void
*
mem
,
int
len
)
{
return
(
__do_clear_user
(
mem
,
len
,
&
current
->
thread
.
fault_addr
,
&
current
->
thread
.
fault_catcher
));
}
static
inline
int
clear_user_tt
(
void
*
mem
,
int
len
)
{
return
(
access_ok_tt
(
VERIFY_WRITE
,
mem
,
len
)
?
__do_clear_user
(
mem
,
len
,
&
current
->
thread
.
fault_addr
,
&
current
->
thread
.
fault_catcher
)
:
len
);
}
extern
int
__do_strnlen_user
(
const
char
*
str
,
unsigned
long
n
,
void
**
fault_addr
,
void
**
fault_catcher
);
static
inline
int
strnlen_user_tt
(
void
*
str
,
int
len
)
{
return
(
__do_strnlen_user
(
str
,
len
,
&
current
->
thread
.
fault_addr
,
&
current
->
thread
.
fault_catcher
));
}
#endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
* Emacs will notice this stuff at the end of the file and automatically
* adjust the settings for this buffer only. This must remain at the end
* of the file.
* ---------------------------------------------------------------------------
* Local variables:
* c-file-style: "linux"
* End:
*/
arch/um/kernel/uaccess_user.c
→
arch/um/kernel/
tt/
uaccess_user.c
View file @
3817da13
File moved
include/asm-um/uaccess.h
View file @
3817da13
/*
* Copyright (C) 200
0
Jeff Dike (jdike@karaya.com)
* Copyright (C) 200
2
Jeff Dike (jdike@karaya.com)
* Licensed under the GPL
*/
#ifndef __UM_UACCESS_H
#define __UM_UACCESS_H
#include "linux/string.h"
#include "linux/sched.h"
#include "asm/processor.h"
#include "asm/errno.h"
#include "asm/current.h"
#include "asm/a.out.h"
#define VERIFY_READ 0
#define VERIFY_WRITE 1
...
...
@@ -26,8 +19,6 @@
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
#define ABOVE_KMEM (16 * 1024 * 1024)
#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
#define USER_DS MAKE_MM_SEG(TASK_SIZE)
...
...
@@ -35,56 +26,12 @@
#define get_fs() (current_thread_info()->addr_limit)
#define set_fs(x) (current_thread_info()->addr_limit = (x))
extern
unsigned
long
end_vm
;
extern
unsigned
long
uml_physmem
;
#define under_task_size(addr, size) \
(((unsigned long) (addr) < TASK_SIZE) && \
(((unsigned long) (addr) + (size)) < TASK_SIZE))
#define is_stack(addr, size) \
(((unsigned long) (addr) < STACK_TOP) && \
((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
(((unsigned long) (addr) + (size)) <= STACK_TOP))
#define segment_eq(a, b) ((a).seg == (b).seg)
#define access_ok(type, addr, size) \
((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \
(((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \
(under_task_size(addr, size) || is_stack(addr, size))))
static
inline
int
verify_area
(
int
type
,
const
void
*
addr
,
unsigned
long
size
)
{
return
(
access_ok
(
type
,
addr
,
size
)
?
0
:
-
EFAULT
);
}
extern
unsigned
long
get_fault_addr
(
void
);
extern
int
__do_copy_from_user
(
void
*
to
,
const
void
*
from
,
int
n
,
void
**
fault_addr
,
void
**
fault_catcher
);
static
inline
int
copy_from_user
(
void
*
to
,
const
void
*
from
,
int
n
)
{
return
(
access_ok
(
VERIFY_READ
,
from
,
n
)
?
__do_copy_from_user
(
to
,
from
,
n
,
&
current
->
thread
.
fault_addr
,
&
current
->
thread
.
fault_catcher
)
:
n
);
}
#include "um_uaccess.h"
#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
extern
int
__do_copy_to_user
(
void
*
to
,
const
void
*
from
,
int
n
,
void
**
fault_addr
,
void
**
fault_catcher
);
static
inline
int
copy_to_user
(
void
*
to
,
const
void
*
from
,
int
n
)
{
return
(
access_ok
(
VERIFY_WRITE
,
to
,
n
)
?
__do_copy_to_user
(
to
,
from
,
n
,
&
current
->
thread
.
fault_addr
,
&
current
->
thread
.
fault_catcher
)
:
n
);
}
#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
#define __get_user(x, ptr) \
...
...
@@ -128,49 +75,6 @@ static inline int copy_to_user(void *to, const void *from, int n)
__put_user(x, private_ptr) : -EFAULT); \
})
extern
int
__do_strncpy_from_user
(
char
*
dst
,
const
char
*
src
,
size_t
n
,
void
**
fault_addr
,
void
**
fault_catcher
);
static
inline
int
strncpy_from_user
(
char
*
dst
,
const
char
*
src
,
int
count
)
{
int
n
;
if
(
!
access_ok
(
VERIFY_READ
,
src
,
1
))
return
(
-
EFAULT
);
n
=
__do_strncpy_from_user
(
dst
,
src
,
count
,
&
current
->
thread
.
fault_addr
,
&
current
->
thread
.
fault_catcher
);
if
(
n
<
0
)
return
(
-
EFAULT
);
return
(
n
);
}
extern
int
__do_clear_user
(
void
*
mem
,
size_t
len
,
void
**
fault_addr
,
void
**
fault_catcher
);
static
inline
int
__clear_user
(
void
*
mem
,
int
len
)
{
return
(
__do_clear_user
(
mem
,
len
,
&
current
->
thread
.
fault_addr
,
&
current
->
thread
.
fault_catcher
));
}
static
inline
int
clear_user
(
void
*
mem
,
int
len
)
{
return
(
access_ok
(
VERIFY_WRITE
,
mem
,
len
)
?
__do_clear_user
(
mem
,
len
,
&
current
->
thread
.
fault_addr
,
&
current
->
thread
.
fault_catcher
)
:
len
);
}
extern
int
__do_strnlen_user
(
const
char
*
str
,
unsigned
long
n
,
void
**
fault_addr
,
void
**
fault_catcher
);
static
inline
int
strnlen_user
(
void
*
str
,
int
len
)
{
return
(
__do_strnlen_user
(
str
,
len
,
&
current
->
thread
.
fault_addr
,
&
current
->
thread
.
fault_catcher
));
}
#define strlen_user(str) strnlen_user(str, ~0UL >> 1)
struct
exception_table_entry
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment