After KPTI, it is no longer trivial for us to have a custom int 0x83 handler -> go back to ioctl()

This commit is contained in:
Lubos Dolezel 2018-05-27 21:19:14 +02:00
parent 6872a36b3d
commit d66e208242
12 changed files with 95 additions and 40 deletions

View File

@ -83,6 +83,10 @@ static NSLinkEditErrors sLastErrorFileCode;
static int sLastErrorNo;
#endif
#ifdef DARLING
extern "C" int mach_driver_get_fd(void);
#endif
// In 10.3.x and earlier all the NSObjectFileImage API's were implemeneted in libSystem.dylib
// Beginning in 10.4 the NSObjectFileImage API's are implemented in dyld and libSystem just forwards
// This conditional keeps support for old libSystem's which needed some help implementing the API's
@ -208,6 +212,9 @@ static struct dyld_func dyld_funcs[] = {
#if OLD_LIBSYSTEM_SUPPORT
{"__dyld_link_module", (void*)_dyld_link_module },
#endif
#ifdef DARLING
{"__dyld_get_mach_driver_fd", (void*)mach_driver_get_fd },
#endif
#endif //DEPRECATED_APIS_SUPPORTED
{NULL, 0}

View File

@ -195,7 +195,7 @@ static void rebaseDyld(const struct macho_header* mh, intptr_t slide)
}
extern "C" void mach_init();
extern "C" void mach_init(const char* apple[]);
extern "C" void __guard_setup(const char* apple[]);
@ -222,7 +222,7 @@ uintptr_t start(const struct macho_header* appsMachHeader, int argc, const char*
++apple;
// allow dyld to use mach messaging
mach_init();
mach_init(apple);
// set up random value for stack canary
__guard_setup(apple);

View File

@ -15,7 +15,6 @@ set(mach_server_client_sources
mach_time.c
lkm.c
darling_mach_syscall.S
lkm-int.S
mach_table.c
)

View File

@ -1,22 +0,0 @@
.globl _lkm_call
#if defined(__x86_64__)
_lkm_call:
movq %rdi, %rax
movq %rsi, %rcx
int $0x83
ret
#elif defined(__i386__)
_lkm_call:
movl 4(%esp), %eax
movl 8(%esp), %ecx
int $0x83
ret
#else
#error Missing implementation
#endif

View File

@ -21,8 +21,68 @@ extern _libkernel_functions_t _libkernel_functions;
extern void sigexc_setup1(void);
extern void sigexc_setup2(void);
void mach_driver_init(void)
static int driver_fd = -1;
void mach_driver_init(const char** applep)
{
#ifdef VARIANT_DYLD
if (applep != NULL)
{
int i;
for (i = 0; applep[i] != NULL; i++)
{
if (strncmp(applep[i], "kernfd=", 7) == 0)
{
driver_fd = __simple_atoi(applep[i] + 7, NULL);
break;
}
}
}
#else
// Ask for fd already set up by dyld
int (*p)(void);
_libkernel_functions->dyld_func_lookup("__dyld_get_mach_driver_fd", &p);
driver_fd = (*p)();
#endif
// If mach_driver_init() is being called in the fork child, the LKM will now
// swap out driver_fd for a new one.
if (__real_ioctl(driver_fd, NR_get_api_version, 0) != DARLING_MACH_API_VERSION)
{
const char* msg = "Darling Mach kernel module reports different API level. Aborting.\n";
sys_write(2, msg, strlen(msg));
sys_kill(0, 6);
}
// mach_driver_init() gets called at several points in application's lifetime:
// 1) When dyld loads
// 2) When libc initializes
// 3) After forking
#ifdef VARIANT_DYLD
struct rlimit lim;
if (sys_getrlimit(RLIMIT_NOFILE, &lim) == 0 && driver_fd != lim.rlim_cur)
{
// sys_getrlimit intentionally reports a limit lower by 1
// so that our fd remains "hidden" to applications.
// It also means rlim_cur is not above the limit
// in the following statement.
int d = sys_dup2(driver_fd, lim.rlim_cur);
sys_close(driver_fd);
driver_fd = d;
}
#endif
}
__attribute__((visibility("default")))
int lkm_call(int call_nr, void* arg)
{
return __real_ioctl(driver_fd, call_nr, arg);
}
int mach_driver_get_fd(void)
{
return driver_fd;
}

View File

@ -1,7 +1,7 @@
#ifndef _LKM_H
#define _LKM_H
void mach_driver_init(void);
void mach_driver_init(const char** applep);
int lkm_call(int call_nr, void* arg);

View File

@ -16,6 +16,12 @@ long sys_getrlimit(unsigned int which, struct rlimit* rlp)
if (ret < 0)
ret = errno_linux_to_bsd(ret);
if (which == LINUX_RLIMIT_NOFILE)
{
rlp->rlim_cur--;
rlp->rlim_max--;
}
return ret;
}

