From 781b1d2d17db57053f5f24b4447d2789dc10dfab Mon Sep 17 00:00:00 2001 From: Sergey Lisov Date: Fri, 10 Jun 2022 18:33:42 +0300 Subject: [PATCH] Fix UaF on Mira's kernel process --- kernel/Makefile | 2 +- kernel/src/Mira.cpp | 7 +++ kernel/src/Plugins/Substitute/Substitute.cpp | 12 +++-- kernel/src/Utils/SysWrappers.cpp | 53 ++++++++++++++++++++ kernel/src/Utils/SysWrappers.hpp | 4 +- loader/Makefile | 4 +- 6 files changed, 75 insertions(+), 7 deletions(-) diff --git a/kernel/Makefile b/kernel/Makefile index 31ef4086..660f84bf 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -68,7 +68,7 @@ LIBS := C_DEFS := -D_KERNEL=1 -D_DEBUG -D_STANDALONE -D"MIRA_PLATFORM=${MIRA_PLATFORM}" -DMIRA_UNSUPPORTED_PLATFORMS -D__LP64__ -D_M_X64 -D__amd64__ -D__BSD_VISIBLE # C++ Flags, -02 Optimizations break shit badly -CFLAGS := $(I_DIRS) $(C_DEFS) -fpic -m64 -O0 -fno-builtin -nodefaultlibs -nostdlib -nostdinc -fcheck-new -ffreestanding -fno-strict-aliasing -fno-exceptions -fno-asynchronous-unwind-tables -Wall -Werror -Wno-unknown-pragmas +CFLAGS := $(I_DIRS) $(C_DEFS) -fpic -m64 -O0 -fno-builtin -nodefaultlibs -nostdlib -nostdinc -fcheck-new -ffreestanding -fno-strict-aliasing -fno-exceptions -fno-asynchronous-unwind-tables -Wall -Wno-unknown-pragmas -mno-red-zone # Assembly flags SFLAGS := -m64 -nodefaultlibs -nostdlib diff --git a/kernel/src/Mira.cpp b/kernel/src/Mira.cpp index ef778c15..5c6874d5 100644 --- a/kernel/src/Mira.cpp +++ b/kernel/src/Mira.cpp @@ -222,6 +222,13 @@ extern "C" void mira_entry(void* args) // At this point we don't need kernel context anymore WriteLog(LL_Info, "Mira initialization complete"); + + // Try not to exit + int pipe_fds[2]; + kpipe_t(pipe_fds, curthread); + char cha; + kread_t(pipe_fds[0], &cha, 1, curthread); + kthread_exit(); } diff --git a/kernel/src/Plugins/Substitute/Substitute.cpp b/kernel/src/Plugins/Substitute/Substitute.cpp index 109e7469..9e37fa72 100644 --- a/kernel/src/Plugins/Substitute/Substitute.cpp +++ b/kernel/src/Plugins/Substitute/Substitute.cpp @@ -1095,7 +1095,9 @@ void Substitute::OnProcessStart(void *arg, struct proc *p) char* s_SandboxPath = nullptr; char* s_Freepath = nullptr; - vn_fullpath(s_MainThread, fd->fd_jdir, &s_SandboxPath, &s_Freepath); + if (fd->fd_jdir != nullptr) { + vn_fullpath(s_MainThread, fd->fd_jdir, &s_SandboxPath, &s_Freepath); + } if (s_SandboxPath == nullptr) { if (s_Freepath) @@ -1213,7 +1215,9 @@ void Substitute::OnProcessExit(void *arg, struct proc *p) { char* s_SandboxPath = nullptr; char* s_Freepath = nullptr; - vn_fullpath(s_MainThread, fd->fd_jdir, &s_SandboxPath, &s_Freepath); + if (fd->fd_jdir != nullptr) { + vn_fullpath(s_MainThread, fd->fd_jdir, &s_SandboxPath, &s_Freepath); + } if (s_SandboxPath == nullptr) { if (s_Freepath) @@ -1301,7 +1305,9 @@ int Substitute::Sys_dynlib_dlsym_hook(struct thread* td, struct dynlib_dlsym_arg char* s_SandboxPath = nullptr; char* s_Freepath = nullptr; - vn_fullpath(s_MainThread, fd->fd_jdir, &s_SandboxPath, &s_Freepath); + if (fd->fd_jdir != nullptr) { + vn_fullpath(s_MainThread, fd->fd_jdir, &s_SandboxPath, &s_Freepath); + } if (s_SandboxPath == nullptr) { if (s_Freepath) diff --git a/kernel/src/Utils/SysWrappers.cpp b/kernel/src/Utils/SysWrappers.cpp index 3217f042..dea8c7ce 100644 --- a/kernel/src/Utils/SysWrappers.cpp +++ b/kernel/src/Utils/SysWrappers.cpp @@ -2520,3 +2520,56 @@ int ksandbox_path_t(char* path, struct thread* td) return ret; } + +int kpipe_internal(int* ans, struct thread* td) +{ + auto sv = (struct sysentvec*)kdlsym(self_orbis_sysvec); + struct sysent* sysents = sv->sv_table; + auto sys_pipe = (int(*)(struct thread*, struct pipe_args*))sysents[SYS_PIPE].sy_call; + if (!sys_pipe) + return -1; + + int error; + struct pipe_args uap; + + // clear errors + td->td_retval[0] = 0; + + // call syscall + error = sys_pipe(td, &uap); + if (error) + return -error; + + // return pipes + ans[0] = td->td_retval[0]; + ans[1] = td->td_retval[1]; + return 0; +} + +int kpipe_t(int* ans, struct thread* td) +{ + int ret = -EIO; + int retry = 0; + + for (;;) + { + ret = kpipe_internal(ans, td); + if (ret < 0) + { + if (ret == -EINTR) + { + if (retry > MaxInterruptRetries) + break; + + retry++; + continue; + } + + return ret; + } + + break; + } + + return ret; +} diff --git a/kernel/src/Utils/SysWrappers.hpp b/kernel/src/Utils/SysWrappers.hpp index 4fc8317d..a04133d2 100644 --- a/kernel/src/Utils/SysWrappers.hpp +++ b/kernel/src/Utils/SysWrappers.hpp @@ -159,4 +159,6 @@ extern "C" extern int klinkat_t(int fd1, const char *path1, int fd2, const char *path2, int flag, struct thread* td); extern int ksandbox_path_t(char* path, struct thread* td); -}; \ No newline at end of file + + extern int kpipe_t(int* fds, struct thread* td); +}; diff --git a/loader/Makefile b/loader/Makefile index 15b2e1f8..389e56c6 100644 --- a/loader/Makefile +++ b/loader/Makefile @@ -1,6 +1,6 @@ # CHANGEME: Default Orbis Version ifeq ($(MIRA_PLATFORM),) -MIRA_PLATFORM := MIRA_PLATFORM_ORBIS_BSD_620 +MIRA_PLATFORM := MIRA_PLATFORM_ORBIS_BSD_505 #MIRA_PLATFORM_STEAM_LINK2 #MIRA_PLATFORM_ORBIS_BSD_505 endif @@ -60,7 +60,7 @@ LIBS := C_DEFS := -D_KERNEL=1 -D_DEBUG -D_STANDALONE -D"MIRA_PLATFORM=${MIRA_PLATFORM}" -DMIRA_UNSUPPORTED_PLATFORMS -D__LP64__ -D_M_X64 -D__amd64__ -D__BSD_VISIBLE # C++ Flags, -02 Optimizations break shit badly -CFLAGS := $(I_DIRS) $(C_DEFS) -fpie -fPIC -m64 -std=c++17 -O0 -fno-builtin -nodefaultlibs -nostdlib -nostdinc -fcheck-new -ffreestanding -fno-strict-aliasing -fno-exceptions -fno-asynchronous-unwind-tables -Wall -Werror -Wno-unknown-pragmas +CFLAGS := $(I_DIRS) $(C_DEFS) -fpie -fPIC -m64 -std=c++17 -O0 -fno-builtin -nodefaultlibs -nostdlib -nostdinc -fcheck-new -ffreestanding -fno-strict-aliasing -fno-exceptions -fno-asynchronous-unwind-tables -Wall -Werror -Wno-unknown-pragmas -mno-red-zone # Assembly flags SFLAGS := -fPIE -m64 -nodefaultlibs -nostdlib