mirror of
https://github.com/clearlinux/graphene.git
synced 2026-08-27 11:16:54 +00:00
Convert flags between PAL API and host syscalls
Currently various flags in file and memory syscalls work mostly by an accident, because values of some of them align with corresponding Linux syscall flags. Some APIs weren't that lucky though - e.g. DkStreamOpen(..., /*options=*/PAL_OPTION_CLOEXEC) deletes file contents (sic!) intead of opening it with O_CLOEXEC. This is because PAL_OPTION_CLOEXEC == O_TRUNC. This commit fixes all this mess and also adds asserts to check validity of flags passed to Dk* handlers.
This commit is contained in:
@@ -85,7 +85,7 @@ struct shim_mem_entry {
|
||||
void* addr;
|
||||
size_t size;
|
||||
void** paddr;
|
||||
int prot;
|
||||
int prot; /*< Combination of PAL_PROT_* flags */
|
||||
void* data;
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/* Copyright (C) 2020 Invisible Things Lab
|
||||
Michał Kowalczyk <mkow@invisiblethingslab.com>
|
||||
This file is part of Graphene Library OS.
|
||||
Graphene Library OS is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public License
|
||||
as published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
Graphene Library OS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/*
|
||||
* This file defines conversions between Linux syscall flags and PAL API flags.
|
||||
*
|
||||
* For Linux-based PALs there is pal_flag_conv.h in Linux-common, mirroring those conversions.
|
||||
*/
|
||||
|
||||
#ifndef SHIM_FLAGS_CONV_H
|
||||
#define SHIM_FLAGS_CONV_H
|
||||
|
||||
#include <asm/fcntl.h>
|
||||
#include <asm/mman.h>
|
||||
#include <linux/fcntl.h>
|
||||
|
||||
#include "assert.h"
|
||||
#include "pal.h"
|
||||
|
||||
static inline int LINUX_PROT_TO_PAL(int prot, int map_flags) {
|
||||
assert(WITHIN_MASK(prot, PROT_READ | PROT_WRITE | PROT_EXEC));
|
||||
return (prot & PROT_READ ? PAL_PROT_READ : 0) |
|
||||
(prot & PROT_WRITE ? PAL_PROT_WRITE : 0) |
|
||||
(prot & PROT_EXEC ? PAL_PROT_EXEC : 0) |
|
||||
(map_flags & MAP_PRIVATE ? PAL_PROT_WRITECOPY : 0);
|
||||
}
|
||||
|
||||
static inline int LINUX_OPEN_FLAGS_TO_PAL_ACCESS(int access) {
|
||||
return (access & O_RDONLY ? PAL_ACCESS_RDONLY : 0) |
|
||||
(access & O_WRONLY ? PAL_ACCESS_WRONLY : 0) |
|
||||
(access & O_RDWR ? PAL_ACCESS_RDWR : 0) |
|
||||
(access & O_APPEND ? PAL_ACCESS_APPEND : 0);
|
||||
}
|
||||
|
||||
static inline int LINUX_OPEN_FLAGS_TO_PAL_CREATE(int flags) {
|
||||
if (WITHIN_MASK(O_CREAT | O_EXCL, flags))
|
||||
return PAL_CREATE_ALWAYS;
|
||||
if (flags & O_CREAT)
|
||||
return PAL_CREATE_TRY;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int LINUX_OPEN_FLAGS_TO_PAL_OPTIONS(int flags) {
|
||||
return (flags & O_CLOEXEC ? PAL_OPTION_CLOEXEC : 0) |
|
||||
(flags & O_NONBLOCK ? PAL_OPTION_NONBLOCK : 0);
|
||||
}
|
||||
|
||||
#endif /* SHIM_FLAGS_CONV_H */
|
||||
@@ -350,7 +350,7 @@ struct shim_handle {
|
||||
|
||||
struct shim_dir_handle dir_info;
|
||||
|
||||
int flags;
|
||||
int flags; /* Linux' O_* flags */
|
||||
int acc_mode;
|
||||
IDTYPE owner;
|
||||
struct shim_lock lock;
|
||||
|
||||
@@ -80,22 +80,6 @@ static inline void free_vma_val_array(struct shim_vma_val* vmas, size_t count) {
|
||||
#define NEED_MIGRATE_MEMORY(vma) \
|
||||
(((vma)->flags & VMA_TAINTED || !(vma)->file) && !((vma)->flags & VMA_UNMAPPED))
|
||||
|
||||
static inline PAL_FLG PAL_PROT(int prot, int flags) {
|
||||
PAL_FLG pal_prot = 0;
|
||||
|
||||
if (prot & PROT_READ)
|
||||
pal_prot |= PAL_PROT_READ;
|
||||
if (prot & PROT_WRITE)
|
||||
pal_prot |= PAL_PROT_WRITE;
|
||||
if (prot & PROT_EXEC)
|
||||
pal_prot |= PAL_PROT_EXEC;
|
||||
|
||||
if (flags & MAP_PRIVATE)
|
||||
pal_prot |= PAL_PROT_WRITECOPY;
|
||||
|
||||
return pal_prot;
|
||||
}
|
||||
|
||||
int init_vma(void);
|
||||
|
||||
/* Bookkeeping mmap() system call */
|
||||
|
||||
@@ -20,20 +20,20 @@
|
||||
* This file contains code to maintain bookkeeping of VMAs in library OS.
|
||||
*/
|
||||
|
||||
#include <shim_internal.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_vma.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_fs.h>
|
||||
|
||||
#include <pal.h>
|
||||
#include <list.h>
|
||||
|
||||
#include <asm/mman.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "list.h"
|
||||
#include "pal.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_flags_conv.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_vma.h"
|
||||
|
||||
/*
|
||||
* Internal bookkeeping for VMAs (virtual memory areas). This data
|
||||
* structure can only be accessed in this source file, with vma_list_lock
|
||||
@@ -1080,7 +1080,7 @@ BEGIN_CP_FUNC(vma)
|
||||
|
||||
struct shim_vma_val * vma = (struct shim_vma_val *) obj;
|
||||
struct shim_vma_val * new_vma = NULL;
|
||||
PAL_FLG pal_prot = PAL_PROT(vma->prot, 0);
|
||||
PAL_FLG pal_prot = LINUX_PROT_TO_PAL(vma->prot, /*map_flags=*/0);
|
||||
|
||||
ptr_t off = GET_FROM_CP_MAP(obj);
|
||||
|
||||
@@ -1187,11 +1187,9 @@ BEGIN_RS_FUNC(vma)
|
||||
}
|
||||
|
||||
if (need_mapped < vma->addr + vma->length) {
|
||||
int pal_alloc_type = 0;
|
||||
int pal_prot = vma->prot;
|
||||
if (DkVirtualMemoryAlloc(need_mapped,
|
||||
vma->addr + vma->length - need_mapped,
|
||||
pal_alloc_type, pal_prot)) {
|
||||
if (DkVirtualMemoryAlloc(need_mapped, vma->addr + vma->length - need_mapped,
|
||||
/*alloc_type=*/0,
|
||||
LINUX_PROT_TO_PAL(vma->prot, /*map_flags=*/0))) {
|
||||
need_mapped += vma->length;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,18 +26,19 @@
|
||||
#include <asm/mman.h>
|
||||
#include <asm/prctl.h>
|
||||
#include <errno.h>
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_utils.h>
|
||||
#include <shim_vdso.h>
|
||||
#include <shim_vma.h>
|
||||
|
||||
#include "elf.h"
|
||||
#include "ldsodefs.h"
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_flags_conv.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_utils.h"
|
||||
#include "shim_vdso.h"
|
||||
#include "shim_vma.h"
|
||||
|
||||
#ifndef DT_THISPROCNUM
|
||||
#define DT_THISPROCNUM 0
|
||||
@@ -199,7 +200,8 @@ static int protect_page(struct link_map* l, void* addr, size_t size) {
|
||||
void* start = ALLOC_ALIGN_DOWN_PTR(addr);
|
||||
void* end = ALLOC_ALIGN_UP_PTR(addr + size);
|
||||
|
||||
if (!DkVirtualMemoryProtect(start, end - start, PAL_PROT_READ | PAL_PROT_WRITE | prot))
|
||||
if (!DkVirtualMemoryProtect(start, end - start,
|
||||
PAL_PROT_READ | PAL_PROT_WRITE | LINUX_PROT_TO_PAL(prot, /*map_flags=*/0)))
|
||||
return -PAL_ERRNO;
|
||||
|
||||
if (!c)
|
||||
@@ -237,7 +239,8 @@ static int reprotect_map(struct link_map* l) {
|
||||
t = next;
|
||||
l->textrels = t;
|
||||
|
||||
if (c && !DkVirtualMemoryProtect((void*)start, end - start, prot)) {
|
||||
if (c && !DkVirtualMemoryProtect((void*)start, end - start,
|
||||
LINUX_PROT_TO_PAL(prot, /*map_flags=*/0))) {
|
||||
ret = -PAL_ERRNO;
|
||||
break;
|
||||
}
|
||||
@@ -613,13 +616,14 @@ do_remap:
|
||||
if ((c->prot & PROT_WRITE) == 0) {
|
||||
/* Dag nab it. */
|
||||
if (!DkVirtualMemoryProtect((caddr_t)ALLOC_ALIGN_DOWN(zero), g_pal_alloc_align,
|
||||
c->prot | PAL_PROT_WRITE)) {
|
||||
LINUX_PROT_TO_PAL(c->prot, /*map_flags=*/0)
|
||||
| PAL_PROT_WRITE)) {
|
||||
errstring = "cannot change memory protections";
|
||||
goto call_lose;
|
||||
}
|
||||
memset((void*)zero, '\0', zeropage - zero);
|
||||
if (!DkVirtualMemoryProtect((caddr_t)ALLOC_ALIGN_DOWN(zero), g_pal_alloc_align,
|
||||
c->prot)) {
|
||||
LINUX_PROT_TO_PAL(c->prot, /*map_flags=*/0))) {
|
||||
errstring = "cannot change memory protections";
|
||||
goto call_lose;
|
||||
}
|
||||
@@ -632,7 +636,8 @@ do_remap:
|
||||
if (type != OBJECT_MAPPED && type != OBJECT_INTERNAL && type != OBJECT_USER &&
|
||||
type != OBJECT_VDSO) {
|
||||
PAL_PTR mapat =
|
||||
DkVirtualMemoryAlloc((void*)zeropage, zeroend - zeropage, 0, c->prot);
|
||||
DkVirtualMemoryAlloc((void*)zeropage, zeroend - zeropage, /*alloc_type=*/0,
|
||||
LINUX_PROT_TO_PAL(c->prot, /*map_flags=*/0));
|
||||
if (!mapat) {
|
||||
errstring = "cannot map zero-fill pages";
|
||||
goto call_lose;
|
||||
@@ -1431,8 +1436,8 @@ static int vdso_map_init(void) {
|
||||
return -ENOMEM;
|
||||
assert(addr == ALLOC_ALIGN_UP_PTR(addr));
|
||||
|
||||
void* ret_addr = (void*)DkVirtualMemoryAlloc(addr, ALLOC_ALIGN_UP(vdso_so_size), 0,
|
||||
PAL_PROT_READ | PAL_PROT_WRITE);
|
||||
void* ret_addr = (void*)DkVirtualMemoryAlloc(addr, ALLOC_ALIGN_UP(vdso_so_size),
|
||||
/*alloc_type=*/0, PAL_PROT_READ | PAL_PROT_WRITE);
|
||||
if (!ret_addr)
|
||||
return -PAL_ERRNO;
|
||||
assert(addr == ret_addr);
|
||||
|
||||
@@ -20,25 +20,24 @@
|
||||
* This file contains codes for implementation of 'chroot' filesystem.
|
||||
*/
|
||||
|
||||
#include <shim_internal.h>
|
||||
#include <shim_thread.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_vma.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_utils.h>
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include <linux/stat.h>
|
||||
#include <linux/fcntl.h>
|
||||
// FIXME: Sorting these includes causes a bunch of "error: ‘S_IFREG’ undeclared" errors.
|
||||
#include "shim_flags_conv.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_thread.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_vma.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_utils.h"
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
|
||||
#include <asm/fcntl.h>
|
||||
#include <asm/mman.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <asm/prctl.h>
|
||||
#include <asm/unistd.h>
|
||||
#include <errno.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/stat.h>
|
||||
|
||||
#define URI_MAX_SIZE STR_SIZE
|
||||
|
||||
@@ -382,11 +381,8 @@ static int chroot_lookup (struct shim_dentry * dent)
|
||||
return query_dentry(dent, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static int __chroot_open (struct shim_dentry * dent,
|
||||
const char * uri, int flags, mode_t mode,
|
||||
struct shim_handle * hdl,
|
||||
struct shim_file_data * data)
|
||||
{
|
||||
static int __chroot_open(struct shim_dentry* dent, const char* uri, int flags, mode_t mode,
|
||||
struct shim_handle* hdl, struct shim_file_data* data) {
|
||||
int ret = 0;
|
||||
|
||||
if (!uri) {
|
||||
@@ -394,13 +390,12 @@ static int __chroot_open (struct shim_dentry * dent,
|
||||
}
|
||||
|
||||
int version = atomic_read(&data->version);
|
||||
int oldmode = flags & O_ACCMODE;
|
||||
int oldmode = LINUX_OPEN_FLAGS_TO_PAL_ACCESS(flags);
|
||||
int accmode = oldmode;
|
||||
int creat = flags & PAL_CREATE_MASK;
|
||||
int option = flags & PAL_OPTION_MASK;
|
||||
int create = LINUX_OPEN_FLAGS_TO_PAL_CREATE(flags);
|
||||
int options = LINUX_OPEN_FLAGS_TO_PAL_OPTIONS(flags);
|
||||
|
||||
if ((data->type == FILE_REGULAR || data->type == FILE_UNKNOWN)
|
||||
&& accmode == O_WRONLY)
|
||||
if ((data->type == FILE_REGULAR || data->type == FILE_UNKNOWN) && accmode == O_WRONLY)
|
||||
accmode = O_RDWR;
|
||||
|
||||
PAL_HANDLE palhdl;
|
||||
@@ -408,12 +403,11 @@ static int __chroot_open (struct shim_dentry * dent,
|
||||
if (hdl && hdl->pal_handle) {
|
||||
palhdl = hdl->pal_handle;
|
||||
} else {
|
||||
palhdl = DkStreamOpen(uri, accmode, mode, creat, option);
|
||||
palhdl = DkStreamOpen(uri, accmode, mode, create, options);
|
||||
|
||||
if (!palhdl) {
|
||||
if (PAL_NATIVE_ERRNO == PAL_ERROR_DENIED &&
|
||||
accmode != oldmode)
|
||||
palhdl = DkStreamOpen(uri, oldmode, mode, creat, option);
|
||||
if (PAL_NATIVE_ERRNO == PAL_ERROR_DENIED && accmode != oldmode)
|
||||
palhdl = DkStreamOpen(uri, oldmode, mode, create, options);
|
||||
|
||||
if (!palhdl)
|
||||
return -PAL_ERRNO;
|
||||
@@ -421,7 +415,7 @@ static int __chroot_open (struct shim_dentry * dent,
|
||||
|
||||
/* If DENTRY_LISTED is set on the parent dentry, list_directory_dentry() will not update
|
||||
* dent's ino, so ino will be actively updated here. */
|
||||
if (creat)
|
||||
if (create)
|
||||
chroot_update_ino(dent);
|
||||
}
|
||||
|
||||
@@ -445,11 +439,9 @@ static int __chroot_open (struct shim_dentry * dent,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int chroot_open (struct shim_handle * hdl, struct shim_dentry * dent,
|
||||
int flags)
|
||||
{
|
||||
static int chroot_open(struct shim_handle* hdl, struct shim_dentry* dent, int flags) {
|
||||
int ret = 0;
|
||||
struct shim_file_data * data;
|
||||
struct shim_file_data* data;
|
||||
if ((ret = try_create_data(dent, NULL, 0, &data)) < 0)
|
||||
return ret;
|
||||
|
||||
@@ -529,7 +521,7 @@ static int chroot_mkdir (struct shim_dentry * dir, struct shim_dentry * dent,
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = __chroot_open(dent, NULL, O_CREAT|O_EXCL, mode, NULL, data);
|
||||
ret = __chroot_open(dent, NULL, O_CREAT | O_EXCL, mode, NULL, data);
|
||||
|
||||
/* Increment the parent's link count */
|
||||
struct shim_file_data *parent_data = FILE_DENTRY_DATA(dir);
|
||||
@@ -726,7 +718,7 @@ static int chroot_mmap (struct shim_handle * hdl, void ** addr, size_t size,
|
||||
if (NEED_RECREATE(hdl) && (ret = chroot_recreate(hdl)) < 0)
|
||||
return ret;
|
||||
|
||||
int pal_prot = PAL_PROT(prot, flags);
|
||||
int pal_prot = LINUX_PROT_TO_PAL(prot, flags);
|
||||
|
||||
#if MAP_FILE == 0
|
||||
if (flags & MAP_ANONYMOUS)
|
||||
|
||||
@@ -605,8 +605,7 @@ static void * cp_alloc (struct shim_cp_store * store, void * addr, size_t size)
|
||||
bkeep_munmap(addr + size, reserve_size, CP_VMA_FLAGS);
|
||||
}
|
||||
|
||||
addr = (void *) DkVirtualMemoryAlloc(addr, size, 0,
|
||||
PAL_PROT_READ|PAL_PROT_WRITE);
|
||||
addr = (void*)DkVirtualMemoryAlloc(addr, size, 0, PAL_PROT_READ | PAL_PROT_WRITE);
|
||||
if (!addr)
|
||||
bkeep_munmap(addr, size, CP_VMA_FLAGS);
|
||||
|
||||
@@ -863,9 +862,7 @@ int do_migration (struct newproc_cp_header * hdr, void ** cpptr)
|
||||
|
||||
debug("checkpoint mapped at %p-%p\n", base, base + size);
|
||||
|
||||
PAL_FLG pal_prot = PAL_PROT_READ|PAL_PROT_WRITE;
|
||||
|
||||
PAL_PTR mapped = DkVirtualMemoryAlloc(mapaddr, mapsize, 0, pal_prot);
|
||||
PAL_PTR mapped = DkVirtualMemoryAlloc(mapaddr, mapsize, 0, PAL_PROT_READ | PAL_PROT_WRITE);
|
||||
if (!mapped)
|
||||
return -PAL_ERRNO;
|
||||
|
||||
|
||||
@@ -207,9 +207,7 @@ void * allocate_stack (size_t size, size_t protect_size, bool user)
|
||||
if (!stack)
|
||||
return NULL;
|
||||
|
||||
stack = (void *)
|
||||
DkVirtualMemoryAlloc(stack, size + protect_size,
|
||||
0, PAL_PROT_NONE);
|
||||
stack = (void*)DkVirtualMemoryAlloc(stack, size + protect_size, 0, PAL_PROT_NONE);
|
||||
} else {
|
||||
stack = system_malloc(size + protect_size);
|
||||
}
|
||||
|
||||
@@ -140,8 +140,8 @@ int init_brk_region(void* brk_region, size_t data_segment_size) {
|
||||
void* end_brk_region = NULL;
|
||||
|
||||
/* Allocate the whole brk region */
|
||||
void* ret =
|
||||
(void*)DkVirtualMemoryAlloc(brk_region, brk_max_size, 0, PAL_PROT_READ | PAL_PROT_WRITE);
|
||||
void* ret = (void*)DkVirtualMemoryAlloc(brk_region, brk_max_size, /*alloc_type=*/0,
|
||||
PAL_PROT_READ | PAL_PROT_WRITE);
|
||||
|
||||
/* Checking if the PAL call succeeds. */
|
||||
if (!ret) {
|
||||
@@ -286,7 +286,8 @@ BEGIN_RS_FUNC(brk) {
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
void* ptr = DkVirtualMemoryAlloc(alloc_addr, alloc_size, 0, PAL_PROT_READ | PAL_PROT_WRITE);
|
||||
void* ptr = DkVirtualMemoryAlloc(alloc_addr, alloc_size, /*alloc_type=*/0,
|
||||
PAL_PROT_READ | PAL_PROT_WRITE);
|
||||
__UNUSED(ptr);
|
||||
assert(ptr == alloc_addr);
|
||||
debug("brk reserved area: %p - %p\n", alloc_addr, alloc_addr + alloc_size);
|
||||
|
||||
@@ -195,6 +195,9 @@ int shim_do_chmod(const char* path, mode_t mode) {
|
||||
struct shim_dentry* dent = NULL;
|
||||
int ret = 0;
|
||||
|
||||
/* This isn't documented, but that's what Linux does. */
|
||||
mode &= 07777;
|
||||
|
||||
if (test_user_string(path))
|
||||
return -EFAULT;
|
||||
|
||||
@@ -221,6 +224,9 @@ int shim_do_fchmodat(int dfd, const char* filename, mode_t mode) {
|
||||
if (test_user_string(filename))
|
||||
return -EFAULT;
|
||||
|
||||
/* This isn't documented, but that's what Linux does. */
|
||||
mode &= 07777;
|
||||
|
||||
struct shim_dentry* dir = NULL;
|
||||
struct shim_dentry* dent = NULL;
|
||||
int ret = 0;
|
||||
@@ -251,6 +257,9 @@ int shim_do_fchmod(int fd, mode_t mode) {
|
||||
if (!hdl)
|
||||
return -EBADF;
|
||||
|
||||
/* This isn't documented, but that's what Linux does. */
|
||||
mode &= 07777;
|
||||
|
||||
struct shim_dentry* dent = hdl->dentry;
|
||||
int ret = 0;
|
||||
|
||||
|
||||
@@ -21,16 +21,18 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_vma.h>
|
||||
#include <stdatomic.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_flags_conv.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_vma.h"
|
||||
|
||||
void* shim_do_mmap(void* addr, size_t length, int prot, int flags, int fd, off_t offset) {
|
||||
struct shim_handle* hdl = NULL;
|
||||
long ret = 0;
|
||||
@@ -116,7 +118,8 @@ void* shim_do_mmap(void* addr, size_t length, int prot, int flags, int fd, off_t
|
||||
/* addr needs to be kept for bkeep_munmap() below */
|
||||
void* ret_addr = addr;
|
||||
if (!hdl) {
|
||||
ret_addr = (void*)DkVirtualMemoryAlloc(ret_addr, length, pal_alloc_type, PAL_PROT(prot, 0));
|
||||
ret_addr = (void*)DkVirtualMemoryAlloc(ret_addr, length, pal_alloc_type,
|
||||
LINUX_PROT_TO_PAL(prot, /*map_flags=*/0));
|
||||
|
||||
if (!ret_addr) {
|
||||
if (PAL_NATIVE_ERRNO == PAL_ERROR_DENIED)
|
||||
@@ -125,7 +128,7 @@ void* shim_do_mmap(void* addr, size_t length, int prot, int flags, int fd, off_t
|
||||
ret = -PAL_ERRNO;
|
||||
}
|
||||
} else {
|
||||
ret = hdl->fs->fs_ops->mmap(hdl, &ret_addr, length, PAL_PROT(prot, flags), flags, offset);
|
||||
ret = hdl->fs->fs_ops->mmap(hdl, &ret_addr, length, prot, flags, offset);
|
||||
}
|
||||
|
||||
if (hdl)
|
||||
@@ -153,7 +156,7 @@ int shim_do_mprotect(void* addr, size_t length, int prot) {
|
||||
if (bkeep_mprotect(addr, length, prot, 0) < 0)
|
||||
return -EPERM;
|
||||
|
||||
if (!DkVirtualMemoryProtect(addr, length, prot))
|
||||
if (!DkVirtualMemoryProtect(addr, length, LINUX_PROT_TO_PAL(prot, /*map_flags=*/0)))
|
||||
return -PAL_ERRNO;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -114,6 +114,14 @@ int shim_do_open (const char * file, int flags, mode_t mode)
|
||||
if (file[0] == '\0')
|
||||
return -EINVAL;
|
||||
|
||||
if (!(flags & O_CREAT)) {
|
||||
/* `mode` should be ignored if O_CREAT is not specified, according to man */
|
||||
mode = 0;
|
||||
} else {
|
||||
/* This isn't documented, but that's what Linux does. */
|
||||
mode &= 07777;
|
||||
}
|
||||
|
||||
struct shim_handle * hdl = get_new_handle();
|
||||
if (!hdl)
|
||||
return -ENOMEM;
|
||||
@@ -139,6 +147,14 @@ int shim_do_openat (int dfd, const char * filename, int flags, int mode)
|
||||
if (!filename || test_user_string(filename))
|
||||
return -EFAULT;
|
||||
|
||||
if (!(flags & O_CREAT)) {
|
||||
/* `mode` should be ignored if O_CREAT is not specified, according to man */
|
||||
mode = 0;
|
||||
} else {
|
||||
/* This isn't documented, but that's what Linux does. */
|
||||
mode &= 07777;
|
||||
}
|
||||
|
||||
struct shim_dentry * dir = NULL;
|
||||
int ret = 0;
|
||||
|
||||
|
||||
@@ -22,13 +22,15 @@
|
||||
|
||||
#include <asm/fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_utils.h>
|
||||
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
#include "shim_flags_conv.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
static int create_pipes(PAL_HANDLE* srv, PAL_HANDLE* cli, int flags, char* name,
|
||||
struct shim_qstr* qstr) {
|
||||
@@ -39,13 +41,18 @@ static int create_pipes(PAL_HANDLE* srv, PAL_HANDLE* cli, int flags, char* name,
|
||||
PAL_HANDLE hdl1 = NULL; /* one pipe end (accepted connect from hdl2) */
|
||||
PAL_HANDLE hdl2 = NULL; /* other pipe end (connects to hdl0 and talks to hdl1) */
|
||||
|
||||
if (flags & O_DIRECT) {
|
||||
debug("create_pipes(): tried to create O_DIRECT pipe, which is not supported.\n");
|
||||
flags &= ~O_DIRECT;
|
||||
}
|
||||
|
||||
if ((ret = create_pipe(name, uri, PIPE_URI_SIZE, &hdl0, qstr,
|
||||
/*use_vmid_for_name=*/false)) < 0) {
|
||||
debug("pipe creation failure\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!(hdl2 = DkStreamOpen(uri, 0, 0, 0, flags & O_NONBLOCK))) {
|
||||
if (!(hdl2 = DkStreamOpen(uri, 0, 0, 0, LINUX_OPEN_FLAGS_TO_PAL_OPTIONS(flags)))) {
|
||||
ret = -PAL_ERRNO;
|
||||
debug("pipe connection failure\n");
|
||||
goto out;
|
||||
|
||||
@@ -31,13 +31,13 @@
|
||||
#include "hex.h"
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
#include <shim_internal.h>
|
||||
#include <shim_table.h>
|
||||
#include <shim_utils.h>
|
||||
#include "shim_checkpoint.h"
|
||||
#include "shim_flags_conv.h"
|
||||
#include "shim_fs.h"
|
||||
#include "shim_handle.h"
|
||||
#include "shim_internal.h"
|
||||
#include "shim_table.h"
|
||||
#include "shim_utils.h"
|
||||
|
||||
/*
|
||||
* User-settable options (used with setsockopt).
|
||||
@@ -533,7 +533,8 @@ int shim_do_bind(int sockfd, struct sockaddr* addr, socklen_t addrlen) {
|
||||
create_flags &= ~PAL_CREATE_DUALSTACK;
|
||||
}
|
||||
|
||||
PAL_HANDLE pal_hdl = DkStreamOpen(qstrgetstr(&hdl->uri), 0, 0, create_flags, hdl->flags & O_NONBLOCK);
|
||||
PAL_HANDLE pal_hdl = DkStreamOpen(qstrgetstr(&hdl->uri), 0, 0, create_flags,
|
||||
hdl->flags & O_NONBLOCK ? PAL_OPTION_NONBLOCK : 0);
|
||||
|
||||
if (!pal_hdl) {
|
||||
ret = (PAL_NATIVE_ERRNO == PAL_ERROR_STREAMEXIST) ? -EADDRINUSE : -PAL_ERRNO;
|
||||
@@ -802,7 +803,8 @@ int shim_do_connect(int sockfd, struct sockaddr* addr, int addrlen) {
|
||||
if ((ret = create_socket_uri(hdl)) < 0)
|
||||
goto out;
|
||||
|
||||
PAL_HANDLE pal_hdl = DkStreamOpen(qstrgetstr(&hdl->uri), 0, 0, 0, hdl->flags & O_NONBLOCK);
|
||||
PAL_HANDLE pal_hdl = DkStreamOpen(qstrgetstr(&hdl->uri), 0, 0, 0,
|
||||
hdl->flags & O_NONBLOCK ? PAL_OPTION_NONBLOCK : 0);
|
||||
|
||||
if (!pal_hdl) {
|
||||
ret = (PAL_NATIVE_ERRNO == PAL_ERROR_DENIED) ? -ECONNREFUSED : -PAL_ERRNO;
|
||||
@@ -1061,7 +1063,8 @@ static ssize_t do_sendmsg(int fd, struct iovec* bufs, int nbufs, int flags,
|
||||
}
|
||||
|
||||
if (sock->sock_state == SOCK_CREATED && !pal_hdl) {
|
||||
pal_hdl = DkStreamOpen(URI_PREFIX_UDP, 0, 0, 0, hdl->flags & O_NONBLOCK);
|
||||
pal_hdl = DkStreamOpen(URI_PREFIX_UDP, 0, 0, 0,
|
||||
hdl->flags & O_NONBLOCK ? PAL_OPTION_NONBLOCK : 0);
|
||||
if (!pal_hdl) {
|
||||
ret = -PAL_ERRNO;
|
||||
goto out_locked;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import os
|
||||
import unittest
|
||||
import shutil
|
||||
import subprocess
|
||||
|
||||
from regression import (
|
||||
@@ -240,6 +241,9 @@ class TC_30_Syscall(RegressionTestCase):
|
||||
self.assertIn('fstat returned the fd type as S_IFDIR', stdout)
|
||||
|
||||
def test_020_getdents(self):
|
||||
if os.path.exists("root"):
|
||||
shutil.rmtree("root")
|
||||
|
||||
# This doesn't catch extraneous entries, but should be fine
|
||||
# until the LTP test can be run (need symlink support)
|
||||
|
||||
@@ -261,6 +265,8 @@ class TC_30_Syscall(RegressionTestCase):
|
||||
self.assertIn('getdents64: dir3 [0x4]', stdout)
|
||||
|
||||
def test_021_getdents_large_dir(self):
|
||||
if os.path.exists("tmp/large_dir"):
|
||||
shutil.rmtree("tmp/large_dir")
|
||||
stdout, _ = self.run_binary(['large_dir_read', 'tmp/large_dir', '3000'])
|
||||
|
||||
self.assertIn('Success!', stdout)
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/* Copyright (C) 2020 Invisible Things Lab
|
||||
Michał Kowalczyk <mkow@invisiblethingslab.com>
|
||||
This file is part of Graphene Library OS.
|
||||
Graphene Library OS is free software: you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public License
|
||||
as published by the Free Software Foundation, either version 3 of the
|
||||
License, or (at your option) any later version.
|
||||
Graphene Library OS is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/*
|
||||
* This file defines conversions between various PAL API flags and the flags used by Linux syscalls.
|
||||
*
|
||||
* The counterpart of this file is shim_flag_conv.h in LibOS.
|
||||
*/
|
||||
|
||||
#ifndef PAL_FLAGS_CONV_H
|
||||
#define PAL_FLAGS_CONV_H
|
||||
|
||||
#undef __GLIBC__
|
||||
#include <asm/fcntl.h>
|
||||
#include <linux/mman.h>
|
||||
#include <linux/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "assert.h"
|
||||
#include "pal.h"
|
||||
|
||||
static inline int PAL_MEM_FLAGS_TO_LINUX(int alloc_type, int prot) {
|
||||
assert(WITHIN_MASK(alloc_type, PAL_ALLOC_MASK));
|
||||
assert(WITHIN_MASK(prot, PAL_PROT_MASK));
|
||||
|
||||
return (alloc_type & PAL_ALLOC_RESERVE ? MAP_NORESERVE | MAP_UNINITIALIZED : 0) |
|
||||
(prot & PAL_PROT_WRITECOPY ? MAP_PRIVATE : MAP_SHARED);
|
||||
}
|
||||
|
||||
static inline int PAL_PROT_TO_LINUX(int prot) {
|
||||
assert(WITHIN_MASK(prot, PAL_PROT_MASK));
|
||||
return (prot & PAL_PROT_READ ? PROT_READ : 0) |
|
||||
(prot & PAL_PROT_WRITE ? PROT_WRITE : 0) |
|
||||
(prot & PAL_PROT_EXEC ? PROT_EXEC : 0);
|
||||
}
|
||||
|
||||
static inline int PAL_ACCESS_TO_LINUX_OPEN(int access) {
|
||||
assert(WITHIN_MASK(access, PAL_ACCESS_MASK));
|
||||
return (access & PAL_ACCESS_RDONLY ? O_RDONLY : 0) |
|
||||
(access & PAL_ACCESS_WRONLY ? O_WRONLY : 0) |
|
||||
(access & PAL_ACCESS_RDWR ? O_RDWR : 0) |
|
||||
(access & PAL_ACCESS_APPEND ? O_APPEND : 0);
|
||||
}
|
||||
|
||||
static inline int PAL_CREATE_TO_LINUX_OPEN(int create) {
|
||||
assert(create == 0 || create == PAL_CREATE_TRY || create == PAL_CREATE_ALWAYS);
|
||||
return (create & PAL_CREATE_TRY ? O_CREAT : 0) |
|
||||
(create & PAL_CREATE_ALWAYS ? O_CREAT | O_EXCL : 0);
|
||||
}
|
||||
|
||||
static inline int PAL_OPTION_TO_LINUX_OPEN(int options) {
|
||||
assert(WITHIN_MASK(options, PAL_OPTION_CLOEXEC | PAL_OPTION_NONBLOCK));
|
||||
return (options & PAL_OPTION_CLOEXEC ? O_CLOEXEC : 0) |
|
||||
(options & PAL_OPTION_NONBLOCK ? O_NONBLOCK : 0);
|
||||
}
|
||||
|
||||
#endif /* PAL_FLAGS_CONV_H */
|
||||
+36
-30
@@ -352,8 +352,10 @@ PAL_CONTROL * pal_control_addr (void);
|
||||
|
||||
/*! Memory Allocation Flags */
|
||||
enum PAL_ALLOC {
|
||||
PAL_ALLOC_RESERVE = 0x0001, /*!< Only reserve the memory */
|
||||
PAL_ALLOC_INTERNAL = 0x8000, /*!< Allocate for PAL (valid only if #IN_PAL) */
|
||||
PAL_ALLOC_RESERVE = 0x1, /*!< Only reserve the memory */
|
||||
PAL_ALLOC_INTERNAL = 0x2, /*!< Allocate for PAL (valid only if #IN_PAL) */
|
||||
|
||||
PAL_ALLOC_MASK = 0x3,
|
||||
};
|
||||
|
||||
/*! Memory Protection Flags */
|
||||
@@ -447,44 +449,49 @@ DkProcessExit(PAL_NUM exitCode);
|
||||
|
||||
/*! Stream Access Flags */
|
||||
enum PAL_ACCESS {
|
||||
PAL_ACCESS_RDONLY = 00,
|
||||
PAL_ACCESS_WRONLY = 01,
|
||||
PAL_ACCESS_RDWR = 02,
|
||||
PAL_ACCESS_APPEND = 04,
|
||||
PAL_ACCESS_MASK = 07,
|
||||
PAL_ACCESS_RDONLY = 0,
|
||||
PAL_ACCESS_WRONLY = 1,
|
||||
PAL_ACCESS_RDWR = 2,
|
||||
PAL_ACCESS_APPEND = 4,
|
||||
PAL_ACCESS_MASK = 7,
|
||||
};
|
||||
|
||||
/*! Stream Sharing Flags */
|
||||
// FIXME: These flags currently must correspond 1-1 to Linux flags, which is totally unportable.
|
||||
// They should be redesigned when we'll be rewriting the filesystem layer.
|
||||
enum PAL_SHARE {
|
||||
PAL_SHARE_GLOBAL_X = 01,
|
||||
PAL_SHARE_GLOBAL_W = 02,
|
||||
PAL_SHARE_GLOBAL_R = 04,
|
||||
PAL_SHARE_GROUP_X = 010,
|
||||
PAL_SHARE_GROUP_W = 020,
|
||||
PAL_SHARE_GROUP_R = 040,
|
||||
PAL_SHARE_OWNER_X = 0100,
|
||||
PAL_SHARE_OWNER_W = 0200,
|
||||
PAL_SHARE_OWNER_R = 0400,
|
||||
PAL_SHARE_MASK = 0777,
|
||||
PAL_SHARE_GLOBAL_X = 01,
|
||||
PAL_SHARE_GLOBAL_W = 02,
|
||||
PAL_SHARE_GLOBAL_R = 04,
|
||||
PAL_SHARE_GROUP_X = 010,
|
||||
PAL_SHARE_GROUP_W = 020,
|
||||
PAL_SHARE_GROUP_R = 040,
|
||||
PAL_SHARE_OWNER_X = 0100,
|
||||
PAL_SHARE_OWNER_W = 0200,
|
||||
PAL_SHARE_OWNER_R = 0400,
|
||||
PAL_SHARE_STICKY = 01000,
|
||||
PAL_SHARE_SET_GID = 02000,
|
||||
PAL_SHARE_SET_UID = 04000,
|
||||
|
||||
PAL_SHARE_MASK = 07777,
|
||||
};
|
||||
|
||||
/*! Stream Create Flags */
|
||||
enum PAL_CREATE {
|
||||
PAL_CREATE_TRY = 0100, /*!< Create file if file not exist (O_CREAT) */
|
||||
PAL_CREATE_ALWAYS = 0200, /*!< Create file and fail if file already exist
|
||||
(O_CREAT|O_EXCL) */
|
||||
PAL_CREATE_DUALSTACK = 0400, /*!< Create dual-stack socket (opposite of IPV6_V6ONLY) */
|
||||
PAL_CREATE_TRY = 1, /*!< Create file if file does not exist */
|
||||
PAL_CREATE_ALWAYS = 2, /*!< Create file and fail if file already exists */
|
||||
PAL_CREATE_DUALSTACK = 4, /*!< Create dual-stack socket (opposite of IPV6_V6ONLY) */
|
||||
|
||||
PAL_CREATE_MASK = 0700,
|
||||
PAL_CREATE_MASK = 7,
|
||||
};
|
||||
|
||||
/*! Stream Option Flags */
|
||||
enum PAL_OPTION {
|
||||
PAL_OPTION_CLOEXEC = 01000,
|
||||
PAL_OPTION_EFD_SEMAPHORE = 02000, /*!< specific to `eventfd` syscall */
|
||||
PAL_OPTION_NONBLOCK = 04000,
|
||||
PAL_OPTION_CLOEXEC = 1,
|
||||
PAL_OPTION_EFD_SEMAPHORE = 2, /*!< specific to `eventfd` syscall */
|
||||
PAL_OPTION_NONBLOCK = 4,
|
||||
|
||||
PAL_OPTION_MASK = 07000,
|
||||
PAL_OPTION_MASK = 7,
|
||||
};
|
||||
|
||||
|
||||
@@ -551,8 +558,8 @@ PAL_NUM
|
||||
DkStreamWrite(PAL_HANDLE handle, PAL_NUM offset, PAL_NUM count, PAL_PTR buffer, PAL_STR dest);
|
||||
|
||||
enum PAL_DELETE {
|
||||
PAL_DELETE_RD = 01, /*!< shut down the read side only */
|
||||
PAL_DELETE_WR = 02, /*!< shut down the write side only */
|
||||
PAL_DELETE_RD = 1, /*!< shut down the read side only */
|
||||
PAL_DELETE_WR = 2, /*!< shut down the write side only */
|
||||
};
|
||||
|
||||
/*!
|
||||
@@ -560,8 +567,7 @@ enum PAL_DELETE {
|
||||
*
|
||||
* \param access which side to shut down (#PAL_DELETE), or both if 0 is given.
|
||||
*/
|
||||
void
|
||||
DkStreamDelete(PAL_HANDLE handle, PAL_FLG access);
|
||||
void DkStreamDelete(PAL_HANDLE handle, PAL_FLG access);
|
||||
|
||||
/*!
|
||||
* \brief Map a file to a virtual memory address in the current process.
|
||||
|
||||
@@ -103,13 +103,13 @@ int main(int argc, char** argv, char** envp) {
|
||||
|
||||
PAL_HANDLE file4 =
|
||||
DkStreamOpen("file:file_nonexist.tmp", PAL_ACCESS_RDWR,
|
||||
PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W, PAL_CREATE_TRY | PAL_CREATE_ALWAYS, 0);
|
||||
PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W, PAL_CREATE_ALWAYS, 0);
|
||||
if (file4)
|
||||
pal_printf("File Creation Test 1 OK\n");
|
||||
|
||||
PAL_HANDLE file5 =
|
||||
DkStreamOpen("file:file_nonexist.tmp", PAL_ACCESS_RDWR,
|
||||
PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W, PAL_CREATE_TRY | PAL_CREATE_ALWAYS, 0);
|
||||
PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W, PAL_CREATE_ALWAYS, 0);
|
||||
if (file5) {
|
||||
DkObjectClose(file5);
|
||||
} else {
|
||||
@@ -125,7 +125,7 @@ int main(int argc, char** argv, char** envp) {
|
||||
|
||||
file6 =
|
||||
DkStreamOpen("file:file_nonexist_disallowed.tmp", PAL_ACCESS_RDWR,
|
||||
PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W, PAL_CREATE_TRY | PAL_CREATE_ALWAYS, 0);
|
||||
PAL_SHARE_OWNER_R | PAL_SHARE_OWNER_W, PAL_CREATE_ALWAYS, 0);
|
||||
if (!file6) {
|
||||
pal_printf("File Creation Test 4 OK\n");
|
||||
} else {
|
||||
|
||||
+1
-2
@@ -27,8 +27,7 @@
|
||||
#include "pal_error.h"
|
||||
#include "pal_internal.h"
|
||||
|
||||
PAL_PTR
|
||||
DkVirtualMemoryAlloc(PAL_PTR addr, PAL_NUM size, PAL_FLG alloc_type, PAL_FLG prot) {
|
||||
PAL_PTR DkVirtualMemoryAlloc(PAL_PTR addr, PAL_NUM size, PAL_FLG alloc_type, PAL_FLG prot) {
|
||||
ENTER_PAL_CALL(DkVirtualMemoryAlloc);
|
||||
void* map_addr = (void*)addr;
|
||||
|
||||
|
||||
+22
-14
@@ -157,6 +157,11 @@ int _DkStreamOpen(PAL_HANDLE* handle, const char* uri, int access, int share, in
|
||||
struct handle_ops* ops = NULL;
|
||||
char* type = NULL;
|
||||
|
||||
assert(WITHIN_MASK(access, PAL_ACCESS_MASK));
|
||||
assert(WITHIN_MASK(share, PAL_SHARE_MASK));
|
||||
assert(WITHIN_MASK(create, PAL_CREATE_MASK));
|
||||
assert(WITHIN_MASK(options, PAL_OPTION_MASK));
|
||||
|
||||
int ret = parse_stream_uri(&uri, &type, &ops);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@@ -169,13 +174,17 @@ int _DkStreamOpen(PAL_HANDLE* handle, const char* uri, int access, int share, in
|
||||
|
||||
/* PAL call DkStreamOpen: Open stream based on uri, as given access/share/
|
||||
create/options flags. DkStreamOpen return a PAL_HANDLE to access the
|
||||
stream, or return NULL. Error code is notified. */
|
||||
PAL_HANDLE
|
||||
DkStreamOpen(PAL_STR uri, PAL_FLG access, PAL_FLG share, PAL_FLG create, PAL_FLG options) {
|
||||
stream, or return NULL. Error code is notified.
|
||||
|
||||
FIXME: Currently `share` must match 1-1 to Linux open() `mode` argument. This isn't really
|
||||
portable and will cause problems when implementing other PALs.
|
||||
*/
|
||||
PAL_HANDLE DkStreamOpen(PAL_STR uri, PAL_FLG access, PAL_FLG share, PAL_FLG create,
|
||||
PAL_FLG options) {
|
||||
ENTER_PAL_CALL(DkStreamOpen);
|
||||
|
||||
PAL_HANDLE handle = NULL;
|
||||
int ret = _DkStreamOpen(&handle, uri, access, share, create, options);
|
||||
int ret = _DkStreamOpen(&handle, uri, access, share, create, options);
|
||||
|
||||
if (ret < 0) {
|
||||
_DkRaiseFailure(-ret);
|
||||
@@ -221,6 +230,8 @@ DkStreamWaitForClient(PAL_HANDLE handle) {
|
||||
the stream. For example, file will be deleted, socket witll be
|
||||
disconnected, etc */
|
||||
int _DkStreamDelete(PAL_HANDLE handle, int access) {
|
||||
assert(access == 0 || access == PAL_DELETE_RD || access == PAL_DELETE_WR);
|
||||
|
||||
const struct handle_ops* ops = HANDLE_OPS(handle);
|
||||
|
||||
if (!ops)
|
||||
@@ -371,8 +382,7 @@ int _DkStreamAttributesQuery(const char* uri, PAL_STREAM_ATTR* attr) {
|
||||
/* PAL call DkStreamAttributeQuery: query attribute of a stream by its
|
||||
URI, attr is memory given by user space. Return the pointer of attr
|
||||
if succeeded, or NULL if failed. Error code is notified */
|
||||
PAL_BOL
|
||||
DkStreamAttributesQuery(PAL_STR uri, PAL_STREAM_ATTR* attr) {
|
||||
PAL_BOL DkStreamAttributesQuery(PAL_STR uri, PAL_STREAM_ATTR* attr) {
|
||||
ENTER_PAL_CALL(DkStreamAttributesQuery);
|
||||
|
||||
if (!uri || !attr) {
|
||||
@@ -410,8 +420,7 @@ int _DkStreamAttributesQueryByHandle(PAL_HANDLE hdl, PAL_STREAM_ATTR* attr) {
|
||||
/* PAL call DkStreamAttributesQueryByHandle: Query attribute of a stream by
|
||||
its handle, attr is memory given by user space. Return the pointer of attr
|
||||
if succeeded, or NULL if failed. Error code is notified */
|
||||
PAL_BOL
|
||||
DkStreamAttributesQueryByHandle(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) {
|
||||
PAL_BOL DkStreamAttributesQueryByHandle(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) {
|
||||
ENTER_PAL_CALL(DkStreamAttributesQueryByHandle);
|
||||
|
||||
if (!handle || !attr) {
|
||||
@@ -432,8 +441,7 @@ DkStreamAttributesQueryByHandle(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) {
|
||||
/* PAL call DkStreamAttributesSetByHandle: Set attribute of a stream by
|
||||
its handle, attr is memory given by user space. Return the pointer of attr
|
||||
if succeeded, or NULL if failed. Error code is notified */
|
||||
PAL_BOL
|
||||
DkStreamAttributesSetByHandle(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) {
|
||||
PAL_BOL DkStreamAttributesSetByHandle(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) {
|
||||
ENTER_PAL_CALL(DkStreamAttributesSetByHandle);
|
||||
|
||||
if (!handle || !attr) {
|
||||
@@ -507,6 +515,8 @@ int _DkStreamMap(PAL_HANDLE handle, void** paddr, int prot, uint64_t offset, uin
|
||||
void* addr = *paddr;
|
||||
int ret;
|
||||
|
||||
assert(WITHIN_MASK(prot, PAL_PROT_MASK));
|
||||
|
||||
const struct handle_ops* ops = HANDLE_OPS(handle);
|
||||
|
||||
if (!ops)
|
||||
@@ -526,8 +536,7 @@ int _DkStreamMap(PAL_HANDLE handle, void** paddr, int prot, uint64_t offset, uin
|
||||
space. prot/offset/size are the protection, offset and size of the memory
|
||||
mapping. Return the address if succeeded or NULL if failed. Error code
|
||||
is notified. */
|
||||
PAL_PTR
|
||||
DkStreamMap(PAL_HANDLE handle, PAL_PTR addr, PAL_FLG prot, PAL_NUM offset, PAL_NUM size) {
|
||||
PAL_PTR DkStreamMap(PAL_HANDLE handle, PAL_PTR addr, PAL_FLG prot, PAL_NUM offset, PAL_NUM size) {
|
||||
ENTER_PAL_CALL(DkStreamMap);
|
||||
void* map_addr = (void*)addr;
|
||||
|
||||
@@ -598,8 +607,7 @@ int64_t _DkStreamSetLength(PAL_HANDLE handle, uint64_t length) {
|
||||
|
||||
/* PAL call DkStreamSetLength: Truncate the stream at certain length.
|
||||
Return the length if succeeded or 0 if failed. Error code is notified. */
|
||||
PAL_NUM
|
||||
DkStreamSetLength(PAL_HANDLE handle, PAL_NUM length) {
|
||||
PAL_NUM DkStreamSetLength(PAL_HANDLE handle, PAL_NUM length) {
|
||||
PAL_NUM rv = 0;
|
||||
ENTER_PAL_CALL(DkStreamSetLength);
|
||||
|
||||
|
||||
@@ -115,11 +115,16 @@ static int open_standard_term(PAL_HANDLE* handle, const char* param, int access)
|
||||
/* 'open' operation for terminal stream */
|
||||
static int term_open(PAL_HANDLE* handle, const char* type, const char* uri, int access, int share,
|
||||
int create, int options) {
|
||||
if (strcmp_static(type, "tty"))
|
||||
return -PAL_ERROR_INVAL;
|
||||
__UNUSED(share);
|
||||
__UNUSED(create);
|
||||
__UNUSED(options);
|
||||
|
||||
if (!WITHIN_MASK(share, PAL_SHARE_MASK) || !WITHIN_MASK(create, PAL_CREATE_MASK) ||
|
||||
!WITHIN_MASK(options, PAL_OPTION_MASK))
|
||||
assert(WITHIN_MASK(access, PAL_ACCESS_MASK));
|
||||
assert(WITHIN_MASK(share, PAL_SHARE_MASK));
|
||||
assert(WITHIN_MASK(create, PAL_CREATE_MASK));
|
||||
assert(WITHIN_MASK(options, PAL_OPTION_MASK));
|
||||
|
||||
if (strcmp_static(type, "tty"))
|
||||
return -PAL_ERROR_INVAL;
|
||||
|
||||
const char* term = NULL;
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "pal_debug.h"
|
||||
#include "pal_defs.h"
|
||||
#include "pal_error.h"
|
||||
#include "pal_flags_conv.h"
|
||||
#include "pal_internal.h"
|
||||
#include "pal_linux.h"
|
||||
#include "pal_linux_defs.h"
|
||||
@@ -48,7 +49,10 @@ static int file_open(PAL_HANDLE* handle, const char* type, const char* uri, int
|
||||
if (strcmp_static(type, URI_TYPE_FILE))
|
||||
return -PAL_ERROR_INVAL;
|
||||
/* try to do the real open */
|
||||
int fd = ocall_open(uri, access | create | options, share);
|
||||
int fd = ocall_open(uri, PAL_ACCESS_TO_LINUX_OPEN(access) |
|
||||
PAL_CREATE_TO_LINUX_OPEN(create) |
|
||||
PAL_OPTION_TO_LINUX_OPEN(options),
|
||||
share);
|
||||
|
||||
if (IS_ERR(fd))
|
||||
return unix_to_pal_error(ERRNO(fd));
|
||||
@@ -184,7 +188,7 @@ static int file_map(PAL_HANDLE handle, void** addr, int prot, uint64_t offset, u
|
||||
* does not request a specific address.
|
||||
*/
|
||||
if (!mem && !stubs && !(prot & PAL_PROT_WRITECOPY)) {
|
||||
ret = ocall_mmap_untrusted(handle->file.fd, offset, size, HOST_PROT(prot), &mem);
|
||||
ret = ocall_mmap_untrusted(handle->file.fd, offset, size, PAL_PROT_TO_LINUX(prot), &mem);
|
||||
if (!IS_ERR(ret))
|
||||
*addr = mem;
|
||||
return IS_ERR(ret) ? unix_to_pal_error(ERRNO(ret)) : ret;
|
||||
@@ -394,13 +398,19 @@ static int dir_open(PAL_HANDLE* handle, const char* type, const char* uri, int a
|
||||
|
||||
int ret;
|
||||
|
||||
if (create & PAL_CREATE_TRY) {
|
||||
if (create & PAL_CREATE_TRY || create & PAL_CREATE_ALWAYS) {
|
||||
ret = ocall_mkdir(uri, share);
|
||||
if (IS_ERR(ret) && ERRNO(ret) == EEXIST && create & PAL_CREATE_ALWAYS)
|
||||
return -PAL_ERROR_STREAMEXIST;
|
||||
|
||||
if (IS_ERR(ret)) {
|
||||
if (ERRNO(ret) == EEXIST && create & PAL_CREATE_ALWAYS)
|
||||
return -PAL_ERROR_STREAMEXIST;
|
||||
if (ERRNO(ret) != EEXIST)
|
||||
return unix_to_pal_error(ERRNO(ret));
|
||||
assert(ERRNO(ret) == EEXIST && create & PAL_CREATE_TRY);
|
||||
}
|
||||
}
|
||||
|
||||
ret = ocall_open(uri, O_DIRECTORY | options, 0);
|
||||
ret = ocall_open(uri, O_DIRECTORY | PAL_OPTION_TO_LINUX_OPEN(options), 0);
|
||||
if (IS_ERR(ret))
|
||||
return unix_to_pal_error(ERRNO(ret));
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "pal_debug.h"
|
||||
#include "pal_defs.h"
|
||||
#include "pal_error.h"
|
||||
#include "pal_flags_conv.h"
|
||||
#include "pal_internal.h"
|
||||
#include "pal_linux.h"
|
||||
#include "pal_linux_defs.h"
|
||||
@@ -47,7 +48,12 @@ bool _DkCheckMemoryMappable(const void* addr, size_t size) {
|
||||
}
|
||||
|
||||
int _DkVirtualMemoryAlloc(void** paddr, uint64_t size, int alloc_type, int prot) {
|
||||
if (!size || !WITHIN_MASK(prot, PAL_PROT_MASK))
|
||||
__UNUSED(prot);
|
||||
|
||||
assert(WITHIN_MASK(alloc_type, PAL_ALLOC_MASK));
|
||||
assert(WITHIN_MASK(prot, PAL_PROT_MASK));
|
||||
|
||||
if (!size)
|
||||
return -PAL_ERROR_INVAL;
|
||||
|
||||
void* addr = *paddr;
|
||||
@@ -85,6 +91,8 @@ int _DkVirtualMemoryProtect(void* addr, uint64_t size, int prot) {
|
||||
__UNUSED(size);
|
||||
__UNUSED(prot);
|
||||
|
||||
assert(WITHIN_MASK(prot, PAL_PROT_MASK));
|
||||
|
||||
static struct atomic_int at_cnt = {.counter = 0};
|
||||
if (atomic_cmpxchg(&at_cnt, 0, 1) == 0)
|
||||
SGX_DBG(DBG_M, "[Warning] DkVirtualMemoryProtect is unimplemented in Linux-SGX PAL");
|
||||
|
||||
@@ -436,9 +436,13 @@ static int tcp_connect(PAL_HANDLE* handle, char* uri, int options) {
|
||||
/* 'open' operation of tcp stream */
|
||||
static int tcp_open(PAL_HANDLE* handle, const char* type, const char* uri, int access, int share,
|
||||
int create, int options) {
|
||||
if (!WITHIN_MASK(access, PAL_ACCESS_MASK) || !WITHIN_MASK(share, PAL_SHARE_MASK) ||
|
||||
!WITHIN_MASK(create, PAL_CREATE_MASK) || !WITHIN_MASK(options, PAL_OPTION_MASK))
|
||||
return -PAL_ERROR_INVAL;
|
||||
__UNUSED(access);
|
||||
__UNUSED(share);
|
||||
|
||||
assert(WITHIN_MASK(access, PAL_ACCESS_MASK));
|
||||
assert(WITHIN_MASK(share, PAL_SHARE_MASK));
|
||||
assert(WITHIN_MASK(create, PAL_CREATE_MASK));
|
||||
assert(WITHIN_MASK(options, PAL_OPTION_MASK));
|
||||
|
||||
int uri_len = strlen(uri) + 1;
|
||||
|
||||
@@ -589,9 +593,13 @@ static int udp_connect(PAL_HANDLE* handle, char* uri, int create, int options) {
|
||||
|
||||
static int udp_open(PAL_HANDLE* hdl, const char* type, const char* uri, int access, int share,
|
||||
int create, int options) {
|
||||
if (!WITHIN_MASK(access, PAL_ACCESS_MASK) || !WITHIN_MASK(share, PAL_SHARE_MASK) ||
|
||||
!WITHIN_MASK(create, PAL_CREATE_MASK) || !WITHIN_MASK(options, PAL_OPTION_MASK))
|
||||
return -PAL_ERROR_INVAL;
|
||||
__UNUSED(access);
|
||||
__UNUSED(share);
|
||||
|
||||
assert(WITHIN_MASK(access, PAL_ACCESS_MASK));
|
||||
assert(WITHIN_MASK(share, PAL_SHARE_MASK));
|
||||
assert(WITHIN_MASK(create, PAL_CREATE_MASK));
|
||||
assert(WITHIN_MASK(options, PAL_OPTION_MASK));
|
||||
|
||||
char buf[PAL_SOCKADDR_SIZE];
|
||||
int len = strlen(uri);
|
||||
|
||||
@@ -66,18 +66,7 @@ extern struct pal_linux_state {
|
||||
|
||||
#define PRESET_PAGESIZE (1 << 12)
|
||||
|
||||
#define DEFAULT_BACKLOG 2048
|
||||
|
||||
static inline int HOST_FLAGS (int alloc_type, int prot)
|
||||
{
|
||||
return ((alloc_type & PAL_ALLOC_RESERVE) ? MAP_NORESERVE|MAP_UNINITIALIZED : 0) |
|
||||
((prot & PAL_PROT_WRITECOPY) ? MAP_PRIVATE : MAP_SHARED);
|
||||
}
|
||||
|
||||
static inline int HOST_PROT (int prot)
|
||||
{
|
||||
return prot & (PAL_PROT_READ|PAL_PROT_WRITE|PAL_PROT_EXEC);
|
||||
}
|
||||
#define DEFAULT_BACKLOG 2048
|
||||
|
||||
#define ACCESS_R 4
|
||||
#define ACCESS_W 2
|
||||
|
||||
@@ -114,13 +114,13 @@ static long sgx_ocall_cpuid(void * pms)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long sgx_ocall_open(void * pms)
|
||||
{
|
||||
ms_ocall_open_t * ms = (ms_ocall_open_t *) pms;
|
||||
static long sgx_ocall_open(void* pms) {
|
||||
ms_ocall_open_t* ms = (ms_ocall_open_t*)pms;
|
||||
long ret;
|
||||
ODEBUG(OCALL_OPEN, ms);
|
||||
ret = INLINE_SYSCALL(open, 3, ms->ms_pathname, ms->ms_flags|O_CLOEXEC,
|
||||
ms->ms_mode);
|
||||
// FIXME: No idea why someone hardcoded O_CLOEXEC here. We should drop it and carefully
|
||||
// investigate if this cause any descriptor leaks.
|
||||
ret = INLINE_SYSCALL(open, 3, ms->ms_pathname, ms->ms_flags | O_CLOEXEC, ms->ms_mode);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -113,12 +113,17 @@ static int open_standard_term(PAL_HANDLE* handle, const char* param, int access)
|
||||
/* 'open' operation for terminal stream */
|
||||
static int term_open(PAL_HANDLE* handle, const char* type, const char* uri, int access, int share,
|
||||
int create, int options) {
|
||||
__UNUSED(share);
|
||||
__UNUSED(create);
|
||||
__UNUSED(options);
|
||||
|
||||
if (strcmp_static(type, "tty"))
|
||||
return -PAL_ERROR_INVAL;
|
||||
|
||||
if (!WITHIN_MASK(share, PAL_SHARE_MASK) || !WITHIN_MASK(create, PAL_CREATE_MASK) ||
|
||||
!WITHIN_MASK(options, PAL_OPTION_MASK))
|
||||
return -PAL_ERROR_INVAL;
|
||||
assert(WITHIN_MASK(access, PAL_ACCESS_MASK));
|
||||
assert(WITHIN_MASK(share, PAL_SHARE_MASK));
|
||||
assert(WITHIN_MASK(create, PAL_CREATE_MASK));
|
||||
assert(WITHIN_MASK(options, PAL_OPTION_MASK));
|
||||
|
||||
const char* term = NULL;
|
||||
const char* param = NULL;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "pal_defs.h"
|
||||
#include "pal_linux_defs.h"
|
||||
#include "pal.h"
|
||||
#include "pal_flags_conv.h"
|
||||
#include "pal_internal.h"
|
||||
#include "pal_linux.h"
|
||||
#include "pal_linux_error.h"
|
||||
@@ -43,8 +44,19 @@ static int file_open(PAL_HANDLE* handle, const char* type, const char* uri, int
|
||||
if (strcmp_static(type, URI_TYPE_FILE))
|
||||
return -PAL_ERROR_INVAL;
|
||||
|
||||
assert(WITHIN_MASK(access, PAL_ACCESS_MASK));
|
||||
assert(WITHIN_MASK(share, PAL_SHARE_MASK));
|
||||
assert(WITHIN_MASK(create, PAL_CREATE_MASK));
|
||||
assert(WITHIN_MASK(options, PAL_OPTION_MASK));
|
||||
|
||||
/* try to do the real open */
|
||||
int ret = INLINE_SYSCALL(open, 3, uri, HOST_ACCESS(access)|create|options|O_CLOEXEC, share);
|
||||
// FIXME: No idea why someone hardcoded O_CLOEXEC here. We should drop it and carefully
|
||||
// investigate if this causes any descriptor leaks.
|
||||
int ret = INLINE_SYSCALL(open, 3, uri, PAL_ACCESS_TO_LINUX_OPEN(access) |
|
||||
PAL_CREATE_TO_LINUX_OPEN(create) |
|
||||
PAL_OPTION_TO_LINUX_OPEN(options) |
|
||||
O_CLOEXEC,
|
||||
share);
|
||||
|
||||
if (IS_ERR(ret))
|
||||
return unix_to_pal_error(ERRNO(ret));
|
||||
@@ -124,11 +136,9 @@ static int file_delete (PAL_HANDLE handle, int access)
|
||||
}
|
||||
|
||||
/* 'map' operation for file stream. */
|
||||
static int file_map (PAL_HANDLE handle, void ** addr, int prot,
|
||||
uint64_t offset, uint64_t size)
|
||||
{
|
||||
static int file_map(PAL_HANDLE handle, void** addr, int prot, uint64_t offset, uint64_t size) {
|
||||
int fd = handle->file.fd;
|
||||
void * mem = *addr;
|
||||
void* mem = *addr;
|
||||
/*
|
||||
* work around for fork emulation
|
||||
* the first exec image to be loaded has to be at same address
|
||||
@@ -139,12 +149,11 @@ static int file_map (PAL_HANDLE handle, void ** addr, int prot,
|
||||
/* this address is used. don't over-map it later */
|
||||
handle->file.map_start = NULL;
|
||||
}
|
||||
int flags = MAP_FILE|HOST_FLAGS(0, prot)|(mem ? MAP_FIXED : 0);
|
||||
prot = HOST_PROT(prot);
|
||||
int flags = MAP_FILE | PAL_MEM_FLAGS_TO_LINUX(0, prot) | (mem ? MAP_FIXED : 0);
|
||||
prot = PAL_PROT_TO_LINUX(prot);
|
||||
|
||||
/* The memory will always allocated with flag MAP_PRIVATE
|
||||
and MAP_FILE */
|
||||
mem = (void *) ARCH_MMAP(mem, size, prot, flags, fd, offset);
|
||||
/* The memory will always be allocated with flag MAP_PRIVATE and MAP_FILE */
|
||||
mem = (void*)ARCH_MMAP(mem, size, prot, flags, fd, offset);
|
||||
|
||||
if (IS_ERR_P(mem))
|
||||
return -PAL_ERROR_DENIED;
|
||||
@@ -320,9 +329,8 @@ struct handle_ops file_ops = {
|
||||
/* 'open' operation for directory stream. Directory stream does not have a
|
||||
specific type prefix, its URI looks the same file streams, plus it
|
||||
ended with slashes. dir_open will be called by file_open. */
|
||||
static int dir_open (PAL_HANDLE * handle, const char * type, const char * uri,
|
||||
int access, int share, int create, int options)
|
||||
{
|
||||
static int dir_open(PAL_HANDLE* handle, const char* type, const char* uri, int access, int share,
|
||||
int create, int options) {
|
||||
if (strcmp_static(type, URI_TYPE_DIR))
|
||||
return -PAL_ERROR_INVAL;
|
||||
if (!WITHIN_MASK(access, PAL_ACCESS_MASK))
|
||||
@@ -330,15 +338,20 @@ static int dir_open (PAL_HANDLE * handle, const char * type, const char * uri,
|
||||
|
||||
int ret = 0;
|
||||
|
||||
if (create & PAL_CREATE_TRY) {
|
||||
if (create & PAL_CREATE_TRY || create & PAL_CREATE_ALWAYS) {
|
||||
ret = INLINE_SYSCALL(mkdir, 2, uri, share);
|
||||
|
||||
if (IS_ERR(ret) && ERRNO(ret) == EEXIST &&
|
||||
create & PAL_CREATE_ALWAYS)
|
||||
return -PAL_ERROR_STREAMEXIST;
|
||||
if (IS_ERR(ret)) {
|
||||
if (ERRNO(ret) == EEXIST && create & PAL_CREATE_ALWAYS)
|
||||
return -PAL_ERROR_STREAMEXIST;
|
||||
if (ERRNO(ret) != EEXIST)
|
||||
return unix_to_pal_error(ERRNO(ret));
|
||||
assert(ERRNO(ret) == EEXIST && create & PAL_CREATE_TRY);
|
||||
}
|
||||
}
|
||||
|
||||
ret = INLINE_SYSCALL(open, 3, uri, O_DIRECTORY|options|O_CLOEXEC, 0);
|
||||
ret = INLINE_SYSCALL(open, 3, uri, O_DIRECTORY | PAL_OPTION_TO_LINUX_OPEN(options) | O_CLOEXEC,
|
||||
0);
|
||||
|
||||
if (IS_ERR(ret))
|
||||
return unix_to_pal_error(ERRNO(ret));
|
||||
@@ -348,7 +361,7 @@ static int dir_open (PAL_HANDLE * handle, const char * type, const char * uri,
|
||||
SET_HANDLE_TYPE(hdl, dir);
|
||||
HANDLE_HDR(hdl)->flags |= RFD(0);
|
||||
hdl->dir.fd = ret;
|
||||
char * path = (void *) hdl + HANDLE_SIZE(dir);
|
||||
char* path = (void*)hdl + HANDLE_SIZE(dir);
|
||||
memcpy(path, uri, len + 1);
|
||||
hdl->dir.realpath = (PAL_STR) path;
|
||||
hdl->dir.buf = (PAL_PTR) NULL;
|
||||
|
||||
@@ -285,8 +285,7 @@ void pal_linux_main(void* initial_rsp, void* fini_callback) {
|
||||
INIT_FAIL(PAL_ERROR_NOMEM, "Out of memory");
|
||||
snprintf(uri, size, URI_PREFIX_FILE "%s", exec_target);
|
||||
PAL_HANDLE file;
|
||||
// FIXME: `options` should be `PAL_OPTION_CLOEXEC`, but _DkStreamOpen is totally broken.
|
||||
int ret = _DkStreamOpen(&file, uri, PAL_ACCESS_RDONLY, 0, 0, 0);
|
||||
int ret = _DkStreamOpen(&file, uri, PAL_ACCESS_RDONLY, 0, 0, PAL_OPTION_CLOEXEC);
|
||||
free(uri);
|
||||
if (ret < 0)
|
||||
INIT_FAIL(-ret, "Failed to open file to execute");
|
||||
|
||||
@@ -20,33 +20,35 @@
|
||||
* This files contains APIs that allocate, free or protect virtual memory.
|
||||
*/
|
||||
|
||||
#include "pal_defs.h"
|
||||
#include "pal_linux_defs.h"
|
||||
#include "api.h"
|
||||
#include "pal.h"
|
||||
#include "pal_debug.h"
|
||||
#include "pal_defs.h"
|
||||
#include "pal_error.h"
|
||||
#include "pal_flags_conv.h"
|
||||
#include "pal_internal.h"
|
||||
#include "pal_linux.h"
|
||||
#include "pal_error.h"
|
||||
#include "pal_debug.h"
|
||||
#include "api.h"
|
||||
#include "pal_linux_defs.h"
|
||||
|
||||
#include <asm/mman.h>
|
||||
#include <asm/fcntl.h>
|
||||
#include <asm/mman.h>
|
||||
|
||||
bool _DkCheckMemoryMappable (const void * addr, size_t size)
|
||||
{
|
||||
bool _DkCheckMemoryMappable(const void* addr, size_t size) {
|
||||
return (addr < DATA_END && addr + size > TEXT_START);
|
||||
}
|
||||
|
||||
int _DkVirtualMemoryAlloc (void ** paddr, size_t size, int alloc_type,
|
||||
int prot)
|
||||
{
|
||||
void * addr = *paddr, * mem = addr;
|
||||
int _DkVirtualMemoryAlloc(void** paddr, size_t size, int alloc_type, int prot) {
|
||||
assert(WITHIN_MASK(alloc_type, PAL_ALLOC_MASK));
|
||||
assert(WITHIN_MASK(prot, PAL_PROT_MASK));
|
||||
|
||||
int flags = HOST_FLAGS(alloc_type, prot|PAL_PROT_WRITECOPY);
|
||||
prot = HOST_PROT(prot);
|
||||
void* addr = *paddr;
|
||||
void* mem = addr;
|
||||
|
||||
flags |= MAP_ANONYMOUS|(addr ? MAP_FIXED : 0);
|
||||
mem = (void *) ARCH_MMAP(addr, size, prot, flags, -1, 0);
|
||||
int flags = PAL_MEM_FLAGS_TO_LINUX(alloc_type, prot | PAL_PROT_WRITECOPY);
|
||||
prot = PAL_PROT_TO_LINUX(prot);
|
||||
|
||||
flags |= MAP_ANONYMOUS | (addr ? MAP_FIXED : 0);
|
||||
mem = (void*)ARCH_MMAP(addr, size, prot, flags, -1, 0);
|
||||
|
||||
if (IS_ERR_P(mem))
|
||||
return unix_to_pal_error(ERRNO_P(mem));
|
||||
@@ -62,10 +64,8 @@ int _DkVirtualMemoryFree (void * addr, size_t size)
|
||||
return IS_ERR(ret) ? unix_to_pal_error(ERRNO(ret)) : 0;
|
||||
}
|
||||
|
||||
int _DkVirtualMemoryProtect (void * addr, size_t size, int prot)
|
||||
{
|
||||
int ret = INLINE_SYSCALL(mprotect, 3, addr, size, HOST_PROT(prot));
|
||||
|
||||
int _DkVirtualMemoryProtect(void* addr, size_t size, int prot) {
|
||||
int ret = INLINE_SYSCALL(mprotect, 3, addr, size, PAL_PROT_TO_LINUX(prot));
|
||||
return IS_ERR(ret) ? unix_to_pal_error(ERRNO(ret)) : 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -339,7 +339,9 @@ static int tcp_listen(PAL_HANDLE* handle, char* uri, int create, int options) {
|
||||
return -PAL_ERROR_INVAL;
|
||||
#endif
|
||||
|
||||
fd = INLINE_SYSCALL(socket, 3, bind_addr->sa_family, SOCK_STREAM | SOCK_CLOEXEC | options, 0);
|
||||
int sock_options = options & PAL_OPTION_NONBLOCK ? SOCK_NONBLOCK : 0;
|
||||
fd = INLINE_SYSCALL(socket, 3, bind_addr->sa_family, SOCK_STREAM | SOCK_CLOEXEC | sock_options,
|
||||
0);
|
||||
|
||||
if (IS_ERR(fd))
|
||||
return -PAL_ERROR_DENIED;
|
||||
@@ -411,7 +413,7 @@ static int tcp_accept(PAL_HANDLE handle, PAL_HANDLE* client) {
|
||||
socklen_t addrlen = sizeof(struct sockaddr);
|
||||
int ret = 0;
|
||||
|
||||
int newfd = INLINE_SYSCALL(accept4, 4, handle->sock.fd, &buffer, &addrlen, O_CLOEXEC);
|
||||
int newfd = INLINE_SYSCALL(accept4, 4, handle->sock.fd, &buffer, &addrlen, SOCK_CLOEXEC);
|
||||
|
||||
if (IS_ERR(newfd))
|
||||
switch (ERRNO(newfd)) {
|
||||
@@ -460,7 +462,9 @@ static int tcp_connect(PAL_HANDLE* handle, char* uri, int options) {
|
||||
if (bind_addr && bind_addr->sa_family != dest_addr->sa_family)
|
||||
return -PAL_ERROR_INVAL;
|
||||
|
||||
fd = INLINE_SYSCALL(socket, 3, dest_addr->sa_family, SOCK_STREAM | SOCK_CLOEXEC | options, 0);
|
||||
int sock_options = options & PAL_OPTION_NONBLOCK ? SOCK_NONBLOCK : 0;
|
||||
fd = INLINE_SYSCALL(socket, 3, dest_addr->sa_family, SOCK_STREAM | SOCK_CLOEXEC | sock_options,
|
||||
0);
|
||||
if (IS_ERR(fd))
|
||||
return -PAL_ERROR_DENIED;
|
||||
|
||||
@@ -521,9 +525,13 @@ failed:
|
||||
/* 'open' operation of tcp stream */
|
||||
static int tcp_open(PAL_HANDLE* handle, const char* type, const char* uri, int access, int share,
|
||||
int create, int options) {
|
||||
if (!WITHIN_MASK(access, PAL_ACCESS_MASK) || !WITHIN_MASK(share, PAL_SHARE_MASK) ||
|
||||
!WITHIN_MASK(create, PAL_CREATE_MASK))
|
||||
return -PAL_ERROR_INVAL;
|
||||
__UNUSED(access);
|
||||
__UNUSED(share);
|
||||
|
||||
assert(WITHIN_MASK(access, PAL_ACCESS_MASK));
|
||||
assert(WITHIN_MASK(share, PAL_SHARE_MASK));
|
||||
assert(WITHIN_MASK(create, PAL_CREATE_MASK));
|
||||
assert(WITHIN_MASK(options, PAL_OPTION_MASK));
|
||||
|
||||
size_t uri_len = strlen(uri) + 1;
|
||||
|
||||
@@ -626,7 +634,9 @@ static int udp_bind(PAL_HANDLE* handle, char* uri, int create, int options) {
|
||||
return -PAL_ERROR_INVAL;
|
||||
#endif
|
||||
|
||||
fd = INLINE_SYSCALL(socket, 3, bind_addr->sa_family, SOCK_DGRAM | SOCK_CLOEXEC | options, 0);
|
||||
int sock_options = options & PAL_OPTION_NONBLOCK ? SOCK_NONBLOCK : 0;
|
||||
fd = INLINE_SYSCALL(socket, 3, bind_addr->sa_family, SOCK_DGRAM | SOCK_CLOEXEC | sock_options,
|
||||
0);
|
||||
|
||||
if (IS_ERR(fd))
|
||||
return -PAL_ERROR_DENIED;
|
||||
@@ -687,8 +697,9 @@ static int udp_connect(PAL_HANDLE* handle, char* uri, int create, int options) {
|
||||
return -PAL_ERROR_INVAL;
|
||||
#endif
|
||||
|
||||
int sock_options = options & PAL_OPTION_NONBLOCK ? SOCK_NONBLOCK : 0;
|
||||
fd = INLINE_SYSCALL(socket, 3, dest_addr ? dest_addr->sa_family : AF_INET,
|
||||
SOCK_DGRAM | SOCK_CLOEXEC | options, 0);
|
||||
SOCK_DGRAM | SOCK_CLOEXEC | sock_options, 0);
|
||||
|
||||
if (IS_ERR(fd))
|
||||
return -PAL_ERROR_DENIED;
|
||||
@@ -737,9 +748,13 @@ failed:
|
||||
|
||||
static int udp_open(PAL_HANDLE* hdl, const char* type, const char* uri, int access, int share,
|
||||
int create, int options) {
|
||||
if (!WITHIN_MASK(access, PAL_ACCESS_MASK) || !WITHIN_MASK(share, PAL_SHARE_MASK) ||
|
||||
!WITHIN_MASK(create, PAL_CREATE_MASK) || !WITHIN_MASK(options, PAL_OPTION_MASK))
|
||||
return -PAL_ERROR_INVAL;
|
||||
__UNUSED(access);
|
||||
__UNUSED(share);
|
||||
|
||||
assert(WITHIN_MASK(access, PAL_ACCESS_MASK));
|
||||
assert(WITHIN_MASK(share, PAL_SHARE_MASK));
|
||||
assert(WITHIN_MASK(create, PAL_CREATE_MASK));
|
||||
assert(WITHIN_MASK(options, PAL_OPTION_MASK));
|
||||
|
||||
char buf[PAL_SOCKADDR_SIZE];
|
||||
size_t len = strlen(uri);
|
||||
|
||||
@@ -122,24 +122,7 @@ extern struct pal_linux_state {
|
||||
|
||||
#define PRESET_PAGESIZE (1 << 12)
|
||||
|
||||
#define DEFAULT_BACKLOG 2048
|
||||
|
||||
static inline int HOST_FLAGS (int alloc_type, int prot)
|
||||
{
|
||||
return ((alloc_type & PAL_ALLOC_RESERVE) ? MAP_NORESERVE|MAP_UNINITIALIZED : 0) |
|
||||
((prot & PAL_PROT_WRITECOPY) ? MAP_PRIVATE : MAP_SHARED);
|
||||
}
|
||||
|
||||
static inline int HOST_PROT (int prot)
|
||||
{
|
||||
return prot & (PAL_PROT_READ|PAL_PROT_WRITE|PAL_PROT_EXEC);
|
||||
}
|
||||
|
||||
static inline int HOST_ACCESS (int access)
|
||||
{
|
||||
return (access & (PAL_ACCESS_RDONLY|PAL_ACCESS_WRONLY|PAL_ACCESS_RDWR)) |
|
||||
((access & PAL_ACCESS_APPEND) ? O_APPEND|O_WRONLY : 0);
|
||||
}
|
||||
#define DEFAULT_BACKLOG 2048
|
||||
|
||||
int clone (int (*__fn) (void * __arg), void * __child_stack,
|
||||
int __flags, const void * __arg, ...);
|
||||
|
||||
@@ -226,8 +226,8 @@ int _DkGetCPUInfo (PAL_CPU_INFO * info);
|
||||
|
||||
/* Internal DK calls, in case any of the internal routines needs to use them */
|
||||
/* DkStream calls */
|
||||
int _DkStreamOpen (PAL_HANDLE * handle, const char * uri,
|
||||
int access, int share, int create, int options);
|
||||
int _DkStreamOpen(PAL_HANDLE* handle, const char* uri, int access, int share, int create,
|
||||
int options);
|
||||
int _DkStreamDelete (PAL_HANDLE handle, int access);
|
||||
int64_t _DkStreamRead (PAL_HANDLE handle, uint64_t offset, uint64_t count,
|
||||
void * buf, char * addr, int addrlen);
|
||||
|
||||
Reference in New Issue
Block a user