View File

@ -13,6 +13,12 @@ long sys_setrlimit(unsigned int which, const struct rlimit* rlp)
if (which == -1)
return -EINVAL;
if (which == LINUX_RLIMIT_NOFILE)
{
lim.rlim_cur++;
lim.rlim_max++;
}
ret = LINUX_SYSCALL(__NR_prlimit64, 0, which, &lim, 0);
if (ret < 0)
ret = errno_linux_to_bsd(ret);

View File

@ -31,7 +31,6 @@
#define LINUX_ADDR_NO_RANDOMIZE 0x40000
extern void mach_driver_init(void);
long sys_posix_spawn(int* pid, const char* path, const struct _posix_spawn_args_desc* desc,
char** argvp, char** envp)
@ -48,7 +47,7 @@ long sys_posix_spawn(int* pid, const char* path, const struct _posix_spawn_args_
if ((my_pid = sys_fork()) == 0)
{
mach_driver_init();
mach_driver_init(NULL);
// child
// close the reading side

View File

@ -78,10 +78,10 @@ vm_size_t vm_page_size = 0;
vm_size_t vm_page_mask = 0;
int vm_page_shift = 0;
int mach_init(void);
int mach_init(const char** applep);
int _mach_fork_child(void);
static void mach_init_doit(void);
static void mach_init_doit(const char** applep);
extern void _pthread_set_self(void *);
extern void _init_cpu_capabilities(void);
@ -99,11 +99,11 @@ host_page_size(__unused host_t host, vm_size_t *out_page_size)
* called by libSystem_initializer() in dynamic executables
*/
int
mach_init(void)
mach_init(const char** applep)
{
static bool mach_init_inited = false;
if (!mach_init_inited) {
mach_init_doit();
mach_init_doit(applep);
mach_init_inited = true;
}
return 0;
@ -113,7 +113,7 @@ mach_init(void)
int
_mach_fork_child(void)
{
mach_init_doit();
mach_init_doit(NULL);
return 0;
}
@ -123,9 +123,9 @@ void _mach_fork_parent(void)
}
void
mach_init_doit(void)
mach_init_doit(const char** applep)
{
mach_driver_init();
mach_driver_init(applep);
// Initialize cached mach ports defined in mach_init.h
mach_task_self_ = task_self_trap();

View File

@ -28,7 +28,7 @@
#include "_libkernel_init.h"
extern int mach_init(void);
extern int mach_init(const char** applep);
extern void sigexc_setup(void);
/* dlsym() funcptr is for legacy support in exc_catcher */
@ -40,7 +40,7 @@ _libkernel_functions_t _libkernel_functions;
void
__libkernel_init(_libkernel_functions_t fns,
const char *envp[] __attribute__((unused)),
const char *apple[] __attribute__((unused)),
const char *apple[],
const struct ProgramVars *vars __attribute__((unused)))
{
_libkernel_functions = fns;
@ -48,6 +48,6 @@ __libkernel_init(_libkernel_functions_t fns,
_dlsym = fns->dlsym;
}
mach_init();
mach_init(apple);
sigexc_setup();
}

@ -1 +1 @@
Subproject commit 56f0a2d84783a26ef27e8dde0ba75f4d802be8cc
Subproject commit 9e261dff1c08adf546e74b96fb853548f4f67bd7