Commit 21dc2e6c authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml

Pull UML updates from Richard Weinberger:

 - remove hppfs ("HonePot ProcFS")

 - initial support for musl libc

 - uaccess cleanup

 - random cleanups and bug fixes all over the place

* 'for-linus-4.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rw/uml: (21 commits)
  um: Don't pollute kernel namespace with uapi
  um: Include sys/types.h for makedev(), major(), minor()
  um: Do not use stdin and stdout identifiers for struct members
  um: Do not use __ptr_t type for stack_t's .ss pointer
  um: Fix mconsole dependency
  um: Handle tracehook_report_syscall_entry() result
  um: Remove copy&paste code from init.h
  um: Stop abusing __KERNEL__
  um: Catch unprotected user memory access
  um: Fix warning in setup_signal_stack_si()
  um: Rework uaccess code
  um: Add uaccess.h to ldt.c
  um: Add uaccess.h to syscalls_64.c
  um: Add asm/elf.h to vma.c
  um: Cleanup mem_32/64.c headers
  um: Remove hppfs
  um: Move syscall() declaration into os.h
  um: kernel: ksyms: Export symbol syscall() for fixing modpost issue
  um/os-Linux: Use char[] for syscall_stub declarations
  um: Use char[] for linker script address declarations
  ...
