Revert the rest of the COMPAT_MODE changes (back to hrev52003.)
This reverts commit458e758f37. This reverts commitce5eb94a82. This reverts commitaac8d4c317. This reverts commitc70cba914a. This reverts commit2ffbe7aacaThis reverts commitc6e120e2d2.
This commit is contained in:
@@ -31,12 +31,6 @@ bool arch_on_signal_stack(Thread *thread);
|
|||||||
status_t arch_setup_signal_frame(Thread *thread, struct sigaction *action,
|
status_t arch_setup_signal_frame(Thread *thread, struct sigaction *action,
|
||||||
struct signal_frame_data *signalFrameData);
|
struct signal_frame_data *signalFrameData);
|
||||||
int64 arch_restore_signal_frame(struct signal_frame_data* signalFrameData);
|
int64 arch_restore_signal_frame(struct signal_frame_data* signalFrameData);
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
status_t arch_setup_compat_signal_frame(Thread *thread,
|
|
||||||
struct sigaction *action, struct compat_signal_frame_data *signalFrameData);
|
|
||||||
int64 arch_restore_compat_signal_frame(
|
|
||||||
struct compat_signal_frame_data* signalFrameData);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void arch_store_fork_frame(struct arch_fork_arg *arg);
|
void arch_store_fork_frame(struct arch_fork_arg *arg);
|
||||||
void arch_restore_fork_frame(struct arch_fork_arg *arg);
|
void arch_restore_fork_frame(struct arch_fork_arg *arg);
|
||||||
|
|||||||
@@ -51,30 +51,6 @@ arch_thread_set_current_thread(Thread* t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
arch_thread_set_ds(unsigned short ds)
|
|
||||||
{
|
|
||||||
asm volatile("mov %0, %%ds" : : "r" (ds) : "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
arch_thread_set_es(unsigned short es)
|
|
||||||
{
|
|
||||||
asm volatile("mov %0, %%es" : : "r" (es) : "memory");
|
|
||||||
}
|
|
||||||
|
|
||||||
// override empty macro
|
|
||||||
#undef arch_syscall_64_bit_return_value
|
|
||||||
void arch_syscall_64_bit_return_value(void);
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _COMPAT_MODE
|
|
||||||
|
|
||||||
|
|
||||||
#else // __x86_64__
|
#else // __x86_64__
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,277 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef _KERNEL_COMPAT_OS_H
|
|
||||||
#define _KERNEL_COMPAT_OS_H
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bigtime_t boot_time; /* time of boot (usecs since 1/1/1970) */
|
|
||||||
|
|
||||||
uint32 cpu_count; /* number of cpus */
|
|
||||||
|
|
||||||
uint64 max_pages; /* total # of accessible pages */
|
|
||||||
uint64 used_pages; /* # of accessible pages in use */
|
|
||||||
uint64 cached_pages;
|
|
||||||
uint64 block_cache_pages;
|
|
||||||
uint64 ignored_pages; /* # of ignored/inaccessible pages */
|
|
||||||
|
|
||||||
uint64 needed_memory;
|
|
||||||
uint64 free_memory;
|
|
||||||
|
|
||||||
uint64 max_swap_pages;
|
|
||||||
uint64 free_swap_pages;
|
|
||||||
|
|
||||||
uint32 page_faults; /* # of page faults */
|
|
||||||
|
|
||||||
uint32 max_sems;
|
|
||||||
uint32 used_sems;
|
|
||||||
|
|
||||||
uint32 max_ports;
|
|
||||||
uint32 used_ports;
|
|
||||||
|
|
||||||
uint32 max_threads;
|
|
||||||
uint32 used_threads;
|
|
||||||
|
|
||||||
uint32 max_teams;
|
|
||||||
uint32 used_teams;
|
|
||||||
|
|
||||||
char kernel_name[B_FILE_NAME_LENGTH];
|
|
||||||
char kernel_build_date[B_OS_NAME_LENGTH];
|
|
||||||
char kernel_build_time[B_OS_NAME_LENGTH];
|
|
||||||
|
|
||||||
int64 kernel_version;
|
|
||||||
uint32 abi; /* the system API */
|
|
||||||
} _PACKED compat_system_info;
|
|
||||||
|
|
||||||
|
|
||||||
static_assert(sizeof(compat_system_info) == 0x1c4,
|
|
||||||
"size of compat_system_info mismatch");
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(system_info &info, system_info* userInfo)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userInfo))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
compat_system_info compat_info;
|
|
||||||
compat_info.boot_time = info.boot_time;
|
|
||||||
compat_info.cpu_count = info.cpu_count;
|
|
||||||
compat_info.max_pages = info.max_pages;
|
|
||||||
compat_info.used_pages = info.used_pages;
|
|
||||||
compat_info.cached_pages = info.cached_pages;
|
|
||||||
compat_info.block_cache_pages = info.block_cache_pages;
|
|
||||||
compat_info.ignored_pages = info.ignored_pages;
|
|
||||||
compat_info.needed_memory = info.needed_memory;
|
|
||||||
compat_info.free_memory = info.free_memory;
|
|
||||||
compat_info.needed_memory = info.needed_memory;
|
|
||||||
compat_info.max_swap_pages = info.max_swap_pages;
|
|
||||||
compat_info.free_swap_pages = info.free_swap_pages;
|
|
||||||
compat_info.max_sems = info.max_sems;
|
|
||||||
compat_info.used_sems = info.used_sems;
|
|
||||||
compat_info.max_ports = info.max_ports;
|
|
||||||
compat_info.used_ports = info.used_ports;
|
|
||||||
compat_info.max_threads = info.max_threads;
|
|
||||||
compat_info.used_threads = info.used_threads;
|
|
||||||
compat_info.max_teams = info.max_teams;
|
|
||||||
compat_info.used_teams = info.used_teams;
|
|
||||||
strlcpy(compat_info.kernel_name, info.kernel_name, B_FILE_NAME_LENGTH);
|
|
||||||
strlcpy(compat_info.kernel_build_date, info.kernel_build_date,
|
|
||||||
B_OS_NAME_LENGTH);
|
|
||||||
strlcpy(compat_info.kernel_build_time, info.kernel_build_time,
|
|
||||||
B_OS_NAME_LENGTH);
|
|
||||||
compat_info.kernel_version = info.kernel_version;
|
|
||||||
compat_info.abi = info.abi;
|
|
||||||
if (user_memcpy(userInfo, &compat_info, sizeof(compat_info)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
} else if (user_memcpy(userInfo, &info, sizeof(system_info)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#define compat_size_t uint32
|
|
||||||
#define compat_ptr_t uint32
|
|
||||||
typedef struct compat_area_info {
|
|
||||||
area_id area;
|
|
||||||
char name[B_OS_NAME_LENGTH];
|
|
||||||
compat_size_t size;
|
|
||||||
uint32 lock;
|
|
||||||
uint32 protection;
|
|
||||||
team_id team;
|
|
||||||
uint32 ram_size;
|
|
||||||
uint32 copy_count;
|
|
||||||
uint32 in_count;
|
|
||||||
uint32 out_count;
|
|
||||||
compat_ptr_t address;
|
|
||||||
} _PACKED compat_area_info;
|
|
||||||
|
|
||||||
|
|
||||||
static_assert(sizeof(compat_area_info) == 0x48,
|
|
||||||
"size of compat_area_info mismatch");
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(area_info &info, area_info* userInfo)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userInfo))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
compat_area_info compatInfo;
|
|
||||||
compatInfo.area = info.area;
|
|
||||||
strlcpy(compatInfo.name, info.name, B_OS_NAME_LENGTH);
|
|
||||||
compatInfo.size = info.size;
|
|
||||||
compatInfo.lock = info.lock;
|
|
||||||
compatInfo.protection = info.protection;
|
|
||||||
compatInfo.team = info.team;
|
|
||||||
compatInfo.ram_size = info.ram_size;
|
|
||||||
compatInfo.copy_count = info.copy_count;
|
|
||||||
compatInfo.in_count = info.in_count;
|
|
||||||
compatInfo.out_count = info.out_count;
|
|
||||||
compatInfo.address = (compat_ptr_t)(addr_t)info.address;
|
|
||||||
if (user_memcpy(userInfo, &compatInfo, sizeof(compatInfo)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
} else if (user_memcpy(userInfo, &info, sizeof(info)) < B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
thread_id thread;
|
|
||||||
team_id team;
|
|
||||||
char name[B_OS_NAME_LENGTH];
|
|
||||||
thread_state state;
|
|
||||||
int32 priority;
|
|
||||||
sem_id sem;
|
|
||||||
bigtime_t user_time;
|
|
||||||
bigtime_t kernel_time;
|
|
||||||
uint32 stack_base;
|
|
||||||
uint32 stack_end;
|
|
||||||
} _PACKED compat_thread_info;
|
|
||||||
|
|
||||||
|
|
||||||
static_assert(sizeof(compat_thread_info) == 76,
|
|
||||||
"size of compat_thread_info mismatch");
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(void* &addr, void** userAddr)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userAddr))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
compat_ptr_t compatAddr = (uint32)(addr_t)addr;
|
|
||||||
if (user_memcpy(userAddr, &compatAddr, sizeof(compatAddr)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
} else if (user_memcpy(userAddr, &addr, sizeof(addr)) < B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_from_user(void** userAddr, void* &addr)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userAddr))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
compat_ptr_t compatAddr;
|
|
||||||
if (user_memcpy(&compatAddr, userAddr, sizeof(compatAddr)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
addr = (void*)(addr_t)compatAddr;
|
|
||||||
} else if (user_memcpy(&addr, userAddr, sizeof(addr)) < B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(addr_t &addr, addr_t* userAddr)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userAddr))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
uint32 compatAddr = (uint32)addr;
|
|
||||||
if (user_memcpy(userAddr, &compatAddr, sizeof(compatAddr)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
} else if (user_memcpy(userAddr, &addr, sizeof(addr)) < B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_from_user(addr_t* userAddr, addr_t &addr)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userAddr))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
uint32 compatAddr;
|
|
||||||
if (user_memcpy(&compatAddr, userAddr, sizeof(compatAddr)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
addr = (addr_t)compatAddr;
|
|
||||||
} else if (user_memcpy(&addr, userAddr, sizeof(addr)) < B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(ssize_t &size, ssize_t* userSize)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userSize))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
int32 compatSize = (int32)size;
|
|
||||||
if (user_memcpy(userSize, &compatSize, sizeof(compatSize)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
} else if (user_memcpy(userSize, &size, sizeof(size)) < B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_from_user(ssize_t* userSize, ssize_t &size)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userSize))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
int32 compatSize;
|
|
||||||
if (user_memcpy(&compatSize, userSize, sizeof(compatSize)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
size = (ssize_t)compatSize;
|
|
||||||
} else if (user_memcpy(&size, userSize, sizeof(size)) < B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _KERNEL_COMPAT_OS_H
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef _KERNEL_COMPAT_ARCH_SIGNAL_H
|
|
||||||
#define _KERNEL_COMPAT_ARCH_SIGNAL_H
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct packed_fp_stack {
|
|
||||||
unsigned char st0[10];
|
|
||||||
unsigned char st1[10];
|
|
||||||
unsigned char st2[10];
|
|
||||||
unsigned char st3[10];
|
|
||||||
unsigned char st4[10];
|
|
||||||
unsigned char st5[10];
|
|
||||||
unsigned char st6[10];
|
|
||||||
unsigned char st7[10];
|
|
||||||
} packed_fp_stack;
|
|
||||||
|
|
||||||
typedef struct packed_mmx_regs {
|
|
||||||
unsigned char mm0[10];
|
|
||||||
unsigned char mm1[10];
|
|
||||||
unsigned char mm2[10];
|
|
||||||
unsigned char mm3[10];
|
|
||||||
unsigned char mm4[10];
|
|
||||||
unsigned char mm5[10];
|
|
||||||
unsigned char mm6[10];
|
|
||||||
unsigned char mm7[10];
|
|
||||||
} packed_mmx_regs;
|
|
||||||
|
|
||||||
typedef struct xmmx_regs {
|
|
||||||
unsigned char xmm0[16];
|
|
||||||
unsigned char xmm1[16];
|
|
||||||
unsigned char xmm2[16];
|
|
||||||
unsigned char xmm3[16];
|
|
||||||
unsigned char xmm4[16];
|
|
||||||
unsigned char xmm5[16];
|
|
||||||
unsigned char xmm6[16];
|
|
||||||
unsigned char xmm7[16];
|
|
||||||
} xmmx_regs;
|
|
||||||
|
|
||||||
typedef struct compat_stack_t {
|
|
||||||
uint32 ss_sp;
|
|
||||||
uint32 ss_size;
|
|
||||||
int ss_flags;
|
|
||||||
} compat_stack_t;
|
|
||||||
|
|
||||||
typedef struct compat_old_extended_regs {
|
|
||||||
unsigned short fp_control;
|
|
||||||
unsigned short _reserved1;
|
|
||||||
unsigned short fp_status;
|
|
||||||
unsigned short _reserved2;
|
|
||||||
unsigned short fp_tag;
|
|
||||||
unsigned short _reserved3;
|
|
||||||
uint32 fp_eip;
|
|
||||||
unsigned short fp_cs;
|
|
||||||
unsigned short fp_opcode;
|
|
||||||
uint32 fp_datap;
|
|
||||||
unsigned short fp_ds;
|
|
||||||
unsigned short _reserved4;
|
|
||||||
union {
|
|
||||||
packed_fp_stack fp;
|
|
||||||
packed_mmx_regs mmx;
|
|
||||||
} fp_mmx;
|
|
||||||
} compat_old_extended_regs;
|
|
||||||
|
|
||||||
typedef struct compat_new_extended_regs {
|
|
||||||
unsigned short fp_control;
|
|
||||||
unsigned short fp_status;
|
|
||||||
unsigned short fp_tag;
|
|
||||||
unsigned short fp_opcode;
|
|
||||||
uint32 fp_eip;
|
|
||||||
unsigned short fp_cs;
|
|
||||||
unsigned short res_14_15;
|
|
||||||
uint32 fp_datap;
|
|
||||||
unsigned short fp_ds;
|
|
||||||
unsigned short _reserved_22_23;
|
|
||||||
uint32 mxcsr;
|
|
||||||
uint32 _reserved_28_31;
|
|
||||||
union {
|
|
||||||
fp_stack fp;
|
|
||||||
mmx_regs mmx;
|
|
||||||
} fp_mmx;
|
|
||||||
xmmx_regs xmmx;
|
|
||||||
unsigned char _reserved_288_511[224];
|
|
||||||
} compat_new_extended_regs;
|
|
||||||
|
|
||||||
typedef struct compat_extended_regs {
|
|
||||||
union {
|
|
||||||
compat_old_extended_regs old_format;
|
|
||||||
compat_new_extended_regs new_format;
|
|
||||||
} state;
|
|
||||||
uint32 format;
|
|
||||||
} compat_extended_regs;
|
|
||||||
|
|
||||||
struct compat_vregs {
|
|
||||||
uint32 eip;
|
|
||||||
uint32 eflags;
|
|
||||||
uint32 eax;
|
|
||||||
uint32 ecx;
|
|
||||||
uint32 edx;
|
|
||||||
uint32 esp;
|
|
||||||
uint32 ebp;
|
|
||||||
uint32 _reserved_1;
|
|
||||||
compat_extended_regs xregs;
|
|
||||||
uint32 edi;
|
|
||||||
uint32 esi;
|
|
||||||
uint32 ebx;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _KERNEL_COMPAT_ARCH_SIGNAL_H
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef _KERNEL_COMPAT_FCNTL_H
|
|
||||||
#define _KERNEL_COMPAT_FCNTL_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
|
|
||||||
struct compat_flock {
|
|
||||||
short l_type;
|
|
||||||
short l_whence;
|
|
||||||
off_t l_start;
|
|
||||||
off_t l_len;
|
|
||||||
pid_t l_pid;
|
|
||||||
} _PACKED;
|
|
||||||
|
|
||||||
|
|
||||||
static_assert(sizeof(struct compat_flock) == 24,
|
|
||||||
"size of compat_flock mismatch");
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_from_user(struct flock* userFlock, struct flock &flock)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userFlock))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
compat_flock compat_flock;
|
|
||||||
if (user_memcpy(&compat_flock, userFlock, sizeof(compat_flock)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
flock.l_type = compat_flock.l_type;
|
|
||||||
flock.l_whence = compat_flock.l_whence;
|
|
||||||
flock.l_start = compat_flock.l_start;
|
|
||||||
flock.l_len = compat_flock.l_len;
|
|
||||||
flock.l_pid = compat_flock.l_pid;
|
|
||||||
} else {
|
|
||||||
if (user_memcpy(&flock, userFlock, sizeof(struct flock)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(struct flock &flock, struct flock* userFlock)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userFlock))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
compat_flock compat_flock;
|
|
||||||
compat_flock.l_type = flock.l_type;
|
|
||||||
compat_flock.l_whence = flock.l_whence;
|
|
||||||
compat_flock.l_start = flock.l_start;
|
|
||||||
compat_flock.l_len = flock.l_len;
|
|
||||||
compat_flock.l_pid = flock.l_pid;
|
|
||||||
if (user_memcpy(userFlock, &compat_flock, sizeof(compat_flock)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
} else {
|
|
||||||
if (user_memcpy(userFlock, &flock, sizeof(flock)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _KERNEL_COMPAT_FCNTL_H
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef _KERNEL_COMPAT_FS_ATTR_H
|
|
||||||
#define _KERNEL_COMPAT_FS_ATTR_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <fs_attr.h>
|
|
||||||
|
|
||||||
|
|
||||||
struct compat_attr_info {
|
|
||||||
uint32 type;
|
|
||||||
off_t size;
|
|
||||||
} _PACKED;
|
|
||||||
|
|
||||||
|
|
||||||
static_assert(sizeof(compat_attr_info) == 12,
|
|
||||||
"size of compat_attr_info mismatch");
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(attr_info &info, attr_info* userInfo)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userInfo))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
compat_attr_info compat_info;
|
|
||||||
compat_info.type = info.type;
|
|
||||||
compat_info.size = info.size;
|
|
||||||
if (user_memcpy(userInfo, &compat_info, sizeof(compat_info)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
} else {
|
|
||||||
if (user_memcpy(userInfo, &info, sizeof(info)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _KERNEL_COMPAT_FS_ATTR_H
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef _KERNEL_COMPAT_FS_INFO_H
|
|
||||||
#define _KERNEL_COMPAT_FS_INFO_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <fs_info.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct compat_fs_info {
|
|
||||||
dev_t dev; /* volume dev_t */
|
|
||||||
ino_t root; /* root ino_t */
|
|
||||||
uint32 flags; /* flags (see above) */
|
|
||||||
off_t block_size; /* fundamental block size */
|
|
||||||
off_t io_size; /* optimal i/o size */
|
|
||||||
off_t total_blocks; /* total number of blocks */
|
|
||||||
off_t free_blocks; /* number of free blocks */
|
|
||||||
off_t total_nodes; /* total number of nodes */
|
|
||||||
off_t free_nodes; /* number of free nodes */
|
|
||||||
char device_name[128]; /* device holding fs */
|
|
||||||
char volume_name[B_FILE_NAME_LENGTH]; /* volume name */
|
|
||||||
char fsh_name[B_OS_NAME_LENGTH]; /* name of fs handler */
|
|
||||||
} _PACKED compat_fs_info;
|
|
||||||
|
|
||||||
|
|
||||||
static_assert(sizeof(compat_fs_info) == 480,
|
|
||||||
"size of compat_fs_info mismatch");
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(fs_info &info, fs_info* userInfo)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userInfo))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
compat_fs_info compat_info;
|
|
||||||
compat_info.dev = info.dev;
|
|
||||||
compat_info.root = info.root;
|
|
||||||
compat_info.flags = info.flags;
|
|
||||||
compat_info.block_size = info.block_size;
|
|
||||||
compat_info.io_size = info.io_size;
|
|
||||||
compat_info.total_blocks = info.total_blocks;
|
|
||||||
compat_info.free_blocks = info.free_blocks;
|
|
||||||
compat_info.total_nodes = info.total_nodes;
|
|
||||||
compat_info.free_nodes = info.free_nodes;
|
|
||||||
strlcpy(compat_info.device_name, info.device_name, 128);
|
|
||||||
strlcpy(compat_info.volume_name, info.volume_name, B_FILE_NAME_LENGTH);
|
|
||||||
strlcpy(compat_info.fsh_name, info.fsh_name, B_OS_NAME_LENGTH);
|
|
||||||
if (user_memcpy(userInfo, &compat_info, sizeof(compat_info)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
} else {
|
|
||||||
if (user_memcpy(userInfo, &info, sizeof(info)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_from_user(fs_info* userInfo, fs_info &info)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userInfo))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
compat_fs_info compat_info;
|
|
||||||
if (user_memcpy(&compat_info, userInfo, sizeof(compat_info)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
info.dev = compat_info.dev;
|
|
||||||
info.root = compat_info.root;
|
|
||||||
info.flags = compat_info.flags;
|
|
||||||
info.block_size = compat_info.block_size;
|
|
||||||
info.io_size = compat_info.io_size;
|
|
||||||
info.total_blocks = compat_info.total_blocks;
|
|
||||||
info.free_blocks = compat_info.free_blocks;
|
|
||||||
info.total_nodes = compat_info.total_nodes;
|
|
||||||
info.free_nodes = compat_info.free_nodes;
|
|
||||||
strlcpy(info.device_name, compat_info.device_name, 128);
|
|
||||||
strlcpy(info.volume_name, compat_info.volume_name, B_FILE_NAME_LENGTH);
|
|
||||||
strlcpy(info.fsh_name, compat_info.fsh_name, B_OS_NAME_LENGTH);
|
|
||||||
} else if (user_memcpy(&info, userInfo, sizeof(info)) < B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _KERNEL_COMPAT_FS_INFO_H
|
|
||||||
@@ -1,129 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef _KERNEL_COMPAT_IMAGE_H
|
|
||||||
#define _KERNEL_COMPAT_IMAGE_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <image.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define compat_uintptr_t uint32
|
|
||||||
typedef struct {
|
|
||||||
image_id id;
|
|
||||||
image_type type;
|
|
||||||
int32 sequence;
|
|
||||||
int32 init_order;
|
|
||||||
compat_uintptr_t init_routine;
|
|
||||||
compat_uintptr_t term_routine;
|
|
||||||
dev_t device;
|
|
||||||
ino_t node;
|
|
||||||
char name[MAXPATHLEN];
|
|
||||||
compat_uintptr_t text;
|
|
||||||
compat_uintptr_t data;
|
|
||||||
int32 text_size;
|
|
||||||
int32 data_size;
|
|
||||||
|
|
||||||
/* Haiku R1 extensions */
|
|
||||||
int32 api_version; /* the Haiku API version used by the image */
|
|
||||||
int32 abi; /* the Haiku ABI used by the image */
|
|
||||||
} _PACKED compat_image_info;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
compat_image_info basic_info;
|
|
||||||
int32 text_delta;
|
|
||||||
compat_uintptr_t symbol_table;
|
|
||||||
compat_uintptr_t symbol_hash;
|
|
||||||
compat_uintptr_t string_table;
|
|
||||||
} _PACKED compat_extended_image_info;
|
|
||||||
|
|
||||||
|
|
||||||
static_assert(sizeof(compat_image_info) == 1084,
|
|
||||||
"size of compat_image_info mismatch");
|
|
||||||
static_assert(sizeof(compat_extended_image_info) == 1100,
|
|
||||||
"size of compat_extended_image_info mismatch");
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(image_info &info, image_info* userInfo, size_t size)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userInfo))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
if (size > sizeof(compat_image_info))
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
compat_image_info compat_info;
|
|
||||||
compat_info.id = info.id;
|
|
||||||
compat_info.type = info.type;
|
|
||||||
compat_info.sequence = info.sequence;
|
|
||||||
compat_info.init_order = info.init_order;
|
|
||||||
compat_info.init_routine = (uint32)(addr_t)info.init_routine;
|
|
||||||
compat_info.term_routine = (uint32)(addr_t)info.term_routine;
|
|
||||||
compat_info.device = info.device;
|
|
||||||
compat_info.node = info.node;
|
|
||||||
strlcpy(compat_info.name, info.name, MAXPATHLEN);
|
|
||||||
compat_info.text = (uint32)(addr_t)info.text;
|
|
||||||
compat_info.data = (uint32)(addr_t)info.data;
|
|
||||||
compat_info.text_size = info.text_size;
|
|
||||||
compat_info.data_size = info.data_size;
|
|
||||||
if (user_memcpy(userInfo, &compat_info, size) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
} else {
|
|
||||||
if (size > sizeof(image_info))
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
if (user_memcpy(userInfo, &info, size) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_from_user(extended_image_info* userInfo,
|
|
||||||
extended_image_info &info, size_t size)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userInfo))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
compat_extended_image_info compat_info;
|
|
||||||
if (size != sizeof(compat_info))
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
if (user_memcpy(&compat_info, userInfo, size) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
info.basic_info.id = compat_info.basic_info.id;
|
|
||||||
info.basic_info.type = compat_info.basic_info.type;
|
|
||||||
info.basic_info.sequence = compat_info.basic_info.sequence;
|
|
||||||
info.basic_info.init_order = compat_info.basic_info.init_order;
|
|
||||||
info.basic_info.init_routine = (void(*)())(addr_t)compat_info.basic_info.init_routine;
|
|
||||||
info.basic_info.term_routine = (void(*)())(addr_t)compat_info.basic_info.term_routine;
|
|
||||||
info.basic_info.device = compat_info.basic_info.device;
|
|
||||||
info.basic_info.node = compat_info.basic_info.node;
|
|
||||||
strlcpy(info.basic_info.name, compat_info.basic_info.name, MAXPATHLEN);
|
|
||||||
info.basic_info.text = (void*)(addr_t)compat_info.basic_info.text;
|
|
||||||
info.basic_info.data = (void*)(addr_t)compat_info.basic_info.data;
|
|
||||||
info.basic_info.text_size = compat_info.basic_info.text_size;
|
|
||||||
info.basic_info.data_size = compat_info.basic_info.data_size;
|
|
||||||
info.text_delta = compat_info.text_delta;
|
|
||||||
info.symbol_table = (void*)(addr_t)compat_info.symbol_table;
|
|
||||||
info.symbol_hash = (void*)(addr_t)compat_info.symbol_hash;
|
|
||||||
info.string_table = (void*)(addr_t)compat_info.string_table;
|
|
||||||
} else {
|
|
||||||
if (size != sizeof(info))
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
if (user_memcpy(&info, userInfo, size) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _KERNEL_COMPAT_IMAGE_H
|
|
||||||
@@ -1,165 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef _KERNEL_COMPAT_KSIGNAL_H
|
|
||||||
#define _KERNEL_COMPAT_KSIGNAL_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <compat/signal_compat.h>
|
|
||||||
#include <compat/arch/x86/signal_compat.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct compat_vregs compat_mcontext_t;
|
|
||||||
|
|
||||||
typedef struct __compat_ucontext_t {
|
|
||||||
uint32 uc_link;
|
|
||||||
sigset_t uc_sigmask;
|
|
||||||
compat_stack_t uc_stack;
|
|
||||||
compat_mcontext_t uc_mcontext;
|
|
||||||
} _PACKED compat_ucontext_t;
|
|
||||||
|
|
||||||
union compat_sigval {
|
|
||||||
int sival_int;
|
|
||||||
uint32 sival_ptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct __compat_siginfo_t {
|
|
||||||
int si_signo; /* signal number */
|
|
||||||
int si_code; /* signal code */
|
|
||||||
int si_errno; /* if non zero, an error number associated with
|
|
||||||
this signal */
|
|
||||||
pid_t si_pid; /* sending process ID */
|
|
||||||
uid_t si_uid; /* real user ID of sending process */
|
|
||||||
uint32 si_addr; /* address of faulting instruction */
|
|
||||||
int si_status; /* exit value or signal */
|
|
||||||
uint32 si_band; /* band event for SIGPOLL */
|
|
||||||
union compat_sigval si_value; /* signal value */
|
|
||||||
} compat_siginfo_t;
|
|
||||||
|
|
||||||
|
|
||||||
struct compat_signal_frame_data {
|
|
||||||
compat_siginfo_t info;
|
|
||||||
compat_ucontext_t context;
|
|
||||||
uint32 user_data;
|
|
||||||
uint32 handler;
|
|
||||||
bool siginfo_handler;
|
|
||||||
char _pad[3];
|
|
||||||
int32 thread_flags;
|
|
||||||
uint64 syscall_restart_return_value;
|
|
||||||
uint8 syscall_restart_parameters[SYSCALL_RESTART_PARAMETER_SIZE];
|
|
||||||
uint32 commpage_address;
|
|
||||||
} _PACKED;
|
|
||||||
|
|
||||||
|
|
||||||
static_assert(sizeof(compat_stack_t) == 12,
|
|
||||||
"size of compat_stack_t mismatch");
|
|
||||||
static_assert(sizeof(compat_mcontext_t) == 560,
|
|
||||||
"size of compat_mcontext_t mismatch");
|
|
||||||
static_assert(sizeof(compat_ucontext_t) == 584,
|
|
||||||
"size of compat_ucontext_t mismatch");
|
|
||||||
static_assert(sizeof(compat_siginfo_t) == 36,
|
|
||||||
"size of compat_siginfo_t mismatch");
|
|
||||||
static_assert(sizeof(struct compat_signal_frame_data) == 680,
|
|
||||||
"size of compat_signal_frame_data mismatch");
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_from_user(union sigval* userSigval, union sigval &sigval)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userSigval))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
compat_sigval compat_sigval;
|
|
||||||
if (user_memcpy(&compat_sigval, userSigval, sizeof(compat_sigval))
|
|
||||||
< B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
sigval.sival_ptr = (void*)(addr_t)compat_sigval.sival_ptr;
|
|
||||||
} else if (user_memcpy(&sigval, userSigval, sizeof(union sigval)) < B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(siginfo_t &info, siginfo_t* userInfo)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userInfo))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
compat_siginfo_t compat_info;
|
|
||||||
compat_info.si_signo = info.si_signo;
|
|
||||||
compat_info.si_code = info.si_code;
|
|
||||||
compat_info.si_errno = info.si_errno;
|
|
||||||
compat_info.si_pid = info.si_pid;
|
|
||||||
compat_info.si_uid = info.si_uid;
|
|
||||||
compat_info.si_addr = (addr_t)info.si_addr;
|
|
||||||
compat_info.si_status = info.si_status;
|
|
||||||
compat_info.si_band = info.si_band;
|
|
||||||
compat_info.si_value.sival_ptr = (addr_t)info.si_value.sival_ptr;
|
|
||||||
if (user_memcpy(userInfo, &compat_info, sizeof(compat_info))
|
|
||||||
< B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
} else if (user_memcpy(userInfo, &info, sizeof(info)) < B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_from_user(stack_t* userStack, stack_t &stack)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userStack))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
compat_stack_t compatStack;
|
|
||||||
if (user_memcpy(&compatStack, userStack, sizeof(compatStack))
|
|
||||||
< B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
stack.ss_sp = (void*)(addr_t)compatStack.ss_sp;
|
|
||||||
stack.ss_size = compatStack.ss_size;
|
|
||||||
stack.ss_flags = compatStack.ss_flags;
|
|
||||||
} else if (user_memcpy(&stack, userStack, sizeof(stack_t)) < B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(stack_t &stack, stack_t* userStack)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userStack))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
compat_stack_t compatStack;
|
|
||||||
compatStack.ss_sp = (addr_t)stack.ss_sp;
|
|
||||||
compatStack.ss_size = stack.ss_size;
|
|
||||||
compatStack.ss_flags = stack.ss_flags;
|
|
||||||
if (user_memcpy(userStack, &compatStack, sizeof(compatStack))
|
|
||||||
< B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
} else if (user_memcpy(userStack, &stack, sizeof(stack)) < B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _KERNEL_COMPAT_KSIGNAL_H
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef _KERNEL_COMPAT_SIGNAL_H
|
|
||||||
#define _KERNEL_COMPAT_SIGNAL_H
|
|
||||||
|
|
||||||
|
|
||||||
struct compat_sigaction {
|
|
||||||
union {
|
|
||||||
uint32 sa_handler;
|
|
||||||
uint32 sa_sigaction;
|
|
||||||
};
|
|
||||||
sigset_t sa_mask;
|
|
||||||
int sa_flags;
|
|
||||||
uint32 sa_userdata; /* will be passed to the signal
|
|
||||||
handler, BeOS extension */
|
|
||||||
} _PACKED;
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_from_user(struct sigaction* userAction, struct sigaction &action)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userAction))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
struct compat_sigaction compat_action;
|
|
||||||
if (user_memcpy(&compat_action, userAction, sizeof(compat_sigaction))
|
|
||||||
< B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
action.sa_handler = (__sighandler_t)(addr_t)compat_action.sa_handler;
|
|
||||||
action.sa_mask = compat_action.sa_mask;
|
|
||||||
action.sa_flags = compat_action.sa_flags;
|
|
||||||
action.sa_userdata = (void*)(addr_t)compat_action.sa_userdata;
|
|
||||||
} else if (user_memcpy(&action, userAction, sizeof(action)) < B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(struct sigaction &action, struct sigaction* userAction)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userAction))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
struct compat_sigaction compat_action;
|
|
||||||
compat_action.sa_handler = (addr_t)action.sa_handler;
|
|
||||||
compat_action.sa_mask = action.sa_mask;
|
|
||||||
compat_action.sa_flags = action.sa_flags;
|
|
||||||
compat_action.sa_userdata = (addr_t)action.sa_userdata;
|
|
||||||
if (user_memcpy(userAction, &compat_action, sizeof(compat_action))
|
|
||||||
< B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
} else if (user_memcpy(userAction, &action, sizeof(action)) < B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _KERNEL_COMPAT_SIGNAL_H
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef _KERNEL_COMPAT_STAT_H
|
|
||||||
#define _KERNEL_COMPAT_STAT_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <time_compat.h>
|
|
||||||
|
|
||||||
|
|
||||||
struct compat_stat {
|
|
||||||
dev_t st_dev; /* device ID that this file resides on */
|
|
||||||
ino_t st_ino; /* this file's serial inode ID */
|
|
||||||
mode_t st_mode; /* file mode (rwx for user, group, etc) */
|
|
||||||
nlink_t st_nlink; /* number of hard links to this file */
|
|
||||||
uid_t st_uid; /* user ID of the owner of this file */
|
|
||||||
gid_t st_gid; /* group ID of the owner of this file */
|
|
||||||
off_t st_size; /* size in bytes of this file */
|
|
||||||
dev_t st_rdev; /* device type (not used) */
|
|
||||||
blksize_t st_blksize; /* preferred block size for I/O */
|
|
||||||
struct compat_timespec st_atim; /* last access time */
|
|
||||||
struct compat_timespec st_mtim; /* last modification time */
|
|
||||||
struct compat_timespec st_ctim; /* last change time, not creation time */
|
|
||||||
struct compat_timespec st_crtim; /* creation time */
|
|
||||||
__haiku_uint32 st_type; /* attribute/index type */
|
|
||||||
blkcnt_t st_blocks; /* number of blocks allocated for object */
|
|
||||||
} _PACKED;
|
|
||||||
|
|
||||||
|
|
||||||
static_assert(sizeof(struct compat_stat) == 88,
|
|
||||||
"size of struct compat_stat mismatch");
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(struct stat &stat, struct stat* userStat, size_t size)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userStat))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
if (size > sizeof(compat_stat))
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
struct compat_stat compat_stat;
|
|
||||||
compat_stat.st_dev = stat.st_dev;
|
|
||||||
compat_stat.st_ino = stat.st_ino;
|
|
||||||
compat_stat.st_mode = stat.st_mode;
|
|
||||||
compat_stat.st_nlink = stat.st_nlink;
|
|
||||||
compat_stat.st_uid = stat.st_gid;
|
|
||||||
compat_stat.st_size = stat.st_size;
|
|
||||||
compat_stat.st_rdev = stat.st_rdev;
|
|
||||||
compat_stat.st_blksize = stat.st_blksize;
|
|
||||||
compat_stat.st_atim.tv_sec = stat.st_atim.tv_sec;
|
|
||||||
compat_stat.st_atim.tv_nsec = stat.st_atim.tv_nsec;
|
|
||||||
compat_stat.st_mtim.tv_sec = stat.st_mtim.tv_sec;
|
|
||||||
compat_stat.st_mtim.tv_nsec = stat.st_mtim.tv_nsec;
|
|
||||||
compat_stat.st_ctim.tv_sec = stat.st_ctim.tv_sec;
|
|
||||||
compat_stat.st_ctim.tv_nsec = stat.st_ctim.tv_nsec;
|
|
||||||
compat_stat.st_crtim.tv_sec = stat.st_crtim.tv_sec;
|
|
||||||
compat_stat.st_crtim.tv_nsec = stat.st_crtim.tv_nsec;
|
|
||||||
compat_stat.st_type = stat.st_type;
|
|
||||||
compat_stat.st_blocks = stat.st_blocks;
|
|
||||||
if (user_memcpy(userStat, &compat_stat, size) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
} else {
|
|
||||||
if (size > sizeof(struct stat))
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
|
|
||||||
if (user_memcpy(userStat, &stat, size) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(struct stat &stat, struct stat* userStat)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userStat))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
struct compat_stat compat_stat;
|
|
||||||
compat_stat.st_dev = stat.st_dev;
|
|
||||||
compat_stat.st_ino = stat.st_ino;
|
|
||||||
compat_stat.st_mode = stat.st_mode;
|
|
||||||
compat_stat.st_nlink = stat.st_nlink;
|
|
||||||
compat_stat.st_uid = stat.st_gid;
|
|
||||||
compat_stat.st_size = stat.st_size;
|
|
||||||
compat_stat.st_rdev = stat.st_rdev;
|
|
||||||
compat_stat.st_blksize = stat.st_blksize;
|
|
||||||
compat_stat.st_atim.tv_sec = stat.st_atim.tv_sec;
|
|
||||||
compat_stat.st_atim.tv_nsec = stat.st_atim.tv_nsec;
|
|
||||||
compat_stat.st_mtim.tv_sec = stat.st_mtim.tv_sec;
|
|
||||||
compat_stat.st_mtim.tv_nsec = stat.st_mtim.tv_nsec;
|
|
||||||
compat_stat.st_ctim.tv_sec = stat.st_ctim.tv_sec;
|
|
||||||
compat_stat.st_ctim.tv_nsec = stat.st_ctim.tv_nsec;
|
|
||||||
compat_stat.st_crtim.tv_sec = stat.st_crtim.tv_sec;
|
|
||||||
compat_stat.st_crtim.tv_nsec = stat.st_crtim.tv_nsec;
|
|
||||||
compat_stat.st_type = stat.st_type;
|
|
||||||
compat_stat.st_blocks = stat.st_blocks;
|
|
||||||
if (user_memcpy(userStat, &compat_stat, sizeof(compat_stat)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
} else {
|
|
||||||
if (user_memcpy(userStat, &stat, sizeof(stat)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _KERNEL_COMPAT_STAT_H
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef _KERNEL_COMPAT_TIME_H
|
|
||||||
#define _KERNEL_COMPAT_TIME_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
|
|
||||||
struct compat_timespec {
|
|
||||||
uint32 tv_sec; /* seconds */
|
|
||||||
uint32 tv_nsec; /* and nanoseconds */
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _KERNEL_COMPAT_TIME_H
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018, Haiku Inc. All rights reserved.
|
|
||||||
*
|
|
||||||
* Distributed under the terms of the MIT License.
|
|
||||||
*/
|
|
||||||
#ifndef _KERNEL_COMPAT_VFS_DEFS_H
|
|
||||||
#define _KERNEL_COMPAT_VFS_DEFS_H
|
|
||||||
|
|
||||||
|
|
||||||
#include <vfs_defs.h>
|
|
||||||
|
|
||||||
|
|
||||||
struct compat_fd_info {
|
|
||||||
int number;
|
|
||||||
int32 open_mode;
|
|
||||||
dev_t device;
|
|
||||||
ino_t node;
|
|
||||||
} _PACKED;
|
|
||||||
|
|
||||||
|
|
||||||
static_assert(sizeof(compat_fd_info) == 20,
|
|
||||||
"size of compat_fd_info mismatch");
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_to_user(attr_info &info, attr_info* userInfo, size_t size)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userInfo))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
if (size != sizeof(compat_fd_info))
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
compat_fd_info compat_info;
|
|
||||||
compat_info.number = info.number;
|
|
||||||
compat_info.open_mode = info.open_mode;
|
|
||||||
compat_info.device = info.device;
|
|
||||||
compat_info.node = info.node;
|
|
||||||
if (user_memcpy(userInfo, &compat_info, size) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
} else {
|
|
||||||
if (size != sizeof(fd_info))
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
if (user_memcpy(userInfo, &info, size) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
|
||||||
copy_ref_var_from_user(fd_info* userInfo, fd_info &info, size_t size)
|
|
||||||
{
|
|
||||||
if (!IS_USER_ADDRESS(userInfo))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
bool compatMode = (thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0;
|
|
||||||
if (compatMode) {
|
|
||||||
if (size != sizeof(compat_fd_info))
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
compat_fd_info compat_info;
|
|
||||||
if (user_memcpy(&compat_info, userInfo, size) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
info.number = compat_info.number;
|
|
||||||
info.open_mode = compat_info.open_mode;
|
|
||||||
info.device = compat_info.device;
|
|
||||||
info.node = compat_info.node;
|
|
||||||
} else {
|
|
||||||
if (size != sizeof(fd_info))
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
if (user_memcpy(&info, userInfo, size) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _KERNEL_COMPAT_VFS_DEFS_H
|
|
||||||
@@ -23,18 +23,6 @@ copy_ref_var_from_user(T *user, T &kernel)
|
|||||||
return user_memcpy(&kernel, user, sizeof(T));
|
return user_memcpy(&kernel, user, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline
|
|
||||||
status_t
|
|
||||||
copy_ref_var_from_user(T *user, T &kernel, size_t size)
|
|
||||||
{
|
|
||||||
if (size != sizeof(T))
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
return copy_ref_var_from_user(user, kernel);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// copy_ref_var_to_user
|
// copy_ref_var_to_user
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline
|
inline
|
||||||
@@ -47,17 +35,4 @@ copy_ref_var_to_user(T &kernel, T *user)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
inline
|
|
||||||
status_t
|
|
||||||
copy_ref_var_to_user(T &kernel, T *user, size_t size)
|
|
||||||
{
|
|
||||||
if (size > sizeof(T))
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
if (!IS_USER_ADDRESS(user))
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
return user_memcpy(user, &kernel, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _SYSCALL_ARGS_H
|
#endif // _SYSCALL_ARGS_H
|
||||||
|
|||||||
@@ -18,9 +18,6 @@
|
|||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
#include <kernel.h>
|
#include <kernel.h>
|
||||||
#include <ksignal.h>
|
#include <ksignal.h>
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
# include <compat/ksignal_compat.h>
|
|
||||||
#endif
|
|
||||||
#include <int.h>
|
#include <int.h>
|
||||||
#include <team.h>
|
#include <team.h>
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
@@ -91,33 +88,11 @@ x86_restart_syscall(iframe* frame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
set_fs_register(uint32 segment)
|
|
||||||
{
|
|
||||||
asm("movl %0,%%fs" :: "r" (segment));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _COMPAT_MODE
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
x86_set_tls_context(Thread* thread)
|
x86_set_tls_context(Thread* thread)
|
||||||
{
|
{
|
||||||
#ifdef _COMPAT_MODE
|
// Set FS segment base address to the TLS segment.
|
||||||
if ((thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0) {
|
x86_write_msr(IA32_MSR_FS_BASE, thread->user_local_storage);
|
||||||
unsigned index = x86_64_set_user_tls_segment_base(
|
|
||||||
smp_get_current_cpu(), thread->user_local_storage);
|
|
||||||
set_fs_register((index << 3) | DPL_USER);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
// Set FS segment base address to the TLS segment.
|
|
||||||
x86_write_msr(IA32_MSR_FS_BASE, thread->user_local_storage);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -134,24 +109,6 @@ arch_randomize_stack_pointer(addr_t value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
|
|
||||||
|
|
||||||
static addr_t
|
|
||||||
arch_compat_randomize_stack_pointer(addr_t value)
|
|
||||||
{
|
|
||||||
STATIC_ASSERT(MAX_RANDOM_VALUE >= B_PAGE_SIZE - 1);
|
|
||||||
value -= random_value() & (B_PAGE_SIZE - 1);
|
|
||||||
return (value & ~addr_t(0xf)) - 4;
|
|
||||||
// This means, result % 16 == 12, which is what esp should adhere to
|
|
||||||
// when a function is entered for the stack to be considered aligned to
|
|
||||||
// 16 byte.
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif // _COMPAT_MODE
|
|
||||||
|
|
||||||
|
|
||||||
static uint8*
|
static uint8*
|
||||||
get_signal_stack(Thread* thread, iframe* frame, struct sigaction* action,
|
get_signal_stack(Thread* thread, iframe* frame, struct sigaction* action,
|
||||||
size_t spaceNeeded)
|
size_t spaceNeeded)
|
||||||
@@ -261,55 +218,27 @@ arch_thread_enter_userspace(Thread* thread, addr_t entry, void* args1,
|
|||||||
TRACE("arch_thread_enter_userspace: entry %#lx, args %p %p, "
|
TRACE("arch_thread_enter_userspace: entry %#lx, args %p %p, "
|
||||||
"stackTop %#lx\n", entry, args1, args2, stackTop);
|
"stackTop %#lx\n", entry, args1, args2, stackTop);
|
||||||
|
|
||||||
|
stackTop = arch_randomize_stack_pointer(stackTop - sizeof(codeAddr));
|
||||||
|
|
||||||
// Copy the address of the stub that calls exit_thread() when the thread
|
// Copy the address of the stub that calls exit_thread() when the thread
|
||||||
// entry function returns to the top of the stack to act as the return
|
// entry function returns to the top of the stack to act as the return
|
||||||
// address. The stub is inside commpage.
|
// address. The stub is inside commpage.
|
||||||
addr_t commPageAddress = (addr_t)thread->team->commpage_address;
|
addr_t commPageAddress = (addr_t)thread->team->commpage_address;
|
||||||
|
set_ac();
|
||||||
#ifdef _COMPAT_MODE
|
codeAddr = ((addr_t*)commPageAddress)[COMMPAGE_ENTRY_X86_THREAD_EXIT]
|
||||||
if ((thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0) {
|
+ commPageAddress;
|
||||||
uint32 args[3];
|
clear_ac();
|
||||||
stackTop = arch_compat_randomize_stack_pointer(stackTop - sizeof(args));
|
if (user_memcpy((void*)stackTop, (const void*)&codeAddr, sizeof(codeAddr))
|
||||||
|
|
||||||
set_ac();
|
|
||||||
args[0] = ((addr_t*)commPageAddress)[COMMPAGE_ENTRY_X86_THREAD_EXIT]
|
|
||||||
+ commPageAddress;
|
|
||||||
clear_ac();
|
|
||||||
args[1] = (uint32)(addr_t)args1;
|
|
||||||
args[2] = (uint32)(addr_t)args2;
|
|
||||||
if (user_memcpy((void *)stackTop, args, sizeof(args)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
stackTop = arch_randomize_stack_pointer(stackTop - sizeof(codeAddr));
|
|
||||||
|
|
||||||
set_ac();
|
|
||||||
codeAddr = ((addr_t*)commPageAddress)[COMMPAGE_ENTRY_X86_THREAD_EXIT]
|
|
||||||
+ commPageAddress;
|
|
||||||
clear_ac();
|
|
||||||
if (user_memcpy((void*)stackTop, (const void*)&codeAddr, sizeof(codeAddr))
|
|
||||||
!= B_OK)
|
!= B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
}
|
|
||||||
|
|
||||||
// Prepare the user iframe.
|
// Prepare the user iframe.
|
||||||
iframe frame = {};
|
iframe frame = {};
|
||||||
frame.type = IFRAME_TYPE_SYSCALL;
|
frame.type = IFRAME_TYPE_SYSCALL;
|
||||||
|
frame.si = (uint64)args2;
|
||||||
|
frame.di = (uint64)args1;
|
||||||
frame.ip = entry;
|
frame.ip = entry;
|
||||||
#ifdef _COMPAT_MODE
|
frame.cs = USER_CODE_SELECTOR;
|
||||||
if ((thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0) {
|
|
||||||
frame.cs = USER32_CODE_SELECTOR;
|
|
||||||
arch_thread_set_ds(USER_DATA_SELECTOR);
|
|
||||||
arch_thread_set_es(USER_DATA_SELECTOR);
|
|
||||||
} else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
frame.si = (uint64)args2;
|
|
||||||
frame.di = (uint64)args1;
|
|
||||||
frame.cs = USER_CODE_SELECTOR;
|
|
||||||
}
|
|
||||||
frame.flags = X86_EFLAGS_RESERVED1 | X86_EFLAGS_INTERRUPT
|
frame.flags = X86_EFLAGS_RESERVED1 | X86_EFLAGS_INTERRUPT
|
||||||
| (3 << X86_EFLAGS_IO_PRIVILEG_LEVEL_SHIFT);
|
| (3 << X86_EFLAGS_IO_PRIVILEG_LEVEL_SHIFT);
|
||||||
frame.sp = stackTop;
|
frame.sp = stackTop;
|
||||||
@@ -465,120 +394,3 @@ arch_restore_signal_frame(struct signal_frame_data* signalFrameData)
|
|||||||
// restored.
|
// restored.
|
||||||
return frame->ax;
|
return frame->ax;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
|
|
||||||
status_t
|
|
||||||
arch_setup_compat_signal_frame(Thread* thread, struct sigaction* action,
|
|
||||||
struct compat_signal_frame_data* signalFrameData)
|
|
||||||
{
|
|
||||||
iframe* frame = x86_get_current_iframe();
|
|
||||||
if (!IFRAME_IS_USER(frame)) {
|
|
||||||
panic("arch_setup_compat_signal_frame(): No user iframe!");
|
|
||||||
return B_BAD_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the register state.
|
|
||||||
signalFrameData->context.uc_mcontext.eax = frame->ax;
|
|
||||||
signalFrameData->context.uc_mcontext.ebx = frame->bx;
|
|
||||||
signalFrameData->context.uc_mcontext.ecx = frame->cx;
|
|
||||||
signalFrameData->context.uc_mcontext.edx = frame->dx;
|
|
||||||
signalFrameData->context.uc_mcontext.edi = frame->di;
|
|
||||||
signalFrameData->context.uc_mcontext.esi = frame->si;
|
|
||||||
signalFrameData->context.uc_mcontext.ebp = frame->bp;
|
|
||||||
signalFrameData->context.uc_mcontext.esp = frame->user_sp;
|
|
||||||
signalFrameData->context.uc_mcontext.eip = frame->ip;
|
|
||||||
signalFrameData->context.uc_mcontext.eflags = frame->flags;
|
|
||||||
x86_fnsave((void *)(&signalFrameData->context.uc_mcontext.xregs));
|
|
||||||
|
|
||||||
// Fill in signalFrameData->context.uc_stack.
|
|
||||||
stack_t stack;
|
|
||||||
signal_get_user_stack(frame->user_sp, &stack);
|
|
||||||
signalFrameData->context.uc_stack.ss_sp = (addr_t)stack.ss_sp;
|
|
||||||
signalFrameData->context.uc_stack.ss_size = stack.ss_size;
|
|
||||||
signalFrameData->context.uc_stack.ss_flags = stack.ss_flags;
|
|
||||||
|
|
||||||
// Store syscall_restart_return_value.
|
|
||||||
signalFrameData->syscall_restart_return_value = frame->orig_rax;
|
|
||||||
|
|
||||||
// Get the stack to use and copy the frame data to it.
|
|
||||||
uint32 stackFrame[2];
|
|
||||||
uint8* userStack = get_signal_stack(thread, frame, action,
|
|
||||||
sizeof(*signalFrameData) + sizeof(stackFrame));
|
|
||||||
|
|
||||||
compat_signal_frame_data* userSignalFrameData
|
|
||||||
= (compat_signal_frame_data*)(userStack + sizeof(stackFrame));
|
|
||||||
|
|
||||||
if (user_memcpy(userSignalFrameData, signalFrameData,
|
|
||||||
sizeof(*signalFrameData)) != B_OK) {
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// prepare the user stack frame for a function call to the signal handler
|
|
||||||
// wrapper function
|
|
||||||
stackFrame[0] = frame->ip;
|
|
||||||
stackFrame[1] = (addr_t)userSignalFrameData;
|
|
||||||
// parameter: pointer to signal frame data
|
|
||||||
|
|
||||||
if (user_memcpy(userStack, stackFrame, sizeof(stackFrame)) != B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
|
|
||||||
// Update Thread::user_signal_context, now that everything seems to have
|
|
||||||
// gone fine.
|
|
||||||
thread->user_signal_context = (ucontext_t*)&userSignalFrameData->context;
|
|
||||||
|
|
||||||
// Set up the iframe to execute the signal handler wrapper on our prepared
|
|
||||||
// stack. First argument points to the frame data.
|
|
||||||
addr_t* commPageAddress = (addr_t*)thread->team->commpage_address;
|
|
||||||
frame->user_sp = (addr_t)userStack;
|
|
||||||
set_ac();
|
|
||||||
|
|
||||||
// from x86/arch_commpage_defs.h
|
|
||||||
#define COMPAT_COMMPAGE_ENTRY_X86_SIGNAL_HANDLER \
|
|
||||||
(COMMPAGE_ENTRY_FIRST_ARCH_SPECIFIC + 3)
|
|
||||||
frame->ip = commPageAddress[COMPAT_COMMPAGE_ENTRY_X86_SIGNAL_HANDLER]
|
|
||||||
+ (addr_t)commPageAddress;
|
|
||||||
clear_ac();
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int64
|
|
||||||
arch_restore_compat_signal_frame(struct compat_signal_frame_data* signalFrameData)
|
|
||||||
{
|
|
||||||
iframe* frame = x86_get_current_iframe();
|
|
||||||
|
|
||||||
frame->orig_rax = signalFrameData->syscall_restart_return_value;
|
|
||||||
frame->ax = signalFrameData->context.uc_mcontext.eax;
|
|
||||||
frame->bx = signalFrameData->context.uc_mcontext.ebx;
|
|
||||||
frame->cx = signalFrameData->context.uc_mcontext.ecx;
|
|
||||||
frame->dx = signalFrameData->context.uc_mcontext.edx;
|
|
||||||
frame->di = signalFrameData->context.uc_mcontext.edi;
|
|
||||||
frame->si = signalFrameData->context.uc_mcontext.esi;
|
|
||||||
frame->bp = signalFrameData->context.uc_mcontext.ebp;
|
|
||||||
frame->user_sp = signalFrameData->context.uc_mcontext.esp;
|
|
||||||
frame->ip = signalFrameData->context.uc_mcontext.eip;
|
|
||||||
frame->flags = (frame->flags & ~(uint64)X86_EFLAGS_USER_FLAGS)
|
|
||||||
| (signalFrameData->context.uc_mcontext.eflags & X86_EFLAGS_USER_FLAGS);
|
|
||||||
|
|
||||||
x86_frstor((void*)(&signalFrameData->context.uc_mcontext.xregs));
|
|
||||||
|
|
||||||
// The syscall return code overwrites frame->ax with the return value of
|
|
||||||
// the syscall, need to return it here to ensure the correct value is
|
|
||||||
// restored.
|
|
||||||
return frame->ax;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
arch_syscall_64_bit_return_value(void)
|
|
||||||
{
|
|
||||||
Thread* thread = thread_get_current_thread();
|
|
||||||
if ((thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0)
|
|
||||||
atomic_or(&thread->flags, THREAD_FLAGS_64_BIT_SYSCALL_RETURN);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _COMPAT_MODE
|
|
||||||
|
|
||||||
|
|||||||
@@ -49,19 +49,11 @@
|
|||||||
#include <util/atomic.h>
|
#include <util/atomic.h>
|
||||||
#include <util/AutoLock.h>
|
#include <util/AutoLock.h>
|
||||||
#include <util/DoublyLinkedList.h>
|
#include <util/DoublyLinkedList.h>
|
||||||
#include <util/syscall_args.h>
|
|
||||||
#include <vfs.h>
|
#include <vfs.h>
|
||||||
#include <vm/vm.h>
|
#include <vm/vm.h>
|
||||||
#include <vm/VMCache.h>
|
#include <vm/VMCache.h>
|
||||||
#include <wait_for_objects.h>
|
#include <wait_for_objects.h>
|
||||||
|
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
# include <fcntl_compat.h>
|
|
||||||
# include <stat_compat.h>
|
|
||||||
# include <fs_attr_compat.h>
|
|
||||||
# include <fs_info_compat.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "EntryCache.h"
|
#include "EntryCache.h"
|
||||||
#include "fifo.h"
|
#include "fifo.h"
|
||||||
#include "IORequest.h"
|
#include "IORequest.h"
|
||||||
@@ -6124,8 +6116,10 @@ common_fcntl(int fd, int op, size_t argument, bool kernel)
|
|||||||
if (op == F_SETLK || op == F_SETLKW || op == F_GETLK) {
|
if (op == F_SETLK || op == F_SETLKW || op == F_GETLK) {
|
||||||
if (descriptor->type != FDTYPE_FILE)
|
if (descriptor->type != FDTYPE_FILE)
|
||||||
status = B_BAD_VALUE;
|
status = B_BAD_VALUE;
|
||||||
else
|
else if (user_memcpy(&flock, (struct flock*)argument,
|
||||||
status = copy_ref_var_from_user((struct flock*)argument, flock);
|
sizeof(struct flock)) != B_OK)
|
||||||
|
status = B_BAD_ADDRESS;
|
||||||
|
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
put_fd(descriptor);
|
put_fd(descriptor);
|
||||||
return status;
|
return status;
|
||||||
@@ -8804,7 +8798,10 @@ _user_read_fs_info(dev_t device, struct fs_info* userInfo)
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
return copy_ref_var_to_user(info, userInfo);
|
if (user_memcpy(userInfo, &info, sizeof(struct fs_info)) != B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -8816,9 +8813,9 @@ _user_write_fs_info(dev_t device, const struct fs_info* userInfo, int mask)
|
|||||||
if (userInfo == NULL)
|
if (userInfo == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
status_t status = copy_ref_var_from_user((struct fs_info*)userInfo, info);
|
if (!IS_USER_ADDRESS(userInfo)
|
||||||
if (status != B_OK)
|
|| user_memcpy(&info, userInfo, sizeof(struct fs_info)) != B_OK)
|
||||||
return status;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
return fs_write_info(device, &info, mask);
|
return fs_write_info(device, &info, mask);
|
||||||
}
|
}
|
||||||
@@ -8864,6 +8861,9 @@ _user_get_next_fd_info(team_id team, uint32* userCookie, fd_info* userInfo,
|
|||||||
if (geteuid() != 0)
|
if (geteuid() != 0)
|
||||||
return B_NOT_ALLOWED;
|
return B_NOT_ALLOWED;
|
||||||
|
|
||||||
|
if (infoSize != sizeof(fd_info))
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userCookie) || !IS_USER_ADDRESS(userInfo)
|
if (!IS_USER_ADDRESS(userCookie) || !IS_USER_ADDRESS(userInfo)
|
||||||
|| user_memcpy(&cookie, userCookie, sizeof(uint32)) != B_OK)
|
|| user_memcpy(&cookie, userCookie, sizeof(uint32)) != B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
@@ -8872,9 +8872,11 @@ _user_get_next_fd_info(team_id team, uint32* userCookie, fd_info* userInfo,
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
if (user_memcpy(userCookie, &cookie, sizeof(uint32)) != B_OK)
|
if (user_memcpy(userCookie, &cookie, sizeof(uint32)) != B_OK
|
||||||
|
|| user_memcpy(userInfo, &info, infoSize) != B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
return copy_ref_var_to_user(info, userInfo);
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -9525,7 +9527,7 @@ _user_read_stat(int fd, const char* userPath, bool traverseLink,
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
return copy_ref_var_to_user(stat, userStat, statSize);
|
return user_memcpy(userStat, &stat, statSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -9696,7 +9698,8 @@ _user_stat_attr(int fd, const char* userAttribute,
|
|||||||
info.type = stat.st_type;
|
info.type = stat.st_type;
|
||||||
info.size = stat.st_size;
|
info.size = stat.st_size;
|
||||||
|
|
||||||
status = copy_ref_var_to_user(info, userAttrInfo);
|
if (user_memcpy(userAttrInfo, &info, sizeof(struct attr_info)) != B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@@ -9805,8 +9808,10 @@ _user_read_index_stat(dev_t device, const char* userName, struct stat* userStat)
|
|||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status = index_name_read_stat(device, name, &stat, false);
|
status = index_name_read_stat(device, name, &stat, false);
|
||||||
if (status == B_OK)
|
if (status == B_OK) {
|
||||||
status = copy_ref_var_to_user(stat, userStat);
|
if (user_memcpy(userStat, &stat, sizeof(stat)) != B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
+15
-15
@@ -18,11 +18,6 @@
|
|||||||
#include <thread_types.h>
|
#include <thread_types.h>
|
||||||
#include <user_debugger.h>
|
#include <user_debugger.h>
|
||||||
#include <util/AutoLock.h>
|
#include <util/AutoLock.h>
|
||||||
#include <util/syscall_args.h>
|
|
||||||
|
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
# include <image_compat.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@@ -469,9 +464,12 @@ _user_register_image(extended_image_info *userInfo, size_t size)
|
|||||||
{
|
{
|
||||||
extended_image_info info;
|
extended_image_info info;
|
||||||
|
|
||||||
status_t status = copy_ref_var_from_user(userInfo, info, size);
|
if (size != sizeof(info))
|
||||||
if (status != B_OK)
|
return B_BAD_VALUE;
|
||||||
return status;
|
|
||||||
|
if (!IS_USER_ADDRESS(userInfo)
|
||||||
|
|| user_memcpy(&info, userInfo, size) < B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
return register_image(thread_get_current_thread()->team, &info, size);
|
return register_image(thread_get_current_thread()->team, &info, size);
|
||||||
}
|
}
|
||||||
@@ -527,9 +525,9 @@ _user_get_image_info(image_id id, image_info *userInfo, size_t size)
|
|||||||
|
|
||||||
status = _get_image_info(id, &info, sizeof(image_info));
|
status = _get_image_info(id, &info, sizeof(image_info));
|
||||||
|
|
||||||
status_t err = copy_ref_var_to_user(info, userInfo, size);
|
if (user_memcpy(userInfo, &info, size) < B_OK)
|
||||||
if (err != B_OK)
|
return B_BAD_ADDRESS;
|
||||||
return err;
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,6 +540,9 @@ _user_get_next_image_info(team_id team, int32 *_cookie, image_info *userInfo,
|
|||||||
status_t status;
|
status_t status;
|
||||||
int32 cookie;
|
int32 cookie;
|
||||||
|
|
||||||
|
if (size > sizeof(image_info))
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userInfo) || !IS_USER_ADDRESS(_cookie)
|
if (!IS_USER_ADDRESS(userInfo) || !IS_USER_ADDRESS(_cookie)
|
||||||
|| user_memcpy(&cookie, _cookie, sizeof(int32)) < B_OK) {
|
|| user_memcpy(&cookie, _cookie, sizeof(int32)) < B_OK) {
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
@@ -549,11 +550,10 @@ _user_get_next_image_info(team_id team, int32 *_cookie, image_info *userInfo,
|
|||||||
|
|
||||||
status = _get_next_image_info(team, &cookie, &info, sizeof(image_info));
|
status = _get_next_image_info(team, &cookie, &info, sizeof(image_info));
|
||||||
|
|
||||||
status_t err = copy_ref_var_to_user(info, userInfo, size);
|
if (user_memcpy(userInfo, &info, size) < B_OK
|
||||||
if (err != B_OK)
|
|| user_memcpy(_cookie, &cookie, sizeof(int32)) < B_OK) {
|
||||||
return err;
|
|
||||||
if (user_memcpy(_cookie, &cookie, sizeof(int32)) < B_OK)
|
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-143
@@ -35,11 +35,6 @@
|
|||||||
#include <user_debugger.h>
|
#include <user_debugger.h>
|
||||||
#include <user_thread.h>
|
#include <user_thread.h>
|
||||||
#include <util/AutoLock.h>
|
#include <util/AutoLock.h>
|
||||||
#include <util/syscall_args.h>
|
|
||||||
|
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
# include <compat/ksignal_compat.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
//#define TRACE_SIGNAL
|
//#define TRACE_SIGNAL
|
||||||
@@ -913,61 +908,6 @@ setup_signal_frame(Thread* thread, struct sigaction* action, Signal* signal,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
|
|
||||||
static status_t
|
|
||||||
setup_compat_signal_frame(Thread* thread, struct sigaction* action, Signal* signal,
|
|
||||||
sigset_t signalMask)
|
|
||||||
{
|
|
||||||
// prepare the data, we need to copy onto the user stack
|
|
||||||
struct compat_signal_frame_data frameData;
|
|
||||||
|
|
||||||
// signal info
|
|
||||||
frameData.info.si_signo = signal->Number();
|
|
||||||
frameData.info.si_code = signal->SignalCode();
|
|
||||||
frameData.info.si_errno = signal->ErrorCode();
|
|
||||||
frameData.info.si_pid = signal->SendingProcess();
|
|
||||||
frameData.info.si_uid = signal->SendingUser();
|
|
||||||
frameData.info.si_addr = (addr_t)signal->Address();
|
|
||||||
frameData.info.si_status = signal->Status();
|
|
||||||
frameData.info.si_band = signal->PollBand();
|
|
||||||
frameData.info.si_value.sival_ptr = (addr_t)signal->UserValue().sival_ptr;
|
|
||||||
|
|
||||||
// context
|
|
||||||
frameData.context.uc_link = (addr_t)thread->user_signal_context;
|
|
||||||
frameData.context.uc_sigmask = signalMask;
|
|
||||||
// uc_stack and uc_mcontext are filled in by the architecture specific code.
|
|
||||||
|
|
||||||
// user data
|
|
||||||
frameData.user_data = (addr_t)action->sa_userdata;
|
|
||||||
|
|
||||||
// handler function
|
|
||||||
frameData.siginfo_handler = (action->sa_flags & SA_SIGINFO) != 0;
|
|
||||||
frameData.handler = frameData.siginfo_handler
|
|
||||||
? (addr_t)action->sa_sigaction : (addr_t)action->sa_handler;
|
|
||||||
|
|
||||||
// thread flags -- save the and clear the thread's syscall restart related
|
|
||||||
// flags
|
|
||||||
frameData.thread_flags = atomic_and(&thread->flags,
|
|
||||||
~(THREAD_FLAGS_RESTART_SYSCALL | THREAD_FLAGS_64_BIT_SYSCALL_RETURN));
|
|
||||||
|
|
||||||
// syscall restart related fields
|
|
||||||
memcpy(frameData.syscall_restart_parameters,
|
|
||||||
thread->syscall_restart.parameters,
|
|
||||||
sizeof(frameData.syscall_restart_parameters));
|
|
||||||
|
|
||||||
// commpage address
|
|
||||||
frameData.commpage_address = (addr_t)thread->team->commpage_address;
|
|
||||||
|
|
||||||
// syscall_restart_return_value is filled in by the architecture specific
|
|
||||||
// code.
|
|
||||||
|
|
||||||
return arch_setup_compat_signal_frame(thread, action, &frameData);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // _COMPAT_MODE
|
|
||||||
|
|
||||||
|
|
||||||
/*! Actually handles pending signals -- i.e. the thread will exit, a custom
|
/*! Actually handles pending signals -- i.e. the thread will exit, a custom
|
||||||
signal handler is prepared, or whatever the signal demands.
|
signal handler is prepared, or whatever the signal demands.
|
||||||
The function will not return, when a deadly signal is encountered. The
|
The function will not return, when a deadly signal is encountered. The
|
||||||
@@ -1318,11 +1258,6 @@ handle_signals(Thread* thread)
|
|||||||
|
|
||||||
locker.Unlock();
|
locker.Unlock();
|
||||||
|
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
if ((thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0)
|
|
||||||
setup_compat_signal_frame(thread, &handler, signal, oldBlockMask);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
setup_signal_frame(thread, &handler, signal, oldBlockMask);
|
setup_signal_frame(thread, &handler, signal, oldBlockMask);
|
||||||
|
|
||||||
// Reset sigsuspend_original_unblocked_mask. It would have been set by
|
// Reset sigsuspend_original_unblocked_mask. It would have been set by
|
||||||
@@ -2300,10 +2235,11 @@ _user_send_signal(int32 id, uint32 signalNumber,
|
|||||||
// Copy the user value from userland. If not given, use a dummy value.
|
// Copy the user value from userland. If not given, use a dummy value.
|
||||||
union sigval userValue;
|
union sigval userValue;
|
||||||
if (userUserValue != NULL) {
|
if (userUserValue != NULL) {
|
||||||
status_t status = copy_ref_var_from_user((union sigval*)userUserValue,
|
if (!IS_USER_ADDRESS(userUserValue)
|
||||||
userValue);
|
|| user_memcpy(&userValue, userUserValue, sizeof(userValue))
|
||||||
if (status != B_OK)
|
!= B_OK) {
|
||||||
return status;
|
return B_BAD_ADDRESS;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
userValue.sival_ptr = NULL;
|
userValue.sival_ptr = NULL;
|
||||||
|
|
||||||
@@ -2360,23 +2296,20 @@ _user_sigaction(int signal, const struct sigaction *userAction,
|
|||||||
struct sigaction act, oact;
|
struct sigaction act, oact;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
if (userAction != NULL) {
|
if ((userAction != NULL && (!IS_USER_ADDRESS(userAction)
|
||||||
status = copy_ref_var_from_user((struct sigaction*)userAction, act);
|
|| user_memcpy(&act, userAction, sizeof(struct sigaction)) < B_OK))
|
||||||
if (status < B_OK)
|
|| (userOldAction != NULL && (!IS_USER_ADDRESS(userOldAction)
|
||||||
return status;
|
|| user_memcpy(&oact, userOldAction, sizeof(struct sigaction))
|
||||||
}
|
< B_OK)))
|
||||||
if (userOldAction != NULL) {
|
return B_BAD_ADDRESS;
|
||||||
status = copy_ref_var_from_user(userOldAction, oact);
|
|
||||||
if (status < B_OK)
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
status = sigaction_internal(signal, userAction ? &act : NULL,
|
status = sigaction_internal(signal, userAction ? &act : NULL,
|
||||||
userOldAction ? &oact : NULL);
|
userOldAction ? &oact : NULL);
|
||||||
|
|
||||||
// only copy the old action if a pointer has been given
|
// only copy the old action if a pointer has been given
|
||||||
if (status >= B_OK && userOldAction != NULL)
|
if (status >= B_OK && userOldAction != NULL
|
||||||
status = copy_ref_var_to_user(oact, userOldAction);
|
&& user_memcpy(userOldAction, &oact, sizeof(struct sigaction)) < B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -2406,7 +2339,7 @@ _user_sigwait(const sigset_t *userSet, siginfo_t *userInfo, uint32 flags,
|
|||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
// copy the info back to userland, if userSet is non-NULL
|
// copy the info back to userland, if userSet is non-NULL
|
||||||
if (userInfo != NULL)
|
if (userInfo != NULL)
|
||||||
status = copy_ref_var_to_user(info, userInfo);
|
status = user_memcpy(userInfo, &info, sizeof(info));
|
||||||
} else if (status == B_INTERRUPTED) {
|
} else if (status == B_INTERRUPTED) {
|
||||||
// make sure we'll be restarted
|
// make sure we'll be restarted
|
||||||
Thread* thread = thread_get_current_thread();
|
Thread* thread = thread_get_current_thread();
|
||||||
@@ -2460,17 +2393,11 @@ _user_set_signal_stack(const stack_t* newUserStack, stack_t* oldUserStack)
|
|||||||
struct stack_t newStack, oldStack;
|
struct stack_t newStack, oldStack;
|
||||||
bool onStack = false;
|
bool onStack = false;
|
||||||
|
|
||||||
if (newUserStack != NULL) {
|
if ((newUserStack != NULL && (!IS_USER_ADDRESS(newUserStack)
|
||||||
status_t status = copy_ref_var_from_user((stack_t*)newUserStack,
|
|| user_memcpy(&newStack, newUserStack, sizeof(stack_t)) < B_OK))
|
||||||
newStack);
|
|| (oldUserStack != NULL && (!IS_USER_ADDRESS(oldUserStack)
|
||||||
if (status < B_OK)
|
|| user_memcpy(&oldStack, oldUserStack, sizeof(stack_t)) < B_OK)))
|
||||||
return status;
|
return B_BAD_ADDRESS;
|
||||||
}
|
|
||||||
if (oldUserStack != NULL) {
|
|
||||||
status_t status = copy_ref_var_from_user(oldUserStack, oldStack);
|
|
||||||
if (status < B_OK)
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thread->signal_stack_enabled) {
|
if (thread->signal_stack_enabled) {
|
||||||
// determine whether or not the user thread is currently
|
// determine whether or not the user thread is currently
|
||||||
@@ -2507,8 +2434,9 @@ _user_set_signal_stack(const stack_t* newUserStack, stack_t* oldUserStack)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// only copy the old stack info if a pointer has been given
|
// only copy the old stack info if a pointer has been given
|
||||||
if (oldUserStack != NULL)
|
if (oldUserStack != NULL
|
||||||
return copy_ref_var_to_user(oldStack, oldUserStack);
|
&& user_memcpy(oldUserStack, &oldStack, sizeof(stack_t)) < B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -2542,54 +2470,6 @@ _user_restore_signal_frame(struct signal_frame_data* userSignalFrameData)
|
|||||||
|
|
||||||
Thread *thread = thread_get_current_thread();
|
Thread *thread = thread_get_current_thread();
|
||||||
|
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
if ((thread->flags & THREAD_FLAGS_COMPAT_MODE) != 0) {
|
|
||||||
// copy the signal frame data from userland
|
|
||||||
compat_signal_frame_data signalFrameData;
|
|
||||||
if (userSignalFrameData == NULL || !IS_USER_ADDRESS(userSignalFrameData)
|
|
||||||
|| user_memcpy(&signalFrameData, userSignalFrameData,
|
|
||||||
sizeof(signalFrameData)) != B_OK) {
|
|
||||||
// We failed to copy the signal frame data from userland. This is a
|
|
||||||
// serious problem. Kill the thread.
|
|
||||||
dprintf("_user_restore_signal_frame(): thread %" B_PRId32 ": Failed to "
|
|
||||||
"copy signal frame data (%p) from userland. Killing thread...\n",
|
|
||||||
thread->id, userSignalFrameData);
|
|
||||||
kill_thread(thread->id);
|
|
||||||
return B_BAD_ADDRESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// restore the signal block mask
|
|
||||||
InterruptsSpinLocker locker(thread->team->signal_lock);
|
|
||||||
|
|
||||||
thread->sig_block_mask
|
|
||||||
= signalFrameData.context.uc_sigmask & BLOCKABLE_SIGNALS;
|
|
||||||
update_current_thread_signals_flag();
|
|
||||||
|
|
||||||
locker.Unlock();
|
|
||||||
|
|
||||||
// restore the syscall restart related thread flags and the syscall restart
|
|
||||||
// parameters
|
|
||||||
atomic_and(&thread->flags,
|
|
||||||
~(THREAD_FLAGS_RESTART_SYSCALL | THREAD_FLAGS_64_BIT_SYSCALL_RETURN));
|
|
||||||
atomic_or(&thread->flags, signalFrameData.thread_flags
|
|
||||||
& (THREAD_FLAGS_RESTART_SYSCALL | THREAD_FLAGS_64_BIT_SYSCALL_RETURN));
|
|
||||||
|
|
||||||
memcpy(thread->syscall_restart.parameters,
|
|
||||||
signalFrameData.syscall_restart_parameters,
|
|
||||||
sizeof(thread->syscall_restart.parameters));
|
|
||||||
|
|
||||||
// restore the previously stored Thread::user_signal_context
|
|
||||||
thread->user_signal_context = (ucontext_t*)(addr_t)signalFrameData.context.uc_link;
|
|
||||||
if (thread->user_signal_context != NULL
|
|
||||||
&& !IS_USER_ADDRESS(thread->user_signal_context)) {
|
|
||||||
thread->user_signal_context = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// let the architecture specific code restore the registers
|
|
||||||
return arch_restore_compat_signal_frame(&signalFrameData);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// copy the signal frame data from userland
|
// copy the signal frame data from userland
|
||||||
signal_frame_data signalFrameData;
|
signal_frame_data signalFrameData;
|
||||||
if (userSignalFrameData == NULL || !IS_USER_ADDRESS(userSignalFrameData)
|
if (userSignalFrameData == NULL || !IS_USER_ADDRESS(userSignalFrameData)
|
||||||
|
|||||||
@@ -31,9 +31,6 @@
|
|||||||
#include <lock.h>
|
#include <lock.h>
|
||||||
#include <Notifications.h>
|
#include <Notifications.h>
|
||||||
#include <messaging.h>
|
#include <messaging.h>
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
# include <OS_compat.h>
|
|
||||||
#endif
|
|
||||||
#include <port.h>
|
#include <port.h>
|
||||||
#include <real_time_clock.h>
|
#include <real_time_clock.h>
|
||||||
#include <sem.h>
|
#include <sem.h>
|
||||||
@@ -41,7 +38,6 @@
|
|||||||
#include <team.h>
|
#include <team.h>
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
#include <util/AutoLock.h>
|
#include <util/AutoLock.h>
|
||||||
#include <util/syscall_args.h>
|
|
||||||
#include <vm/vm.h>
|
#include <vm/vm.h>
|
||||||
#include <vm/vm_page.h>
|
#include <vm/vm_page.h>
|
||||||
|
|
||||||
@@ -549,8 +545,13 @@ _user_get_system_info(system_info* userInfo)
|
|||||||
|
|
||||||
system_info info;
|
system_info info;
|
||||||
status_t status = get_system_info(&info);
|
status_t status = get_system_info(&info);
|
||||||
if (status == B_OK)
|
if (status == B_OK) {
|
||||||
return copy_ref_var_to_user(info, userInfo);
|
if (user_memcpy(userInfo, &info, sizeof(system_info)) < B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+39
-100
@@ -47,17 +47,12 @@
|
|||||||
#include <team.h>
|
#include <team.h>
|
||||||
#include <tracing.h>
|
#include <tracing.h>
|
||||||
#include <util/AutoLock.h>
|
#include <util/AutoLock.h>
|
||||||
#include <util/syscall_args.h>
|
|
||||||
#include <vm/vm_page.h>
|
#include <vm/vm_page.h>
|
||||||
#include <vm/vm_priv.h>
|
#include <vm/vm_priv.h>
|
||||||
#include <vm/VMAddressSpace.h>
|
#include <vm/VMAddressSpace.h>
|
||||||
#include <vm/VMArea.h>
|
#include <vm/VMArea.h>
|
||||||
#include <vm/VMCache.h>
|
#include <vm/VMCache.h>
|
||||||
|
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
# include <OS_compat.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "VMAddressSpaceLocking.h"
|
#include "VMAddressSpaceLocking.h"
|
||||||
#include "VMAnonymousCache.h"
|
#include "VMAnonymousCache.h"
|
||||||
#include "VMAnonymousNoSwapCache.h"
|
#include "VMAnonymousNoSwapCache.h"
|
||||||
@@ -6008,44 +6003,6 @@ _get_next_area_info(team_id team, ssize_t* cookie, area_info* info, size_t size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef _COMPAT_MODE
|
|
||||||
status_t
|
|
||||||
_compat_get_next_area_info(team_id team, ssize_t* cookie, area_info* info, size_t size)
|
|
||||||
{
|
|
||||||
area_id nextID = *(area_id*)cookie;
|
|
||||||
|
|
||||||
// we're already through the list
|
|
||||||
if (nextID == (area_id)-1)
|
|
||||||
return B_ENTRY_NOT_FOUND;
|
|
||||||
|
|
||||||
if (team == B_CURRENT_TEAM)
|
|
||||||
team = team_get_current_team_id();
|
|
||||||
|
|
||||||
AddressSpaceReadLocker locker(team);
|
|
||||||
if (!locker.IsLocked())
|
|
||||||
return B_BAD_TEAM_ID;
|
|
||||||
|
|
||||||
VMArea* area;
|
|
||||||
for (VMAddressSpace::AreaIterator it
|
|
||||||
= locker.AddressSpace()->GetAreaIterator();
|
|
||||||
(area = it.Next()) != NULL;) {
|
|
||||||
if (area->id > nextID)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (area == NULL) {
|
|
||||||
nextID = (area_id)-1;
|
|
||||||
return B_ENTRY_NOT_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
fill_area_info(area, info, size);
|
|
||||||
*cookie = (ssize_t)(area->id);
|
|
||||||
|
|
||||||
return B_OK;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
set_area_protection(area_id area, uint32 newProtection)
|
set_area_protection(area_id area, uint32 newProtection)
|
||||||
{
|
{
|
||||||
@@ -6175,22 +6132,23 @@ _user_reserve_address_range(addr_t* userAddress, uint32 addressSpec,
|
|||||||
|
|
||||||
addr_t address;
|
addr_t address;
|
||||||
|
|
||||||
status_t status = copy_ref_var_from_user(userAddress, address);
|
if (!IS_USER_ADDRESS(userAddress)
|
||||||
if (status != B_OK)
|
|| user_memcpy(&address, userAddress, sizeof(address)) != B_OK)
|
||||||
return status;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status = vm_reserve_address_range(
|
status_t status = vm_reserve_address_range(
|
||||||
VMAddressSpace::CurrentID(), (void**)&address, addressSpec, size,
|
VMAddressSpace::CurrentID(), (void**)&address, addressSpec, size,
|
||||||
RESERVED_AVOID_BASE);
|
RESERVED_AVOID_BASE);
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
status = copy_ref_var_to_user(address, userAddress);
|
if (user_memcpy(userAddress, &address, sizeof(address)) != B_OK) {
|
||||||
if (status != B_OK) {
|
|
||||||
vm_unreserve_address_range(VMAddressSpace::CurrentID(),
|
vm_unreserve_address_range(VMAddressSpace::CurrentID(),
|
||||||
(void*)address, size);
|
(void*)address, size);
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
}
|
}
|
||||||
return status;
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6236,8 +6194,10 @@ _user_get_area_info(area_id area, area_info* userInfo)
|
|||||||
// TODO: do we want to prevent userland from seeing kernel protections?
|
// TODO: do we want to prevent userland from seeing kernel protections?
|
||||||
//info.protection &= B_USER_PROTECTION;
|
//info.protection &= B_USER_PROTECTION;
|
||||||
|
|
||||||
return copy_ref_var_to_user(info, userInfo);
|
if (user_memcpy(userInfo, &info, sizeof(area_info)) < B_OK)
|
||||||
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -6247,28 +6207,21 @@ _user_get_next_area_info(team_id team, ssize_t* userCookie, area_info* userInfo)
|
|||||||
ssize_t cookie;
|
ssize_t cookie;
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userCookie)
|
if (!IS_USER_ADDRESS(userCookie)
|
||||||
|| !IS_USER_ADDRESS(userInfo))
|
|| !IS_USER_ADDRESS(userInfo)
|
||||||
|
|| user_memcpy(&cookie, userCookie, sizeof(ssize_t)) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status_t status = copy_ref_var_from_user(userCookie, cookie);
|
|
||||||
if (status != B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
area_info info;
|
area_info info;
|
||||||
#ifdef _COMPAT_MODE
|
status_t status = _get_next_area_info(team, &cookie, &info,
|
||||||
status = _compat_get_next_area_info(team, &cookie, &info,
|
|
||||||
#else
|
|
||||||
status = _get_next_area_info(team, &cookie, &info,
|
|
||||||
#endif
|
|
||||||
sizeof(area_info));
|
sizeof(area_info));
|
||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
//info.protection &= B_USER_PROTECTION;
|
//info.protection &= B_USER_PROTECTION;
|
||||||
|
|
||||||
status = copy_ref_var_to_user(cookie, userCookie);
|
if (user_memcpy(userCookie, &cookie, sizeof(ssize_t)) < B_OK
|
||||||
if (status == B_OK)
|
|| user_memcpy(userInfo, &info, sizeof(area_info)) < B_OK)
|
||||||
status = copy_ref_var_to_user(info, userInfo);
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -6306,17 +6259,16 @@ _user_transfer_area(area_id area, void** userAddress, uint32 addressSpec,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* address;
|
void* address;
|
||||||
status_t status = copy_ref_var_from_user(userAddress, address);
|
if (!IS_USER_ADDRESS(userAddress)
|
||||||
if (status != B_OK)
|
|| user_memcpy(&address, userAddress, sizeof(address)) < B_OK)
|
||||||
return status;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
area_id newArea = transfer_area(area, &address, addressSpec, target, false);
|
area_id newArea = transfer_area(area, &address, addressSpec, target, false);
|
||||||
if (newArea < B_OK)
|
if (newArea < B_OK)
|
||||||
return newArea;
|
return newArea;
|
||||||
|
|
||||||
status = copy_ref_var_to_user(address, userAddress);
|
if (user_memcpy(userAddress, &address, sizeof(address)) < B_OK)
|
||||||
if (status != B_OK)
|
return B_BAD_ADDRESS;
|
||||||
return status;
|
|
||||||
|
|
||||||
return newArea;
|
return newArea;
|
||||||
}
|
}
|
||||||
@@ -6339,13 +6291,11 @@ _user_clone_area(const char* userName, void** userAddress, uint32 addressSpec,
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userName)
|
if (!IS_USER_ADDRESS(userName)
|
||||||
|| user_strlcpy(name, userName, sizeof(name)) < B_OK)
|
|| !IS_USER_ADDRESS(userAddress)
|
||||||
|
|| user_strlcpy(name, userName, sizeof(name)) < B_OK
|
||||||
|
|| user_memcpy(&address, userAddress, sizeof(address)) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status_t status = copy_ref_var_from_user(userAddress, address);
|
|
||||||
if (status != B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
fix_protection(&protection);
|
fix_protection(&protection);
|
||||||
|
|
||||||
area_id clonedArea = vm_clone_area(VMAddressSpace::CurrentID(), name,
|
area_id clonedArea = vm_clone_area(VMAddressSpace::CurrentID(), name,
|
||||||
@@ -6354,10 +6304,9 @@ _user_clone_area(const char* userName, void** userAddress, uint32 addressSpec,
|
|||||||
if (clonedArea < B_OK)
|
if (clonedArea < B_OK)
|
||||||
return clonedArea;
|
return clonedArea;
|
||||||
|
|
||||||
status = copy_ref_var_to_user(address, userAddress);
|
if (user_memcpy(userAddress, &address, sizeof(address)) < B_OK) {
|
||||||
if (status < B_OK) {
|
|
||||||
delete_area(clonedArea);
|
delete_area(clonedArea);
|
||||||
return status;
|
return B_BAD_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return clonedArea;
|
return clonedArea;
|
||||||
@@ -6381,13 +6330,11 @@ _user_create_area(const char* userName, void** userAddress, uint32 addressSpec,
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userName)
|
if (!IS_USER_ADDRESS(userName)
|
||||||
|| user_strlcpy(name, userName, sizeof(name)) < B_OK)
|
|| !IS_USER_ADDRESS(userAddress)
|
||||||
|
|| user_strlcpy(name, userName, sizeof(name)) < B_OK
|
||||||
|
|| user_memcpy(&address, userAddress, sizeof(address)) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status_t status = copy_ref_var_from_user(userAddress, address);
|
|
||||||
if (status != B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
if (addressSpec == B_EXACT_ADDRESS
|
if (addressSpec == B_EXACT_ADDRESS
|
||||||
&& IS_KERNEL_ADDRESS(address))
|
&& IS_KERNEL_ADDRESS(address))
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
@@ -6407,12 +6354,10 @@ _user_create_area(const char* userName, void** userAddress, uint32 addressSpec,
|
|||||||
size, lock, protection, 0, 0, &virtualRestrictions,
|
size, lock, protection, 0, 0, &virtualRestrictions,
|
||||||
&physicalRestrictions, false, &address);
|
&physicalRestrictions, false, &address);
|
||||||
|
|
||||||
if (area >= B_OK) {
|
if (area >= B_OK
|
||||||
status = copy_ref_var_to_user(address, userAddress);
|
&& user_memcpy(userAddress, &address, sizeof(address)) < B_OK) {
|
||||||
if (status < B_OK) {
|
delete_area(area);
|
||||||
delete_area(area);
|
return B_BAD_ADDRESS;
|
||||||
return status;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return area;
|
return area;
|
||||||
@@ -6446,14 +6391,11 @@ _user_map_file(const char* userName, void** userAddress, uint32 addressSpec,
|
|||||||
|
|
||||||
fix_protection(&protection);
|
fix_protection(&protection);
|
||||||
|
|
||||||
if (!IS_USER_ADDRESS(userName)
|
if (!IS_USER_ADDRESS(userName) || !IS_USER_ADDRESS(userAddress)
|
||||||
|| user_strlcpy(name, userName, B_OS_NAME_LENGTH) < B_OK)
|
|| user_strlcpy(name, userName, B_OS_NAME_LENGTH) < B_OK
|
||||||
|
|| user_memcpy(&address, userAddress, sizeof(address)) < B_OK)
|
||||||
return B_BAD_ADDRESS;
|
return B_BAD_ADDRESS;
|
||||||
|
|
||||||
status_t status = copy_ref_var_from_user(userAddress, address);
|
|
||||||
if (status != B_OK)
|
|
||||||
return status;
|
|
||||||
|
|
||||||
if (addressSpec == B_EXACT_ADDRESS) {
|
if (addressSpec == B_EXACT_ADDRESS) {
|
||||||
if ((addr_t)address + size < (addr_t)address
|
if ((addr_t)address + size < (addr_t)address
|
||||||
|| (addr_t)address % B_PAGE_SIZE != 0) {
|
|| (addr_t)address % B_PAGE_SIZE != 0) {
|
||||||
@@ -6471,11 +6413,8 @@ _user_map_file(const char* userName, void** userAddress, uint32 addressSpec,
|
|||||||
if (area < B_OK)
|
if (area < B_OK)
|
||||||
return area;
|
return area;
|
||||||
|
|
||||||
status = copy_ref_var_to_user(address, userAddress);
|
if (user_memcpy(userAddress, &address, sizeof(address)) < B_OK)
|
||||||
if (status < B_OK) {
|
return B_BAD_ADDRESS;
|
||||||
delete_area(area);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user