permissions for shared regions

This commit is contained in:
nakst 2021-11-19 19:02:02 +00:00
parent 259da06df8
commit a9401068d7
13 changed files with 52 additions and 35 deletions

View File

@ -1512,8 +1512,8 @@ extern "C" void _start(EsProcessStartupInformation *_startupInformation) {
ThreadInitialise(&api.firstThreadLocalStorage);
EsMessageMutexAcquire();
api.global = (GlobalData *) EsObjectMap(api.startupInformation->globalDataRegion,
0, sizeof(GlobalData), desktop ? ES_MAP_OBJECT_READ_WRITE : ES_MAP_OBJECT_READ_ONLY);
api.global = (GlobalData *) EsMemoryMapObject(api.startupInformation->globalDataRegion,
0, sizeof(GlobalData), desktop ? ES_MEMORY_MAP_OBJECT_READ_WRITE : ES_MEMORY_MAP_OBJECT_READ_ONLY);
}
bool uiProcess = true; // TODO Determine this properly.

View File

@ -1504,7 +1504,7 @@ void InstanceBlankTabCreate(EsMessage *message) {
// TODO Generic icon and thumbnail cache in the API, based off the one from File Manager?
size_t fileBytes;
void *file = EsFileMap(application->cExecutable, -1, &fileBytes, ES_MAP_OBJECT_READ_ONLY);
void *file = EsFileMap(application->cExecutable, -1, &fileBytes, ES_MEMORY_MAP_OBJECT_READ_ONLY);
EsBundle bundle = { .base = (const BundleHeader *) file, .bytes = (ptrdiff_t) fileBytes };
if (file) {

View File

@ -360,8 +360,6 @@ define ES_REJECTED (-2)
define ES_LIST_VIEW_COLUMN_SORT_ASCENDING (1)
define ES_LIST_VIEW_COLUMN_SORT_DESCENDING (2)
define ES_MAP_OBJECT_ALL (0)
define ES_TEXT_H_LEFT (1 << 0)
define ES_TEXT_H_CENTER (1 << 1)
define ES_TEXT_H_RIGHT (1 << 2)
@ -407,9 +405,12 @@ define _ES_NODE_NO_WRITE_BASE (0x080000)
define ES_DIRECTORY_CHILDREN_UNKNOWN ((EsFileOffsetDifference) (-1))
define ES_MAP_OBJECT_READ_WRITE (0)
define ES_MAP_OBJECT_READ_ONLY (1)
define ES_MAP_OBJECT_COPY_ON_WRITE (2)
define ES_MEMORY_MAP_OBJECT_ALL (0) // Set size to this to map the entire object.
define ES_MEMORY_MAP_OBJECT_READ_WRITE (1 << 0)
define ES_MEMORY_MAP_OBJECT_READ_ONLY (1 << 1)
define ES_MEMORY_MAP_OBJECT_COPY_ON_WRITE (1 << 2) // Files only.
define ES_SHARED_MEMORY_READ_WRITE (1 << 0)
define ES_STRING_FORMAT_ENOUGH_SPACE (-1)
@ -740,6 +741,9 @@ define ES_SCROLL_X_DRAG (1 << 0)
define ES_SCROLL_Y_DRAG (1 << 1)
private define ES_SCROLL_MANUAL (1 << 2) // The parent is responsible for updating the position of the scroll bars.
define ES_SUBSYSTEM_ID_NATIVE (0)
define ES_SUBSYSTEM_ID_POSIX (1)
include desktop/icons.header
enum EsFatalError {
@ -2101,7 +2105,7 @@ function uint8_t EsMemorySumBytes(uint8_t *data, size_t bytes);
function void EsMemoryUnreserve(void *pointer, size_t size = 0); // Must cover the entire reserved region. Leave size 0 if you don't know the size.
function void EsMemoryZero(void *destination, size_t bytes);
function void *EsObjectMap(EsHandle object, uintptr_t offset, size_t size, unsigned flags);
function void *EsMemoryMapObject(EsHandle object, uintptr_t offset, size_t size, uint32_t flags);
// Standard functions.

View File

@ -697,10 +697,11 @@ void EsPOSIXInitialise(int *argc, char ***argv) {
// Get the arguments and environment.
EsHandle environmentHandle = startupInformation->data.environment;
EsHandle environmentHandle = startupInformation->data.subsystemData;
char *environmentBuffer = (char *) "./application\0\0LANG=en_US.UTF-8\0PWD=/\0HOME=/\0PATH=/Applications/POSIX/bin\0TMPDIR=/Applications/POSIX/tmp\0\0";
if (environmentHandle) {
EsAssert(startupInformation->data.subsystemID == ES_SUBSYSTEM_ID_POSIX);
environmentBuffer = (char *) EsHeapAllocate(ARG_MAX, false);
EsConstantBufferRead((EsHandle) environmentHandle, environmentBuffer);
EsHandleClose((EsHandle) environmentHandle);

View File

@ -299,7 +299,7 @@ EsHandle EsMemoryShare(EsHandle sharedMemoryRegion, EsHandle targetProcess, bool
return EsSyscall(ES_SYSCALL_HANDLE_SHARE, sharedMemoryRegion, targetProcess, readOnly, 0);
}
void *EsObjectMap(EsHandle sharedMemoryRegion, uintptr_t offset, size_t size, unsigned flags) {
void *EsMemoryMapObject(EsHandle sharedMemoryRegion, uintptr_t offset, size_t size, unsigned flags) {
intptr_t result = EsSyscall(ES_SYSCALL_MEMORY_MAP_OBJECT, sharedMemoryRegion, offset, size, flags);
if (result >= 0) {
@ -425,7 +425,7 @@ void *EsFileStoreMap(EsFileStore *file, size_t *fileSize, uint32_t flags) {
EsFileOffsetDifference size = EsFileStoreGetSize(file);
if (size == -1) return nullptr;
*fileSize = size;
return EsObjectMap(file->handle, 0, size, flags);
return EsMemoryMapObject(file->handle, 0, size, flags);
} else if (file->type == FILE_STORE_PATH) {
return EsFileMap(file->path, file->pathBytes, fileSize, flags);
} else if (file->type == FILE_STORE_EMBEDDED_FILE) {
@ -530,13 +530,13 @@ EsError EsFileDelete(EsHandle handle) {
void *EsFileMap(const char *path, ptrdiff_t pathBytes, size_t *fileSize, uint32_t flags) {
EsFileInformation information = EsFileOpen(path, pathBytes,
ES_NODE_FAIL_IF_NOT_FOUND | ((flags & ES_MAP_OBJECT_READ_WRITE) ? ES_FILE_WRITE : ES_FILE_READ));
ES_NODE_FAIL_IF_NOT_FOUND | ((flags & ES_MEMORY_MAP_OBJECT_READ_WRITE) ? ES_FILE_WRITE : ES_FILE_READ));
if (ES_CHECK_ERROR(information.error)) {
return nullptr;
}
void *base = EsObjectMap(information.handle, 0, information.size, flags);
void *base = EsMemoryMapObject(information.handle, 0, information.size, flags);
EsHandleClose(information.handle);
if (fileSize) *fileSize = information.size;
return base;

View File

@ -758,7 +758,7 @@ Font FontGet(EsFont key) {
// EsPrint("Loading font from '%z' (f%d/w%d/i%d).\n", file, key.family, key.weight, key.italic);
size_t size;
void *data = EsFileStoreMap(file, &size, ES_MAP_OBJECT_READ_ONLY);
void *data = EsFileStoreMap(file, &size, ES_MEMORY_MAP_OBJECT_READ_ONLY);
if (!data) {
EsPrint("Could not load font (f%d/w%d/i%d).\n", key.family, key.weight, key.italic);

View File

@ -1312,7 +1312,7 @@ bool ThemeInitialise() {
size_t cursorsBitmapBytes;
const void *cursorsBitmap = EsBundleFind(&bundleDesktop, EsLiteral("Cursors.png"), &cursorsBitmapBytes);
theming.cursorData = EsMemoryCreateShareableRegion(ES_THEME_CURSORS_WIDTH * ES_THEME_CURSORS_HEIGHT * 4);
void *destination = EsObjectMap(theming.cursorData, 0, ES_THEME_CURSORS_WIDTH * ES_THEME_CURSORS_HEIGHT * 4, ES_MAP_OBJECT_READ_WRITE);
void *destination = EsMemoryMapObject(theming.cursorData, 0, ES_THEME_CURSORS_WIDTH * ES_THEME_CURSORS_HEIGHT * 4, ES_MEMORY_MAP_OBJECT_READ_WRITE);
LoadImage(cursorsBitmap, cursorsBitmapBytes, destination, ES_THEME_CURSORS_WIDTH, ES_THEME_CURSORS_HEIGHT, true);
EsObjectUnmap(destination);
}
@ -1320,7 +1320,7 @@ bool ThemeInitialise() {
theming.cursors.width = ES_THEME_CURSORS_WIDTH;
theming.cursors.height = ES_THEME_CURSORS_HEIGHT;
theming.cursors.stride = ES_THEME_CURSORS_WIDTH * 4;
theming.cursors.bits = EsObjectMap(theming.cursorData, 0, ES_MAP_OBJECT_ALL, ES_MAP_OBJECT_READ_ONLY);
theming.cursors.bits = EsMemoryMapObject(theming.cursorData, 0, ES_MEMORY_MAP_OBJECT_ALL, ES_MEMORY_MAP_OBJECT_READ_ONLY);
theming.cursors.fullAlpha = true;
theming.cursors.readOnly = true;

View File

@ -154,7 +154,7 @@ EsError KLoadELF(KNode *node, KLoadedExecutable *executable) {
// Map the bundle file.
if (!MMMapFile(thisProcess->vmm, (FSFile *) node,
0, fileSize, ES_MAP_OBJECT_READ_ONLY,
0, fileSize, ES_MEMORY_MAP_OBJECT_READ_ONLY,
(uint8_t *) header.mapAddress)) {
return ES_ERROR_INSUFFICIENT_RESOURCES;
}
@ -239,7 +239,7 @@ EsError KLoadELF(KNode *node, KLoadedExecutable *executable) {
success = MMMapFile(thisProcess->vmm, (FSFile *) node,
executableOffset + fileOffset, zeroStart - fileStart,
ES_MAP_OBJECT_COPY_ON_WRITE,
ES_MEMORY_MAP_OBJECT_COPY_ON_WRITE,
(uint8_t *) fileStart, end - zeroStart);
if (success) {

View File

@ -1015,7 +1015,7 @@ void MMUnreserve(MMSpace *space, MMRegion *remove, bool unmapPages, bool guardRe
}
void *MMMapFile(MMSpace *space, FSFile *node, EsFileOffset offset, size_t bytes, int protection, void *baseAddress, size_t zeroedBytes, uint32_t additionalFlags) {
if (protection != ES_MAP_OBJECT_READ_ONLY && protection != ES_MAP_OBJECT_COPY_ON_WRITE) {
if (protection != ES_MEMORY_MAP_OBJECT_READ_ONLY && protection != ES_MEMORY_MAP_OBJECT_COPY_ON_WRITE) {
return nullptr;
}
@ -1025,7 +1025,7 @@ void *MMMapFile(MMSpace *space, FSFile *node, EsFileOffset offset, size_t bytes,
MMRegion *region = nullptr;
uint64_t fileHandleFlags = ES_NODE_PREVENT_RESIZE
| (protection == ES_MAP_OBJECT_READ_WRITE ? ES_FILE_WRITE_SHARED : ES_FILE_READ_SHARED);
| (protection == ES_MEMORY_MAP_OBJECT_READ_WRITE ? ES_FILE_WRITE_SHARED : ES_FILE_READ_SHARED);
bool decommit = false;
// Register a handle to the node.
@ -1056,8 +1056,8 @@ void *MMMapFile(MMSpace *space, FSFile *node, EsFileOffset offset, size_t bytes,
// Reserve the region.
region = MMReserve(space, bytes + zeroedBytes, MM_REGION_FILE | additionalFlags
| ((protection == ES_MAP_OBJECT_READ_ONLY || protection == ES_MAP_OBJECT_COPY_ON_WRITE) ? MM_REGION_READ_ONLY : 0)
| (protection == ES_MAP_OBJECT_COPY_ON_WRITE ? MM_REGION_COPY_ON_WRITE : 0),
| ((protection == ES_MEMORY_MAP_OBJECT_READ_ONLY || protection == ES_MEMORY_MAP_OBJECT_COPY_ON_WRITE) ? MM_REGION_READ_ONLY : 0)
| (protection == ES_MEMORY_MAP_OBJECT_COPY_ON_WRITE ? MM_REGION_COPY_ON_WRITE : 0),
baseAddress ? (uintptr_t) baseAddress - offsetIntoPage : 0);
if (!region) {
@ -1066,7 +1066,7 @@ void *MMMapFile(MMSpace *space, FSFile *node, EsFileOffset offset, size_t bytes,
// Commit copy on write regions.
if (protection == ES_MAP_OBJECT_COPY_ON_WRITE) {
if (protection == ES_MEMORY_MAP_OBJECT_COPY_ON_WRITE) {
if (!MMCommit(bytes + zeroedBytes, false)) {
goto fail;
}

View File

@ -373,7 +373,7 @@ uintptr_t HandleShare(Handle share, Process *process, uint32_t mode, EsHandle at
// TODO Sort out flag modes.
if (share.type == KERNEL_OBJECT_SHMEM) {
sharedFlags = mode;
sharedFlags &= mode;
} else if (share.type == KERNEL_OBJECT_NODE) {
sharedFlags = (mode & 1) && (share.flags & (ES_FILE_WRITE_SHARED | ES_FILE_WRITE)) ? ES_FILE_READ_SHARED : share.flags;
if (mode & 2) sharedFlags &= ~_ES_NODE_DIRECTORY_WRITE;

View File

@ -762,9 +762,10 @@ void ProcessLoadExecutable() {
startupInformation->tlsBytes = application.tlsBytes;
startupInformation->timeStampTicksPerMs = timeStampTicksPerMs;
if (OpenHandleToObject(mmGlobalDataRegion, KERNEL_OBJECT_SHMEM, ES_FLAGS_DEFAULT)) {
// TODO Write protection.
startupInformation->globalDataRegion = thisProcess->handleTable.OpenHandle(mmGlobalDataRegion, ES_FLAGS_DEFAULT, KERNEL_OBJECT_SHMEM);
uint32_t globalDataRegionFlags = thisProcess->type == PROCESS_DESKTOP ? ES_SHARED_MEMORY_READ_WRITE : ES_FLAGS_DEFAULT;
if (OpenHandleToObject(mmGlobalDataRegion, KERNEL_OBJECT_SHMEM, globalDataRegionFlags)) {
startupInformation->globalDataRegion = thisProcess->handleTable.OpenHandle(mmGlobalDataRegion, globalDataRegionFlags, KERNEL_OBJECT_SHMEM);
}
EsMemoryCopy(&startupInformation->data, &thisProcess->data, sizeof(EsProcessCreateData));

View File

@ -63,7 +63,7 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_MEMORY_ALLOCATE) {
if (argument0 > ES_SHARED_MEMORY_MAXIMUM_SIZE) SYSCALL_RETURN(ES_FATAL_ERROR_OUT_OF_RANGE, true);
MMSharedRegion *region = MMSharedCreateRegion(argument0, false, 0);
if (!region) SYSCALL_RETURN(ES_ERROR_INSUFFICIENT_RESOURCES, false);
SYSCALL_RETURN(currentProcess->handleTable.OpenHandle(region, 0, KERNEL_OBJECT_SHMEM), false);
SYSCALL_RETURN(currentProcess->handleTable.OpenHandle(region, ES_SHARED_MEMORY_READ_WRITE, KERNEL_OBJECT_SHMEM), false);
} else {
EsMemoryProtection protection = (EsMemoryProtection) argument2;
uint32_t flags = MM_REGION_USER;
@ -546,22 +546,33 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_THREAD_CREATE) {
SYSCALL_IMPLEMENT(ES_SYSCALL_MEMORY_MAP_OBJECT) {
SYSCALL_HANDLE_2(argument0, (KernelObjectType) (KERNEL_OBJECT_SHMEM | KERNEL_OBJECT_NODE), object);
if (((argument3 & ES_MEMORY_MAP_OBJECT_READ_WRITE) ? 1 : 0)
+ ((argument3 & ES_MEMORY_MAP_OBJECT_READ_ONLY) ? 1 : 0)
+ ((argument3 & ES_MEMORY_MAP_OBJECT_COPY_ON_WRITE) ? 1 : 0) != 1) {
SYSCALL_RETURN(ES_FATAL_ERROR_INCORRECT_FILE_ACCESS, true);
}
if (object.type == KERNEL_OBJECT_SHMEM) {
// TODO Access permissions and modes.
MMSharedRegion *region = (MMSharedRegion *) object.object;
if (argument2 == ES_MAP_OBJECT_ALL) {
if (argument2 == ES_MEMORY_MAP_OBJECT_ALL) {
argument2 = region->sizeBytes;
}
uintptr_t address = (uintptr_t) MMMapShared(currentVMM, region, argument1, argument2, MM_REGION_USER);
if ((argument3 == ES_MEMORY_MAP_OBJECT_READ_WRITE && (~object.flags & ES_SHARED_MEMORY_READ_WRITE))
|| argument3 == ES_MEMORY_MAP_OBJECT_COPY_ON_WRITE) {
SYSCALL_RETURN(ES_FATAL_ERROR_INSUFFICIENT_PERMISSIONS, true);
}
uint32_t flags = MM_REGION_USER | ((argument3 & ES_MEMORY_MAP_OBJECT_READ_ONLY) ? MM_REGION_READ_ONLY : 0);
uintptr_t address = (uintptr_t) MMMapShared(currentVMM, region, argument1 /* offset */, argument2 /* bytes */, flags);
SYSCALL_RETURN(address, false);
} else if (object.type == KERNEL_OBJECT_NODE) {
KNode *file = (KNode *) object.object;
if (file->directoryEntry->type != ES_NODE_FILE) SYSCALL_RETURN(ES_FATAL_ERROR_INCORRECT_NODE_TYPE, true);
if (argument3 == ES_MAP_OBJECT_READ_WRITE) {
if (argument3 == ES_MEMORY_MAP_OBJECT_READ_WRITE) {
if (!(object.flags & (ES_FILE_WRITE_SHARED | ES_FILE_WRITE))) {
SYSCALL_RETURN(ES_FATAL_ERROR_INCORRECT_FILE_ACCESS, true);
}
@ -571,7 +582,7 @@ SYSCALL_IMPLEMENT(ES_SYSCALL_MEMORY_MAP_OBJECT) {
}
}
if (argument2 == ES_MAP_OBJECT_ALL) {
if (argument2 == ES_MEMORY_MAP_OBJECT_ALL) {
argument2 = file->directoryEntry->totalSize;
}

View File

@ -91,7 +91,7 @@ EsMemoryCreateShareableRegion=89
EsMemoryShare=90
EsMemorySumBytes=91
EsMemoryZero=92
EsObjectMap=93
EsMemoryMapObject=93
EsAssertionFailure=94
EsDrawInvert=95
EsFileControl=96