parents b779157d da028d5e
......@@ -44,23 +44,9 @@ config HOSTFS
If you'd like to be able to work with files stored on the host,
say Y or M here; otherwise say N.
config HPPFS
tristate "HoneyPot ProcFS"
depends on PROC_FS
help
hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
entries to be overridden, removed, or fabricated from the host.
Its purpose is to allow a UML to appear to be a physical machine
by removing or changing anything in /proc which gives away the
identity of a UML.
See <http://user-mode-linux.sf.net/old/hppfs.html> for more information.
You only need this if you are setting up a UML honeypot. Otherwise,
it is safe to say 'N' here.
config MCONSOLE
bool "Management console"
depends on PROC_FS
default y
help
The user mode linux management console is a low-level interface to
......
......@@ -68,9 +68,10 @@ KBUILD_CFLAGS += $(CFLAGS) $(CFLAGS-y) -D__arch_um__ \
KBUILD_AFLAGS += $(ARCH_INCLUDE)
USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -D__KERNEL__,,\
$(patsubst -I%,,$(KBUILD_CFLAGS)))) $(ARCH_INCLUDE) $(MODE_INCLUDE) \
$(filter -I%,$(CFLAGS)) -D_FILE_OFFSET_BITS=64 -idirafter include
USER_CFLAGS = $(patsubst $(KERNEL_DEFINES),,$(patsubst -I%,,$(KBUILD_CFLAGS))) \
$(ARCH_INCLUDE) $(MODE_INCLUDE) $(filter -I%,$(CFLAGS)) \
-D_FILE_OFFSET_BITS=64 -idirafter include \
-D__KERNEL__ -D__UM_HOST__
#This will adjust *FLAGS accordingly to the platform.
include $(ARCH_DIR)/Makefile-os-$(OS)
......
......@@ -9,8 +9,8 @@
#include <os.h>
struct dog_data {
int stdin;
int stdout;
int stdin_fd;
int stdout_fd;
int close_me[2];
};
......@@ -18,11 +18,11 @@ static void pre_exec(void *d)
{
struct dog_data *data = d;
dup2(data->stdin, 0);
dup2(data->stdout, 1);
dup2(data->stdout, 2);
close(data->stdin);
close(data->stdout);
dup2(data->stdin_fd, 0);
dup2(data->stdout_fd, 1);
dup2(data->stdout_fd, 2);
close(data->stdin_fd);
close(data->stdout_fd);
close(data->close_me[0]);
close(data->close_me[1]);
}
......@@ -49,8 +49,8 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
goto out_close_in;
}
data.stdin = out_fds[0];
data.stdout = in_fds[1];
data.stdin_fd = out_fds[0];
data.stdout_fd = in_fds[1];
data.close_me[0] = out_fds[1];
data.close_me[1] = in_fds[0];
......
......@@ -7,7 +7,7 @@
#ifndef __MCONSOLE_H__
#define __MCONSOLE_H__
#ifndef __KERNEL__
#ifdef __UM_HOST__
#include <stdint.h>
#define u32 uint32_t
#endif
......
......@@ -166,7 +166,7 @@ int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
struct change_pre_exec_data {
int close_me;
int stdout;
int stdout_fd;
};
static void change_pre_exec(void *arg)
......@@ -174,7 +174,7 @@ static void change_pre_exec(void *arg)
struct change_pre_exec_data *data = arg;
close(data->close_me);
dup2(data->stdout, 1);
dup2(data->stdout_fd, 1);
}
static int change_tramp(char **argv, char *output, int output_len)
......@@ -189,7 +189,7 @@ static int change_tramp(char **argv, char *output, int output_len)
return err;
}
pe_data.close_me = fds[0];
pe_data.stdout = fds[1];
pe_data.stdout_fd = fds[1];
pid = run_helper(change_pre_exec, &pe_data, argv);
if (pid > 0) /* Avoid hang as we won't get data in failure case. */
......
......@@ -55,8 +55,8 @@ static int set_up_tty(int fd)
}
struct slip_pre_exec_data {
int stdin;
int stdout;
int stdin_fd;
int stdout_fd;
int close_me;
};
......@@ -64,9 +64,9 @@ static void slip_pre_exec(void *arg)
{
struct slip_pre_exec_data *data = arg;
if (data->stdin >= 0)
dup2(data->stdin, 0);
dup2(data->stdout, 1);
if (data->stdin_fd >= 0)
dup2(data->stdin_fd, 0);
dup2(data->stdout_fd, 1);
if (data->close_me >= 0)
close(data->close_me);
}
......@@ -85,8 +85,8 @@ static int slip_tramp(char **argv, int fd)
}
err = 0;
pe_data.stdin = fd;
pe_data.stdout = fds[1];
pe_data.stdin_fd = fd;
pe_data.stdout_fd = fds[1];
pe_data.close_me = fds[0];
err = run_helper(slip_pre_exec, &pe_data, argv);
if (err < 0)
......
......@@ -20,18 +20,18 @@ static int slirp_user_init(void *data, void *dev)
}
struct slirp_pre_exec_data {
int stdin;
int stdout;
int stdin_fd;
int stdout_fd;
};
static void slirp_pre_exec(void *arg)
{
struct slirp_pre_exec_data *data = arg;
if (data->stdin != -1)
dup2(data->stdin, 0);
if (data->stdout != -1)
dup2(data->stdout, 1);
if (data->stdin_fd != -1)
dup2(data->stdin_fd, 0);
if (data->stdout_fd != -1)
dup2(data->stdout_fd, 1);
}
static int slirp_tramp(char **argv, int fd)
......@@ -39,8 +39,8 @@ static int slirp_tramp(char **argv, int fd)
struct slirp_pre_exec_data pe_data;
int pid;
pe_data.stdin = fd;
pe_data.stdout = fd;
pe_data.stdin_fd = fd;
pe_data.stdout_fd = fd;
pid = run_helper(slirp_pre_exec, &pe_data, argv);
return pid;
......
......@@ -21,7 +21,6 @@ generic-y += param.h
generic-y += pci.h
generic-y += percpu.h
generic-y += preempt.h
generic-y += sections.h
generic-y += switch_to.h
generic-y += topology.h
generic-y += trace_clock.h
......
......@@ -8,7 +8,6 @@
#ifndef __ASSEMBLY__
#include <asm/ptrace-abi.h>
#include <sysdep/ptrace.h>
struct pt_regs {
......@@ -37,7 +36,7 @@ extern int putreg(struct task_struct *child, int regno, unsigned long value);
extern int arch_copy_tls(struct task_struct *new);
extern void clear_flushed_tls(struct task_struct *task);
extern void syscall_trace_enter(struct pt_regs *regs);
extern int syscall_trace_enter(struct pt_regs *regs);
extern void syscall_trace_leave(struct pt_regs *regs);
#endif
......
#ifndef __UM_SECTIONS_H
#define __UM_SECTIONS_H
#include <asm-generic/sections.h>
extern char __binary_start[];
extern char __syscall_stub_start[], __syscall_stub_end[];
#endif
......@@ -10,7 +10,7 @@
#include <asm/types.h>
#include <asm/page.h>
#include <asm/uaccess.h>
#include <asm/segment.h>
struct thread_info {
struct task_struct *task; /* main task structure */
......
/*
* Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
* Copyright (C) 2015 Richard Weinberger (richard@nod.at)
* Licensed under the GPL
*/
#ifndef __UM_UACCESS_H
#define __UM_UACCESS_H
/* thread_info has a mm_segment_t in it, so put the definition up here */
typedef struct {
unsigned long seg;
} mm_segment_t;
#include <linux/thread_info.h>
#include <linux/errno.h>
#include <asm/processor.h>
#include <asm/thread_info.h>
#include <asm/elf.h>
#define VERIFY_READ 0
#define VERIFY_WRITE 1
/*
* The fs value determines whether argument validity checking should be
* performed or not. If get_fs() == USER_DS, checking is performed, with
* get_fs() == KERNEL_DS, checking is bypassed.
*
* For historical reasons, these macros are grossly misnamed.
*/
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF)
#define USER_DS MAKE_MM_SEG(TASK_SIZE)
#define get_ds() (KERNEL_DS)
#define get_fs() (current_thread_info()->addr_limit)
#define set_fs(x) (current_thread_info()->addr_limit = (x))
#define segment_eq(a, b) ((a).seg == (b).seg)
#define __under_task_size(addr, size) \
(((unsigned long) (addr) < TASK_SIZE) && \
(((unsigned long) (addr) + (size)) < TASK_SIZE))
#define __access_ok_vsyscall(type, addr, size) \
((type == VERIFY_READ) && \
((unsigned long) (addr) >= FIXADDR_USER_START) && \
#define __access_ok_vsyscall(addr, size) \
(((unsigned long) (addr) >= FIXADDR_USER_START) && \
((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \
((unsigned long) (addr) + (size) >= (unsigned long)(addr)))
#define __addr_range_nowrap(addr, size) \
((unsigned long) (addr) <= ((unsigned long) (addr) + (size)))
#define access_ok(type, addr, size) \
(__addr_range_nowrap(addr, size) && \
(__under_task_size(addr, size) || \
__access_ok_vsyscall(type, addr, size) || \
segment_eq(get_fs(), KERNEL_DS)))
extern int copy_from_user(void *to, const void __user *from, int n);
extern int copy_to_user(void __user *to, const void *from, int n);
/*
* strncpy_from_user: - Copy a NUL terminated string from userspace.
* @dst: Destination address, in kernel space. This buffer must be at
* least @count bytes long.
* @src: Source address, in user space.
* @count: Maximum number of bytes to copy, including the trailing NUL.
*
* Copies a NUL-terminated string from userspace to kernel space.
*
* On success, returns the length of the string (not including the trailing
* NUL).
*
* If access to userspace fails, returns -EFAULT (some data may have been
* copied).
*
* If @count is smaller than the length of the string, copies @count bytes
* and returns @count.
*/
extern int strncpy_from_user(char *dst, const char __user *src, int count);
/*
* __clear_user: - Zero a block of memory in user space, with less checking.
* @to: Destination address, in user space.
* @n: Number of bytes to zero.
*
* Zero a block of memory in user space. Caller must check
* the specified block with access_ok() before calling this function.
*
* Returns number of bytes that could not be cleared.
* On success, this will be zero.
*/
extern int __clear_user(void __user *mem, int len);
/*
* clear_user: - Zero a block of memory in user space.
* @to: Destination address, in user space.
* @n: Number of bytes to zero.
*
* Zero a block of memory in user space.
*
* Returns number of bytes that could not be cleared.
* On success, this will be zero.
*/
extern int clear_user(void __user *mem, int len);
/*
* strlen_user: - Get the size of a string in user space.
* @str: The string to measure.
* @n: The maximum valid length
*
* Get the size of a NUL-terminated string in user space.
*
* Returns the size of the string INCLUDING the terminating NUL.
* On exception, returns 0.
* If the string is too long, returns a value greater than @n.
*/
extern int strnlen_user(const void __user *str, int len);
#define __copy_from_user(to, from, n) copy_from_user(to, from, n)
#define __copy_to_user(to, from, n) copy_to_user(to, from, n)
extern long __copy_from_user(void *to, const void __user *from, unsigned long n);
extern long __copy_to_user(void __user *to, const void *from, unsigned long n);
extern long __strncpy_from_user(char *dst, const char __user *src, long count);
extern long __strnlen_user(const void __user *str, long len);
extern unsigned long __clear_user(void __user *mem, unsigned long len);
static inline int __access_ok(unsigned long addr, unsigned long size);
/* Teach asm-generic/uaccess.h that we have C functions for these. */
#define __access_ok __access_ok
#define __clear_user __clear_user
#define __copy_to_user __copy_to_user
#define __copy_from_user __copy_from_user
#define __strnlen_user __strnlen_user
#define __strncpy_from_user __strncpy_from_user
#define __copy_to_user_inatomic __copy_to_user
#define __copy_from_user_inatomic __copy_from_user
#define __get_user(x, ptr) \
({ \
const __typeof__(*(ptr)) __user *__private_ptr = (ptr); \
__typeof__(x) __private_val; \
int __private_ret = -EFAULT; \
(x) = (__typeof__(*(__private_ptr)))0; \
if (__copy_from_user((__force void *)&__private_val, (__private_ptr),\
sizeof(*(__private_ptr))) == 0) { \
(x) = (__typeof__(*(__private_ptr))) __private_val; \
__private_ret = 0; \
} \
__private_ret; \
})
#define get_user(x, ptr) \
({ \
const __typeof__((*(ptr))) __user *private_ptr = (ptr); \
(access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \
__get_user(x, private_ptr) : ((x) = (__typeof__(*ptr))0, -EFAULT)); \
})
#define __put_user(x, ptr) \
({ \
__typeof__(*(ptr)) __user *__private_ptr = ptr; \
__typeof__(*(__private_ptr)) __private_val; \
int __private_ret = -EFAULT; \
__private_val = (__typeof__(*(__private_ptr))) (x); \
if (__copy_to_user((__private_ptr), &__private_val, \
sizeof(*(__private_ptr))) == 0) { \
__private_ret = 0; \
} \
__private_ret; \
})
#define put_user(x, ptr) \
({ \
__typeof__(*(ptr)) __user *private_ptr = (ptr); \
(access_ok(VERIFY_WRITE, private_ptr, sizeof(*private_ptr)) ? \
__put_user(x, private_ptr) : -EFAULT); \
})
#define strlen_user(str) strnlen_user(str, ~0U >> 1)
#include <asm-generic/uaccess.h>
struct exception_table_entry
static inline int __access_ok(unsigned long addr, unsigned long size)
{
unsigned long insn;
unsigned long fixup;
};
return __addr_range_nowrap(addr, size) &&
(__under_task_size(addr, size) ||
__access_ok_vsyscall(addr, size) ||
segment_eq(get_fs(), KERNEL_DS));
}
#endif
......@@ -40,28 +40,8 @@
typedef int (*initcall_t)(void);
typedef void (*exitcall_t)(void);
#ifndef __KERNEL__
#ifndef __section
# define __section(S) __attribute__ ((__section__(#S)))
#endif
#if __GNUC__ == 3
#if __GNUC_MINOR__ >= 3
# define __used __attribute__((__used__))
#else
# define __used __attribute__((__unused__))
#endif
#else
#if __GNUC__ == 4
# define __used __attribute__((__used__))
#endif
#endif
#else
#include <linux/compiler.h>
#endif
/* These are for everybody (although not all archs will actually
discard it in modules) */
#define __init __section(.init.text)
......@@ -131,7 +111,7 @@ extern struct uml_param __uml_setup_start, __uml_setup_end;
#define __uml_postsetup_call __used __section(.uml.postsetup.init)
#define __uml_exit_call __used __section(.uml.exitcall.exit)
#ifndef __KERNEL__
#ifdef __UM_HOST__
#define __define_initcall(level,fn) \
static initcall_t __initcall_##fn __used \
......
......@@ -301,4 +301,6 @@ extern int get_pty(void);
/* sys-$ARCH/task_size.c */
extern unsigned long os_get_top_address(void);
long syscall(long number, ...);
#endif
......@@ -17,7 +17,7 @@
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
/* This is to get size_t */
#ifdef __KERNEL__
#ifndef __UM_HOST__
#include <linux/types.h>
#else
#include <stddef.h>
......
......@@ -42,3 +42,5 @@ EXPORT_SYMBOL(os_makedev);
EXPORT_SYMBOL(add_sigio_fd);
EXPORT_SYMBOL(ignore_sigio_fd);
EXPORT_SYMBOL(sigio_broken);
EXPORT_SYMBOL(syscall);
......@@ -8,6 +8,7 @@
#include <linux/mm.h>
#include <linux/pfn.h>
#include <asm/page.h>
#include <asm/sections.h>
#include <as-layout.h>
#include <init.h>
#include <kern.h>
......@@ -55,8 +56,6 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
}
}
extern int __syscall_stub_start;
/**
* setup_physmem() - Setup physical memory for UML
* @start: Start address of the physical kernel memory,
......@@ -110,8 +109,8 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end,
* Special kludge - This page will be mapped in to userspace processes
* from physmem_fd, so it needs to be written out there.
*/
os_seek_file(physmem_fd, __pa(&__syscall_stub_start));
os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE);
os_seek_file(physmem_fd, __pa(__syscall_stub_start));
os_write_file(physmem_fd, __syscall_stub_start, PAGE_SIZE);
os_fsync_file(physmem_fd);
bootmap_size = init_bootmem(pfn, pfn + delta);
......
......@@ -8,6 +8,7 @@
#include <linux/sched.h>
#include <linux/tracehook.h>
#include <asm/uaccess.h>
#include <asm/ptrace-abi.h>
void user_enable_single_step(struct task_struct *child)
{
......@@ -131,7 +132,7 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
* XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
* PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
*/
void syscall_trace_enter(struct pt_regs *regs)
int syscall_trace_enter(struct pt_regs *regs)
{
audit_syscall_entry(UPT_SYSCALL_NR(&regs->regs),
UPT_SYSCALL_ARG1(&regs->regs),
......@@ -140,9 +141,9 @@ void syscall_trace_enter(struct pt_regs *regs)
UPT_SYSCALL_ARG4(&regs->regs));
if (!test_thread_flag(TIF_SYSCALL_TRACE))
return;
return 0;
tracehook_report_syscall_entry(regs);
return tracehook_report_syscall_entry(regs);
}
void syscall_trace_leave(struct pt_regs *regs)
......
......@@ -8,12 +8,11 @@
#include <linux/slab.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
#include <asm/sections.h>
#include <as-layout.h>
#include <os.h>
#include <skas.h>
extern int __syscall_stub_start;
static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
unsigned long kernel)
{
......@@ -93,7 +92,7 @@ void uml_setup_stubs(struct mm_struct *mm)
int err, ret;
ret = init_stub_pte(mm, STUB_CODE,
(unsigned long) &__syscall_stub_start);
(unsigned long) __syscall_stub_start);
if (ret)
goto out;
......@@ -101,7 +100,7 @@ void uml_setup_stubs(struct mm_struct *mm)
if (ret)
goto out;
mm->context.stub_pages[0] = virt_to_page(&__syscall_stub_start);
mm->context.stub_pages[0] = virt_to_page(__syscall_stub_start);
mm->context.stub_pages[1] = virt_to_page(mm->context.id.stack);
/* dup_mmap already holds mmap_sem */
......
......@@ -18,7 +18,10 @@ void handle_syscall(struct uml_pt_regs *r)
long result;
int syscall;
syscall_trace_enter(regs);
if (syscall_trace_enter(regs)) {
result = -ENOSYS;
goto out;
}
/*
* This should go in the declaration of syscall, but when I do that,
......@@ -34,6 +37,7 @@ void handle_syscall(struct uml_pt_regs *r)
result = -ENOSYS;
else result = EXECUTE_SYSCALL(syscall, regs);
out:
PT_REGS_SET_SYSCALL_RETURN(regs, result);
syscall_trace_leave(regs);
......
......@@ -87,10 +87,10 @@ static int do_op_one_page(unsigned long addr, int len, int is_write,
return n;
}
static int buffer_op(unsigned long addr, int len, int is_write,
int (*op)(unsigned long, int, void *), void *arg)
static long buffer_op(unsigned long addr, int len, int is_write,
int (*op)(unsigned long, int, void *), void *arg)
{
int size, remain, n;
long size, remain, n;
size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
remain = len;
......@@ -139,18 +139,16 @@ static int copy_chunk_from_user(unsigned long from, int len, void *arg)
return 0;
}
int copy_from_user(void *to, const void __user *from, int n)
long __copy_from_user(void *to, const void __user *from, unsigned long n)
{
if (segment_eq(get_fs(), KERNEL_DS)) {
memcpy(to, (__force void*)from, n);
return 0;
}
return access_ok(VERIFY_READ, from, n) ?
buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
n;
return buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to);
}
EXPORT_SYMBOL(copy_from_user);
EXPORT_SYMBOL(__copy_from_user);
static int copy_chunk_to_user(unsigned long to, int len, void *arg)
{
......@@ -161,18 +159,16 @@ static int copy_chunk_to_user(unsigned long to, int len, void *arg)
return 0;
}
int copy_to_user(void __user *to, const void *from, int n)
long __copy_to_user(void __user *to, const void *from, unsigned long n)
{
if (segment_eq(get_fs(), KERNEL_DS)) {
memcpy((__force void *) to, from, n);
return 0;
}
return access_ok(VERIFY_WRITE, to, n) ?
buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
n;
return buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from);
}
EXPORT_SYMBOL(copy_to_user);
EXPORT_SYMBOL(__copy_to_user);
static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
{
......@@ -188,9 +184,9 @@ static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
return 0;
}
int strncpy_from_user(char *dst, const char __user *src, int count)
long __strncpy_from_user(char *dst, const char __user *src, long count)
{
int n;
long n;
char *ptr = dst;
if (segment_eq(get_fs(), KERNEL_DS)) {
......@@ -198,16 +194,13 @@ int strncpy_from_user(char *dst, const char __user *src, int count)
return strnlen(dst, count);
}
if (!access_ok(VERIFY_READ, src, 1))
return -EFAULT;
n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
&ptr);
if (n != 0)
return -EFAULT;
return strnlen(dst, count);
}
EXPORT_SYMBOL(strncpy_from_user);
EXPORT_SYMBOL(__strncpy_from_user);
static int clear_chunk(unsigned long addr, int len, void *unused)
{
......@@ -215,22 +208,16 @@ static int clear_chunk(unsigned long addr, int len, void *unused)
return 0;
}
int __clear_user(void __user *mem, int len)
{
return buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL);
}
int clear_user(void __user *mem, int len)
unsigned long __clear_user(void __user *mem, unsigned long len)
{
if (segment_eq(get_fs(), KERNEL_DS)) {
memset((__force void*)mem, 0, len);
return 0;
}
return access_ok(VERIFY_WRITE, mem, len) ?
buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len;
return buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL);
}
EXPORT_SYMBOL(clear_user);
EXPORT_SYMBOL(__clear_user);
static int strnlen_chunk(unsigned long str, int len, void *arg)
{
......@@ -244,7 +231,7 @@ static int strnlen_chunk(unsigned long str, int len, void *arg)
return 0;
}
int strnlen_user(const void __user *str, int len)
long __strnlen_user(const void __user *str, long len)
{
int count = 0, n;
......@@ -256,4 +243,4 @@ int strnlen_user(const void __user *str, int len)
return count + 1;
return 0;
}
EXPORT_SYMBOL(strnlen_user);
EXPORT_SYMBOL(__strnlen_user);
......@@ -220,6 +220,11 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
show_regs(container_of(regs, struct pt_regs, regs));
panic("Segfault with no mm");
}
else if (!is_user && address < TASK_SIZE) {
show_regs(container_of(regs, struct pt_regs, regs));
panic("Kernel tried to access user memory at addr 0x%lx, ip 0x%lx",
address, ip);
}
if (SEGV_IS_FIXABLE(&fi))
err = handle_page_fault(address, ip, is_write, is_user,
......
......@@ -248,8 +248,6 @@ EXPORT_SYMBOL(end_iomem);
#define MIN_VMALLOC (32 * 1024 * 1024)
extern char __binary_start;
int __init linux_main(int argc, char **argv)
{
unsigned long avail, diff;
......@@ -294,7 +292,7 @@ int __init linux_main(int argc, char **argv)
physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
}
uml_physmem = (unsigned long) &__binary_start & PAGE_MASK;
uml_physmem = (unsigned long) __binary_start & PAGE_MASK;
/* Reserve up to 4M after the current brk */
uml_reserved = ROUND_4M(brk_start) + (1 << 22);
......
......@@ -47,7 +47,7 @@ static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
}
struct tuntap_pre_exec_data {
int stdout;
int stdout_fd;
int close_me;
};
......@@ -55,7 +55,7 @@ static void tuntap_pre_exec(void *arg)
{
struct tuntap_pre_exec_data *data = arg;
dup2(data->stdout, 1);
dup2(data->stdout_fd, 1);
close(data->close_me);
}
......@@ -74,7 +74,7 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
sprintf(version_buf, "%d", UML_NET_VERSION);
data.stdout = remote;
data.stdout_fd = remote;
data.close_me = me;
pid = run_helper(tuntap_pre_exec, &data, argv);
......
......@@ -13,6 +13,7 @@
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>
#include <sys/types.h>
#include <os.h>
static void copy_stat(struct uml_stat *dst, const struct stat64 *src)
......
......@@ -112,9 +112,11 @@ void timer_init(void)
void set_sigstack(void *sig_stack, int size)
{
stack_t stack = ((stack_t) { .ss_flags = 0,
.ss_sp = (__ptr_t) sig_stack,
.ss_size = size - sizeof(void *) });
stack_t stack = {
.ss_flags = 0,
.ss_sp = sig_stack,
.ss_size = size - sizeof(void *)
};
if (sigaltstack(&stack, NULL) != 0)
panic("enabling signal stack failed, errno = %d\n", errno);
......
......@@ -18,7 +18,7 @@
#include <sysdep/ptrace.h>
#include <sysdep/stub.h>
extern unsigned long batch_syscall_stub, __syscall_stub_start;
extern char batch_syscall_stub[], __syscall_stub_start[];
extern void wait_stub_done(int pid);
......@@ -38,8 +38,8 @@ static int __init init_syscall_regs(void)
{
get_safe_registers(syscall_regs, NULL);
syscall_regs[REGS_IP_INDEX] = STUB_CODE +
((unsigned long) &batch_syscall_stub -
(unsigned long) &__syscall_stub_start);
((unsigned long) batch_syscall_stub -
(unsigned long) __syscall_stub_start);
return 0;
}
......
......@@ -174,7 +174,7 @@ static void handle_trap(int pid, struct uml_pt_regs *regs,
handle_syscall(regs);
}
extern int __syscall_stub_start;
extern char __syscall_stub_start[];
static int userspace_tramp(void *stack)
{
......@@ -197,7 +197,7 @@ static int userspace_tramp(void *stack)
* This has a pte, but it can't be mapped in with the usual
* tlb_flush mechanism because this is part of that mechanism
*/
fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
fd = phys_mapping(to_phys(__syscall_stub_start), &offset);
addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE,
PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
if (addr == MAP_FAILED) {
......@@ -223,7 +223,7 @@ static int userspace_tramp(void *stack)
unsigned long v = STUB_CODE +
(unsigned long) stub_segv_handler -
(unsigned long) &__syscall_stub_start;
(unsigned long) __syscall_stub_start;
set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
sigemptyset(&sa.sa_mask);
......@@ -447,7 +447,7 @@ static int __init init_thread_regs(void)
/* Set parent's instruction pointer to start of clone-stub */
thread_regs[REGS_IP_INDEX] = STUB_CODE +
(unsigned long) stub_clone_handler -
(unsigned long) &__syscall_stub_start;
(unsigned long) __syscall_stub_start;
thread_regs[REGS_SP_INDEX] = STUB_DATA + UM_KERN_PAGE_SIZE -
sizeof(void *);
#ifdef __SIGNAL_FRAMESIZE
......
......@@ -3,6 +3,7 @@
#include <linux/string.h>
#include <linux/in6.h>
#include <linux/uaccess.h>
/*
* computes the checksum of a memory block at buff, length len,
......
......@@ -200,8 +200,6 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef struct user_i387_struct elf_fpregset_t;
#define task_pt_regs(t) (&(t)->thread.regs)
struct task_struct;
extern int elf_core_copy_fpregs(struct task_struct *t, elf_fpregset_t *fpu);
......
......@@ -28,6 +28,8 @@ static inline void rep_nop(void)
#define cpu_relax() rep_nop()
#define cpu_relax_lowlatency() cpu_relax()
#define task_pt_regs(t) (&(t)->thread.regs)
#include <asm/processor-generic.h>
#endif
......@@ -7,4 +7,12 @@ extern int host_gdt_entry_tls_min;
#define GDT_ENTRY_TLS_MIN host_gdt_entry_tls_min
#define GDT_ENTRY_TLS_MAX (GDT_ENTRY_TLS_MIN + GDT_ENTRY_TLS_ENTRIES - 1)
typedef struct {
unsigned long seg;
} mm_segment_t;
#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) })
#define KERNEL_DS MAKE_MM_SEG(~0UL)
#define USER_DS MAKE_MM_SEG(TASK_SIZE)
#endif
......@@ -6,6 +6,7 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <asm/unistd.h>
#include <os.h>
#include <skas.h>
......
......@@ -7,8 +7,7 @@
*/
#include <linux/mm.h>
#include <asm/page.h>
#include <asm/mman.h>
#include <asm/elf.h>
static struct vm_area_struct gate_vma;
......
#include <linux/mm.h>
#include <asm/page.h>
#include <asm/mman.h>
#include <asm/elf.h>
const char *arch_vma_name(struct vm_area_struct *vma)
{
......
......@@ -6,6 +6,7 @@
#include <linux/mm.h>
#include <linux/sched.h>
#include <asm/uaccess.h>
#include <asm/ptrace-abi.h>
#include <skas.h>
extern int arch_switch_tls(struct task_struct *to);
......
......@@ -11,6 +11,7 @@
#define __FRAME_OFFSETS
#include <asm/ptrace.h>
#include <asm/uaccess.h>
#include <asm/ptrace-abi.h>
/*
* determines which flags the user has access to.
......
#ifndef _SYSDEP_TLS_H
#define _SYSDEP_TLS_H
# ifndef __KERNEL__
#ifdef __UM_HOST__
/* Change name to avoid conflicts with the original one from <asm/ldt.h>, which
* may be named user_desc (but in 2.4 and in header matching its API was named
......@@ -22,11 +22,11 @@ typedef struct um_dup_user_desc {
#endif
} user_desc_t;
# else /* __KERNEL__ */
#else /* __UM_HOST__ */
typedef struct user_desc user_desc_t;
# endif /* __KERNEL__ */
#endif /* __UM_HOST__ */
extern int os_set_thread_area(user_desc_t *info, int pid);
extern int os_get_thread_area(user_desc_t *info, int pid);
......
......@@ -541,7 +541,8 @@ int setup_signal_stack_si(unsigned long stack_top, struct ksignal *ksig,
*/
/* x86-64 should always use SA_RESTORER. */
if (ksig->ka.sa.sa_flags & SA_RESTORER)
err |= __put_user(ksig->ka.sa.sa_restorer, &frame->pretcode);
err |= __put_user((void *)ksig->ka.sa.sa_restorer,
&frame->pretcode);
else
/* could use a vstub here */
return err;
......
......@@ -6,6 +6,7 @@
*/
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <asm/prctl.h> /* XXX This should get the constants from libc */
#include <os.h>
......
......@@ -7,6 +7,7 @@
#include <linux/sched.h>
#include <linux/syscalls.h>
#include <asm/uaccess.h>
#include <asm/ptrace-abi.h>
#include <os.h>
#include <skas.h>
#include <sysdep/tls.h>
......
#include <linux/sched.h>
#include <asm/ptrace-abi.h>
void clear_flushed_tls(struct task_struct *task)
{
......
......@@ -10,6 +10,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <asm/page.h>
#include <asm/elf.h>
#include <linux/init.h>
static unsigned int __read_mostly vdso_enabled = 1;
......
......@@ -115,7 +115,6 @@ obj-$(CONFIG_AFS_FS) += afs/
obj-$(CONFIG_NILFS2_FS) += nilfs2/
obj-$(CONFIG_BEFS_FS) += befs/
obj-$(CONFIG_HOSTFS) += hostfs/
obj-$(CONFIG_HPPFS) += hppfs/
obj-$(CONFIG_CACHEFILES) += cachefiles/
obj-$(CONFIG_DEBUG_FS) += debugfs/
obj-$(CONFIG_TRACING) += tracefs/
......
#
# Copyright (C) 2002 - 2008 Jeff Dike (jdike@{addtoit,linux.intel}.com)
# Licensed under the GPL
#
obj-$(CONFIG_HPPFS) += hppfs.o
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment