validate timer adjust address

This commit is contained in:
nakst 2021-12-05 17:38:03 +00:00
parent 73920030ff
commit 2d6baf19a0
3 changed files with 22 additions and 9 deletions

View File

@ -826,9 +826,8 @@ extern "C" bool PostContextSwitch(InterruptContext *context, MMSpace *oldAddress
currentThread->timerAdjustTicks += ProcessorReadTimeStamp() - local->currentThread->lastInterruptTimeStamp;
if (currentThread->timerAdjustAddress && MMArchIsBufferInUserRange(currentThread->timerAdjustAddress, sizeof(uint64_t))) {
// TODO If the MMArchSafeCopy fails, then the kernel will panic because interrupts are disabled here.
// We probably need a special version of MMArchSafeCopy that doesn't try to resolve page faults and fails faster.
// TODO Instead of timerAdjustAddress, maybe copy it onto a fixed location at the base of thread's stack?
// ES_SYSCALL_THREAD_SET_TIMER_ADJUST_ADDRESS ensures that this address is on the thread's user stack,
// which is managed by the kernel.
MMArchSafeCopy(currentThread->timerAdjustAddress, (uintptr_t) &local->currentThread->timerAdjustTicks, sizeof(uint64_t));
}

View File

@ -151,8 +151,6 @@ struct {
double performanceTimerStack[PERFORMANCE_TIMER_STACK_SIZE];
uintptr_t performanceTimerStackCount;
ThreadLocalStorage firstThreadLocalStorage;
EsHandle workAvailable;
EsMutex workMutex;
Array<Work> workQueue;
@ -1481,6 +1479,8 @@ void ThreadInitialise(ThreadLocalStorage *local) {
#include "desktop.cpp"
extern "C" void _start(EsProcessStartupInformation *_startupInformation) {
ThreadLocalStorage threadLocalStorage;
api.startupInformation = _startupInformation;
bool desktop = api.startupInformation->isDesktop;
@ -1498,7 +1498,7 @@ extern "C" void _start(EsProcessStartupInformation *_startupInformation) {
_init();
EsRandomSeed(ProcessorReadTimeStamp());
ThreadInitialise(&api.firstThreadLocalStorage);
ThreadInitialise(&threadLocalStorage);
EsMessageMutexAcquire();
api.global = (GlobalData *) EsMemoryMapObject(api.startupInformation->globalDataRegion,

View File

@ -1139,7 +1139,11 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_THREAD_STACK_SIZE) {
MMRegion *region = MMFindAndPinRegion(currentVMM, thread->userStackBase, thread->userStackReserve);
KMutexAcquire(&currentVMM->reserveMutex);
if (thread->userStackCommit <= argument3 && argument3 <= thread->userStackReserve && !(argument3 & (K_PAGE_BITS - 1)) && region) {
if (argument3 >= K_PAGE_SIZE /* see ES_SYSCALL_THREAD_SET_TIMER_ADJUST_ADDRESS */
&& thread->userStackCommit <= argument3
&& argument3 <= thread->userStackReserve
&& !(argument3 & (K_PAGE_BITS - 1))
&& region) {
#ifdef K_ARCH_STACK_GROWS_DOWN
success = MMCommitRange(currentVMM, region, (thread->userStackReserve - argument3) / K_PAGE_SIZE, argument3 / K_PAGE_SIZE);
#else
@ -1320,8 +1324,18 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_THREAD_SET_TLS) {
}
SYSCALL_IMPLEMENT(ES_SYSCALL_THREAD_SET_TIMER_ADJUST_ADDRESS) {
currentThread->timerAdjustAddress = argument0;
SYSCALL_RETURN(ES_SUCCESS, false);
#ifdef K_ARCH_STACK_GROWS_DOWN
uintptr_t page = currentThread->userStackBase + currentThread->userStackReserve - K_PAGE_SIZE;
#else
uintptr_t page = currentThread->userStackBase;
#endif
if (argument0 >= page && argument0 <= page + K_PAGE_SIZE - sizeof(uint64_t)) {
currentThread->timerAdjustAddress = argument0;
SYSCALL_RETURN(ES_SUCCESS, false);
} else {
SYSCALL_RETURN(ES_FATAL_ERROR_INVALID_MEMORY_REGION, true);
}
}
SYSCALL_IMPLEMENT(ES_SYSCALL_PROCESS_GET_TLS) {