Compare commits

..

No commits in common. "e5b26410190200f0b63ddd426f78ffe0d6bec855" and "71633e264fc5ccbe38bbddeb7b7689ede42255cb" have entirely different histories.

3 changed files with 21 additions and 37 deletions

View File

@ -1,12 +1,12 @@
#include "fs/devices/Framebuffer.h" #include "fs/devices/Framebuffer.h"
#include "bootboot.h"
#include "memory/MemoryManager.h"
#include "misc/utils.h"
#include "std/errno.h"
#include "std/stdio.h" #include "std/stdio.h"
#include "std/stdlib.h" #include "std/stdlib.h"
#include "std/string.h" #include "std/string.h"
#include "memory/MemoryManager.h"
#include "utils/Addresses.h" #include "utils/Addresses.h"
#include "misc/utils.h"
#include "std/errno.h"
#include "bootboot.h"
extern BOOTBOOT bootboot; extern BOOTBOOT bootboot;
extern char fb[1]; extern char fb[1];
@ -36,36 +36,39 @@ uintptr_t FramebufferDevice::mmap(VFS::Node* node, uintptr_t addr, size_t size,
{ {
if (!node) return -1; if (!node) return -1;
int real_prot = prot & ~(MAP_AS_OWNED_BY_TASK); int real_prot = prot & ~(MAP_AS_OWNED_BY_TASK);
if (round_down_to_nearest_page(offset) != (uintptr_t)offset) { return MAP_FAIL(EINVAL); } if(round_down_to_nearest_page(offset) != (uintptr_t)offset)
if ((size + offset) > bootboot.fb_size) {
return MAP_FAIL(EINVAL);
}
if((size + offset) > bootboot.fb_size)
{ {
return MAP_FAIL(ERANGE); // FIXME: Should probably be EOVERFLOW. return MAP_FAIL(ERANGE); // FIXME: Should probably be EOVERFLOW.
} }
MemoryManager::map_several_pages(bootboot.fb_ptr + offset, addr, Utilities::get_blocks_from_size(PAGE_SIZE, size), MemoryManager::map_several_pages(bootboot.fb_ptr + offset, addr, Utilities::get_blocks_from_size(PAGE_SIZE, size), real_prot);
real_prot);
return addr; return addr;
} }
ssize_t FramebufferDevice::write(VFS::Node* node, size_t offset, size_t size, const char* buffer) ssize_t FramebufferDevice::write(VFS::Node* node, size_t offset, size_t size, const char* buffer)
{ {
if (!node) return -1; if (!node) return -1;
if ((size + offset) > (uint64_t)bootboot.fb_size) { size = (uint64_t)bootboot.fb_size - offset; } if((size + offset) > (uint64_t)bootboot.fb_size)
{
size = (uint64_t)bootboot.fb_size - offset;
}
memcpy(fb + offset, buffer, size); memcpy(fb + offset, buffer, size);
return (ssize_t)size; return (ssize_t)size;
} }
#define FB_GET_WIDTH 0 #define FB_GET_WIDTH 0
#define FB_GET_HEIGHT 1 #define FB_GET_HEIGHT 1
#define FB_GET_SCANLINE 2
long FramebufferDevice::ioctl(VFS::Node* node, int cmd, uintptr_t) long FramebufferDevice::ioctl(VFS::Node* node, int cmd, uintptr_t)
{ {
if (!node) return -1; if (!node) return -1;
switch (cmd) switch(cmd)
{ {
case FB_GET_WIDTH: return (long)bootboot.fb_width; case FB_GET_WIDTH: return (long)bootboot.fb_width;
case FB_GET_HEIGHT: return (long)bootboot.fb_height; case FB_GET_HEIGHT: return (long)bootboot.fb_height;
case FB_GET_SCANLINE: return (long)bootboot.fb_scanline;
default: return -EINVAL; default: return -EINVAL;
} }
} }

View File

@ -25,16 +25,6 @@ static const char* format_permissions(uint32_t flags)
return perms; return perms;
} }
static bool can_execute_segment(int flags)
{
return flags & 1;
}
static bool can_write_segment(int flags)
{
return flags & 2;
}
ELFImage* ELFLoader::load_elf_from_filesystem(const char* filename) ELFImage* ELFLoader::load_elf_from_filesystem(const char* filename)
{ {
VFS::Node* node = VFS::resolve_path(filename); VFS::Node* node = VFS::resolve_path(filename);
@ -100,8 +90,6 @@ ELFImage* ELFLoader::load_elf_from_vfs(VFS::Node* node)
phdr.p_filesz, phdr.p_memsz, format_permissions(phdr.p_flags)); phdr.p_filesz, phdr.p_memsz, format_permissions(phdr.p_flags));
ensure(phdr.p_vaddr); ensure(phdr.p_vaddr);
ensure(!(can_write_segment(phdr.p_flags) && can_execute_segment(phdr.p_flags)));
uint64_t pages = Utilities::get_blocks_from_size(PAGE_SIZE, (phdr.p_vaddr % PAGE_SIZE) + phdr.p_memsz); uint64_t pages = Utilities::get_blocks_from_size(PAGE_SIZE, (phdr.p_vaddr % PAGE_SIZE) + phdr.p_memsz);
void* buffer = (void*)((uint64_t)MemoryManager::get_pages_at(round_down_to_nearest_page(phdr.p_vaddr), void* buffer = (void*)((uint64_t)MemoryManager::get_pages_at(round_down_to_nearest_page(phdr.p_vaddr),
pages, MAP_READ_WRITE) + pages, MAP_READ_WRITE) +
@ -118,8 +106,8 @@ ELFImage* ELFLoader::load_elf_from_vfs(VFS::Node* node)
VMM::switch_to_previous_user_address_space(); VMM::switch_to_previous_user_address_space();
int new_flags = MAP_USER | MAP_AS_OWNED_BY_TASK; int new_flags = MAP_USER | MAP_AS_OWNED_BY_TASK;
if (can_write_segment(phdr.p_flags)) new_flags |= MAP_READ_WRITE; if(phdr.p_flags & 2) new_flags |= MAP_READ_WRITE;
else if (can_execute_segment(phdr.p_flags)) new_flags |= MAP_EXEC; if(phdr.p_flags & 1) new_flags |= MAP_EXEC;
MemoryManager::protect(buffer, pages, new_flags); MemoryManager::protect(buffer, pages, new_flags);
@ -193,11 +181,6 @@ long ELFLoader::check_elf_image(VFS::Node* node)
kerrorln("trying to load ELF into kernel memory"); kerrorln("trying to load ELF into kernel memory");
return -ENOEXEC; return -ENOEXEC;
} }
if (can_write_segment(phdr.p_flags) && can_execute_segment(phdr.p_flags))
{
kwarnln("executable violates W^X");
return -ENOEXEC;
}
loadable_sections++; loadable_sections++;
memusage += Utilities::get_blocks_from_size(PAGE_SIZE, phdr.p_memsz) * PAGE_SIZE; memusage += Utilities::get_blocks_from_size(PAGE_SIZE, phdr.p_memsz) * PAGE_SIZE;
} }

View File

@ -7,8 +7,6 @@
#define FB_GET_WIDTH 0 #define FB_GET_WIDTH 0
/* Get the height of a framebuffer device. */ /* Get the height of a framebuffer device. */
#define FB_GET_HEIGHT 1 #define FB_GET_HEIGHT 1
/* Get the scanline of a framebuffer device. */
#define FB_GET_SCANLINE 2
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"