mirror of
https://github.com/clearlinux/graphene.git
synced 2026-10-03 23:48:19 +00:00
[LibOS,Pal] Replace 32-bit pipeid with 256-bit pipe name
Previously, Graphene used the notation "pipe:<uint32_t>" to emulate pipes, socketpairs, and UNIX domain sockets. In particular, pipes and socketpairs received random integer IDs, and sockets received deterministic integer IDs. However, 32-bit randomly generated IDs may collide quite often. Since pipe IDs/names should *not* repeat (otherwise e.g. derived crypto keys will be reused), this commit changes pipe IDs (pipeid) from uint32_t to char[96], and pipe IDs (names) become 256-bit random sequences.
This commit is contained in:
@@ -127,11 +127,7 @@ struct shim_dev_handle {
|
||||
};
|
||||
|
||||
struct shim_pipe_handle {
|
||||
#if USE_SIMPLE_PIPE == 1
|
||||
struct shim_handle* pair;
|
||||
#else
|
||||
IDTYPE pipeid;
|
||||
#endif
|
||||
char name[PIPE_URI_SIZE];
|
||||
};
|
||||
|
||||
#define SOCK_STREAM 1
|
||||
@@ -163,10 +159,6 @@ enum shim_sock_state {
|
||||
SOCK_SHUTDOWN,
|
||||
};
|
||||
|
||||
struct shim_unix_data {
|
||||
unsigned int pipeid;
|
||||
};
|
||||
|
||||
struct shim_sock_handle {
|
||||
int domain;
|
||||
int sock_type;
|
||||
@@ -190,8 +182,7 @@ struct shim_sock_handle {
|
||||
// UNIX addr
|
||||
struct addr_unix {
|
||||
struct shim_dentry* dentry;
|
||||
unsigned int pipeid;
|
||||
struct shim_unix_data* data;
|
||||
char name[PIPE_URI_SIZE];
|
||||
} un;
|
||||
} addr;
|
||||
|
||||
|
||||
@@ -827,10 +827,4 @@ static_always_inline void * current_stack(void)
|
||||
# error "Unsupported architecture"
|
||||
#endif /* __x86_64__ */
|
||||
|
||||
static inline IDTYPE hashtype_to_idtype(HASHTYPE hash) {
|
||||
static_assert(sizeof(HASHTYPE) == 8, "Unsupported HASHTYPE size");
|
||||
static_assert(sizeof(IDTYPE) == 4, "Unsupported IDTYPE size");
|
||||
return ((IDTYPE)hash) ^ ((IDTYPE)(hash >> 32));
|
||||
}
|
||||
|
||||
#endif /* _PAL_INTERNAL_H_ */
|
||||
|
||||
@@ -515,4 +515,7 @@ struct shim_qstr {
|
||||
struct shim_str * oflow;
|
||||
};
|
||||
|
||||
/* maximum length of pipe/FIFO name (should be less than Linux sockaddr_un.sun_path = 108) */
|
||||
#define PIPE_URI_SIZE 96
|
||||
|
||||
#endif /* _SHIM_TYPES_H_ */
|
||||
|
||||
@@ -206,8 +206,7 @@ void append_r_debug(const char* uri, void* addr, void* dyn_addr);
|
||||
void clean_link_map_list(void);
|
||||
|
||||
/* create unique files/pipes */
|
||||
#define PIPE_URI_SIZE 40
|
||||
int create_pipe(IDTYPE* pipeid, char* uri, size_t size, PAL_HANDLE* hdl, struct shim_qstr* qstr,
|
||||
int create_pipe(char* name, char* uri, size_t size, PAL_HANDLE* hdl, struct shim_qstr* qstr,
|
||||
bool use_vmid_for_name);
|
||||
int create_dir(const char* prefix, char* path, size_t size, struct shim_handle** hdl);
|
||||
int create_file(const char* prefix, char* path, size_t size, struct shim_handle** hdl);
|
||||
|
||||
+71
-54
@@ -33,9 +33,10 @@
|
||||
#include <shim_profile.h>
|
||||
#include <shim_vdso.h>
|
||||
|
||||
#include <pal.h>
|
||||
#include <pal_debug.h>
|
||||
#include <pal_error.h>
|
||||
#include "hex.h"
|
||||
#include "pal.h"
|
||||
#include "pal_debug.h"
|
||||
#include "pal_error.h"
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <asm/unistd.h>
|
||||
@@ -807,69 +808,85 @@ static int create_unique (int (*mkname) (char *, size_t, void *),
|
||||
}
|
||||
}
|
||||
|
||||
static int name_pipe_rand (char * uri, size_t size, void * id)
|
||||
{
|
||||
IDTYPE pipeid;
|
||||
size_t len;
|
||||
int ret = DkRandomBitsRead(&pipeid, sizeof(pipeid));
|
||||
static int get_256b_random_hex_string(char* buf, size_t size) {
|
||||
char random[32]; /* 256-bit random value, sufficiently crypto secure */
|
||||
|
||||
if (size < sizeof(random) * 2 + 1)
|
||||
return -ENOMEM;
|
||||
|
||||
int ret = DkRandomBitsRead(&random, sizeof(random));
|
||||
if (ret < 0)
|
||||
return -convert_pal_errno(-ret);
|
||||
debug("creating pipe: " URI_PREFIX_PIPE_SRV "%u\n", pipeid);
|
||||
if ((len = snprintf(uri, size, URI_PREFIX_PIPE_SRV "%u", pipeid)) >= size)
|
||||
return -ERANGE;
|
||||
*((IDTYPE *)id) = pipeid;
|
||||
return len;
|
||||
}
|
||||
|
||||
static int name_pipe_vmid (char * uri, size_t size, void * id)
|
||||
{
|
||||
IDTYPE pipeid = cur_process.vmid;
|
||||
size_t len;
|
||||
debug("creating pipe: " URI_PREFIX_PIPE_SRV "%u\n", pipeid);
|
||||
if ((len = snprintf(uri, size, URI_PREFIX_PIPE_SRV "%u", pipeid)) >= size)
|
||||
return -ERANGE;
|
||||
*((IDTYPE *)id) = pipeid;
|
||||
return len;
|
||||
}
|
||||
|
||||
static int open_pipe (const char * uri, void * obj)
|
||||
{
|
||||
PAL_HANDLE pipe = DkStreamOpen(uri, 0, 0, 0, 0);
|
||||
if (!pipe)
|
||||
return PAL_NATIVE_ERRNO == PAL_ERROR_STREAMEXIST ? 1 :
|
||||
-PAL_ERRNO;
|
||||
if (obj)
|
||||
*((PAL_HANDLE *) obj) = pipe;
|
||||
else
|
||||
DkObjectClose(pipe);
|
||||
BYTES2HEXSTR(random, buf, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pipe_addr (char * uri, size_t size, const void * id,
|
||||
struct shim_qstr * qstr)
|
||||
{
|
||||
IDTYPE pipeid = *((IDTYPE *) id);
|
||||
size_t len;
|
||||
if ((len = snprintf(uri, size, URI_PREFIX_PIPE "%u", pipeid)) == size)
|
||||
static int name_pipe_rand(char* uri, size_t uri_size, void* name) {
|
||||
char pipename[PIPE_URI_SIZE];
|
||||
|
||||
int ret = get_256b_random_hex_string(pipename, sizeof(pipename));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
debug("creating pipe: " URI_PREFIX_PIPE_SRV "%s\n", pipename);
|
||||
size_t len = snprintf(uri, uri_size, URI_PREFIX_PIPE_SRV "%s", pipename);
|
||||
if (len >= uri_size)
|
||||
return -ERANGE;
|
||||
|
||||
memcpy(name, pipename, sizeof(pipename));
|
||||
return len;
|
||||
}
|
||||
|
||||
static int name_pipe_vmid(char* uri, size_t uri_size, void* name) {
|
||||
char pipename[PIPE_URI_SIZE];
|
||||
|
||||
size_t len = snprintf(pipename, sizeof(pipename), "%u", cur_process.vmid);
|
||||
if (len >= sizeof(pipename))
|
||||
return -ERANGE;
|
||||
|
||||
debug("creating pipe: " URI_PREFIX_PIPE_SRV "%s\n", pipename);
|
||||
len = snprintf(uri, uri_size, URI_PREFIX_PIPE_SRV "%s", pipename);
|
||||
if (len >= uri_size)
|
||||
return -ERANGE;
|
||||
|
||||
memcpy(name, pipename, sizeof(pipename));
|
||||
return len;
|
||||
}
|
||||
|
||||
static int open_pipe(const char* uri, void* obj) {
|
||||
assert(obj);
|
||||
|
||||
PAL_HANDLE pipe = DkStreamOpen(uri, 0, 0, 0, 0);
|
||||
if (!pipe)
|
||||
return PAL_NATIVE_ERRNO == PAL_ERROR_STREAMEXIST ? 1 : -PAL_ERRNO;
|
||||
|
||||
PAL_HANDLE* pal_hdl = (PAL_HANDLE*)obj;
|
||||
*pal_hdl = pipe;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pipe_addr(char* uri, size_t size, const void* name, struct shim_qstr* qstr) {
|
||||
char* pipename = (char*)name;
|
||||
|
||||
size_t len = snprintf(uri, size, URI_PREFIX_PIPE "%s", pipename);
|
||||
if (len >= size)
|
||||
return -ERANGE;
|
||||
|
||||
if (qstr)
|
||||
qstrsetstr(qstr, uri, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
int create_pipe (IDTYPE * id, char * uri, size_t size, PAL_HANDLE * hdl,
|
||||
struct shim_qstr * qstr, bool use_vmid_for_name)
|
||||
{
|
||||
IDTYPE pipeid;
|
||||
int ret;
|
||||
if (use_vmid_for_name)
|
||||
ret = create_unique(&name_pipe_vmid, &open_pipe, &pipe_addr,
|
||||
uri, size, &pipeid, hdl, qstr);
|
||||
else
|
||||
ret = create_unique(&name_pipe_rand, &open_pipe, &pipe_addr,
|
||||
uri, size, &pipeid, hdl, qstr);
|
||||
if (ret > 0 && id)
|
||||
*id = pipeid;
|
||||
int create_pipe(char* name, char* uri, size_t size, PAL_HANDLE* hdl, struct shim_qstr* qstr,
|
||||
bool use_vmid_for_name) {
|
||||
char pipename[PIPE_URI_SIZE];
|
||||
|
||||
int ret = create_unique(use_vmid_for_name ? &name_pipe_vmid : &name_pipe_rand, &open_pipe,
|
||||
&pipe_addr, uri, size, &pipename, hdl, qstr);
|
||||
if (ret > 0 && name) {
|
||||
memcpy(name, pipename, sizeof(pipename));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,13 +30,16 @@
|
||||
#include <shim_table.h>
|
||||
#include <shim_utils.h>
|
||||
|
||||
int create_pipes(IDTYPE* pipeid, PAL_HANDLE* srv, PAL_HANDLE* cli, struct shim_qstr* qstr,
|
||||
int flags) {
|
||||
PAL_HANDLE hdl0 = NULL, hdl1 = NULL, hdl2 = NULL;
|
||||
static int create_pipes(PAL_HANDLE* srv, PAL_HANDLE* cli, int flags, char* name,
|
||||
struct shim_qstr* qstr) {
|
||||
int ret = 0;
|
||||
char uri[PIPE_URI_SIZE];
|
||||
|
||||
if ((ret = create_pipe(pipeid, uri, PIPE_URI_SIZE, &hdl0, qstr,
|
||||
PAL_HANDLE hdl0 = NULL; /* server pipe (temporary, waits for connect from hdl2) */
|
||||
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 ((ret = create_pipe(name, uri, PIPE_URI_SIZE, &hdl0, qstr,
|
||||
/*use_vmid_for_name=*/false)) < 0) {
|
||||
debug("pipe creation failure\n");
|
||||
return ret;
|
||||
@@ -45,25 +48,26 @@ int create_pipes(IDTYPE* pipeid, PAL_HANDLE* srv, PAL_HANDLE* cli, struct shim_q
|
||||
if (!(hdl2 = DkStreamOpen(uri, 0, 0, 0, flags & O_NONBLOCK))) {
|
||||
ret = -PAL_ERRNO;
|
||||
debug("pipe connection failure\n");
|
||||
goto err;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(hdl1 = DkStreamWaitForClient(hdl0))) {
|
||||
ret = -PAL_ERRNO;
|
||||
debug("pipe acception failure\n");
|
||||
goto err;
|
||||
goto out;
|
||||
}
|
||||
|
||||
DkStreamDelete(hdl0, 0);
|
||||
DkObjectClose(hdl0);
|
||||
*srv = hdl1;
|
||||
*cli = hdl2;
|
||||
return 0;
|
||||
err:
|
||||
if (hdl1)
|
||||
DkObjectClose(hdl1);
|
||||
if (hdl2)
|
||||
DkObjectClose(hdl2);
|
||||
ret = 0;
|
||||
|
||||
out:
|
||||
if (ret < 0) {
|
||||
if (hdl1)
|
||||
DkObjectClose(hdl1);
|
||||
if (hdl2)
|
||||
DkObjectClose(hdl2);
|
||||
}
|
||||
DkStreamDelete(hdl0, 0);
|
||||
DkObjectClose(hdl0);
|
||||
return ret;
|
||||
@@ -93,11 +97,13 @@ int shim_do_pipe2(int* filedes, int flags) {
|
||||
hdl2->flags = O_WRONLY;
|
||||
hdl2->acc_mode = MAY_WRITE;
|
||||
|
||||
if ((ret = create_pipes(&hdl1->info.pipe.pipeid, &hdl1->pal_handle, &hdl2->pal_handle,
|
||||
&hdl1->uri, flags)) < 0)
|
||||
ret = create_pipes(&hdl1->pal_handle, &hdl2->pal_handle, flags, hdl1->info.pipe.name,
|
||||
&hdl1->uri);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
qstrcopy(&hdl2->uri, &hdl2->uri);
|
||||
memcpy(hdl2->info.pipe.name, hdl1->info.pipe.name, sizeof(hdl2->info.pipe.name));
|
||||
qstrcopy(&hdl2->uri, &hdl1->uri);
|
||||
|
||||
flags = flags & O_CLOEXEC ? FD_CLOEXEC : 0;
|
||||
int vfd1 = set_new_fd_handle(hdl1, flags, NULL);
|
||||
@@ -172,11 +178,12 @@ int shim_do_socketpair(int domain, int type, int protocol, int* sv) {
|
||||
sock2->protocol = protocol;
|
||||
sock2->sock_state = SOCK_CONNECTED;
|
||||
|
||||
if ((ret = create_pipes(&sock1->addr.un.pipeid, &hdl1->pal_handle, &hdl2->pal_handle,
|
||||
&hdl1->uri, type & SOCK_NONBLOCK ? O_NONBLOCK : 0)) < 0)
|
||||
ret = create_pipes(&hdl1->pal_handle, &hdl2->pal_handle, type & SOCK_NONBLOCK ? O_NONBLOCK : 0,
|
||||
sock1->addr.un.name, &hdl1->uri);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
sock2->addr.un.pipeid = sock1->addr.un.pipeid;
|
||||
memcpy(sock2->addr.un.name, sock1->addr.un.name, sizeof(sock2->addr.un.name));
|
||||
qstrcopy(&hdl2->uri, &hdl1->uri);
|
||||
|
||||
int flags = type & SOCK_CLOEXEC ? FD_CLOEXEC : 0;
|
||||
|
||||
@@ -27,8 +27,11 @@
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/in6.h>
|
||||
#include <pal.h>
|
||||
#include <pal_error.h>
|
||||
|
||||
#include "hex.h"
|
||||
#include "pal.h"
|
||||
#include "pal_error.h"
|
||||
|
||||
#include <shim_checkpoint.h>
|
||||
#include <shim_fs.h>
|
||||
#include <shim_handle.h>
|
||||
@@ -144,7 +147,7 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int unix_create_uri(char* uri, int count, enum shim_sock_state state, unsigned int pipeid) {
|
||||
static int unix_create_uri(char* uri, int count, enum shim_sock_state state, char* name) {
|
||||
int bytes = 0;
|
||||
|
||||
switch (state) {
|
||||
@@ -156,11 +159,11 @@ static int unix_create_uri(char* uri, int count, enum shim_sock_state state, uns
|
||||
case SOCK_BOUND:
|
||||
case SOCK_LISTENED:
|
||||
case SOCK_ACCEPTED:
|
||||
bytes = snprintf(uri, count, URI_PREFIX_PIPE_SRV "%u", pipeid);
|
||||
bytes = snprintf(uri, count, URI_PREFIX_PIPE_SRV "%s", name);
|
||||
break;
|
||||
|
||||
case SOCK_CONNECTED:
|
||||
bytes = snprintf(uri, count, URI_PREFIX_PIPE "%u", pipeid);
|
||||
bytes = snprintf(uri, count, URI_PREFIX_PIPE "%s", name);
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -410,7 +413,7 @@ static int create_socket_uri(struct shim_handle* hdl) {
|
||||
|
||||
if (sock->domain == AF_UNIX) {
|
||||
char uri_buf[32];
|
||||
int bytes = unix_create_uri(uri_buf, 32, sock->sock_state, sock->addr.un.pipeid);
|
||||
int bytes = unix_create_uri(uri_buf, 32, sock->sock_state, sock->addr.un.name);
|
||||
if (bytes < 0)
|
||||
return bytes;
|
||||
|
||||
@@ -447,6 +450,18 @@ static bool __socket_is_ipv6_v6only(struct shim_handle* hdl) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static int hash_to_hex_string(HASHTYPE hash, char* buf, size_t size) {
|
||||
static_assert(sizeof(hash) == 8, "Unsupported HASHTYPE size");
|
||||
char hashbytes[8];
|
||||
|
||||
if (size < sizeof(hashbytes) * 2 + 1)
|
||||
return -ENOMEM;
|
||||
|
||||
memcpy(hashbytes, &hash, sizeof(hash));
|
||||
BYTES2HEXSTR(hashbytes, buf, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int shim_do_bind(int sockfd, struct sockaddr* addr, socklen_t addrlen) {
|
||||
if (!addr || test_user_memory(addr, addrlen, false))
|
||||
@@ -492,13 +507,14 @@ int shim_do_bind(int sockfd, struct sockaddr* addr, socklen_t addrlen) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
struct shim_unix_data* data = malloc(sizeof(struct shim_unix_data));
|
||||
/* instead of user-specified sun_path of UNIX socket, use its deterministic hash as name
|
||||
* (deterministic so that independent parent and child connect to the same socket) */
|
||||
ret = hash_to_hex_string(dent->rel_path.hash, sock->addr.un.name,
|
||||
sizeof(sock->addr.un.name));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
data->pipeid = hashtype_to_idtype(dent->rel_path.hash);
|
||||
sock->addr.un.pipeid = data->pipeid;
|
||||
sock->addr.un.data = data;
|
||||
sock->addr.un.dentry = dent;
|
||||
|
||||
} else if (sock->domain == AF_INET || sock->domain == AF_INET6) {
|
||||
if ((ret = inet_check_addr(sock->domain, addr, addrlen)) < 0)
|
||||
goto out;
|
||||
@@ -531,7 +547,7 @@ int shim_do_bind(int sockfd, struct sockaddr* addr, socklen_t addrlen) {
|
||||
dent->state ^= DENTRY_NEGATIVE;
|
||||
dent->state |= DENTRY_VALID | DENTRY_RECENTLY;
|
||||
dent->fs = &socket_builtin_fs;
|
||||
dent->data = sock->addr.un.data;
|
||||
dent->data = NULL;
|
||||
}
|
||||
|
||||
if (sock->domain == AF_INET || sock->domain == AF_INET6) {
|
||||
@@ -561,11 +577,6 @@ out:
|
||||
if (sock->domain == AF_UNIX) {
|
||||
if (sock->addr.un.dentry)
|
||||
put_dentry(sock->addr.un.dentry);
|
||||
|
||||
if (sock->addr.un.data) {
|
||||
free(sock->addr.un.data);
|
||||
sock->addr.un.data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -754,18 +765,19 @@ int shim_do_connect(int sockfd, struct sockaddr* addr, int addrlen) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
struct shim_unix_data* data = dent->data;
|
||||
|
||||
if (!(dent->state & DENTRY_VALID) || dent->state & DENTRY_NEGATIVE) {
|
||||
data = malloc(sizeof(struct shim_unix_data));
|
||||
data->pipeid = hashtype_to_idtype(dent->rel_path.hash);
|
||||
} else if (dent->fs != &socket_builtin_fs) {
|
||||
if (dent->state & DENTRY_VALID && !(dent->state & DENTRY_NEGATIVE) &&
|
||||
dent->fs != &socket_builtin_fs) {
|
||||
ret = -ECONNREFUSED;
|
||||
goto out;
|
||||
}
|
||||
|
||||
sock->addr.un.pipeid = data->pipeid;
|
||||
sock->addr.un.data = data;
|
||||
/* instead of user-specified sun_path of UNIX socket, use its deterministic hash as name
|
||||
* (deterministic so that independent parent and child connect to the same socket) */
|
||||
ret = hash_to_hex_string(dent->rel_path.hash, sock->addr.un.name,
|
||||
sizeof(sock->addr.un.name));
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
sock->addr.un.dentry = dent;
|
||||
get_dentry(dent);
|
||||
}
|
||||
@@ -805,7 +817,7 @@ int shim_do_connect(int sockfd, struct sockaddr* addr, int addrlen) {
|
||||
dent->state ^= DENTRY_NEGATIVE;
|
||||
dent->state |= DENTRY_VALID | DENTRY_RECENTLY;
|
||||
dent->fs = &socket_builtin_fs;
|
||||
dent->data = sock->addr.un.data;
|
||||
dent->data = NULL;
|
||||
unlock(&dent->lock);
|
||||
}
|
||||
|
||||
@@ -837,11 +849,6 @@ out:
|
||||
if (sock->domain == AF_UNIX) {
|
||||
if (sock->addr.un.dentry)
|
||||
put_dentry(sock->addr.un.dentry);
|
||||
|
||||
if (sock->addr.un.data) {
|
||||
free(sock->addr.un.data);
|
||||
sock->addr.un.data = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -924,7 +931,7 @@ int __do_accept(struct shim_handle* hdl, int flags, struct sockaddr* addr, sockl
|
||||
cli_sock->sock_state = SOCK_ACCEPTED;
|
||||
|
||||
if (sock->domain == AF_UNIX) {
|
||||
cli_sock->addr.un.pipeid = sock->addr.un.pipeid;
|
||||
memcpy(cli_sock->addr.un.name, sock->addr.un.name, sizeof(cli_sock->addr.un.name));
|
||||
if (sock->addr.un.dentry) {
|
||||
get_dentry(sock->addr.un.dentry);
|
||||
cli_sock->addr.un.dentry = sock->addr.un.dentry;
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
static inline __attribute__((always_inline))
|
||||
char * __bytes2hexstr(void * hex, size_t size, char *str, size_t len)
|
||||
{
|
||||
static char * ch = "0123456789abcdef";
|
||||
static const char* ch = "0123456789abcdef";
|
||||
__UNUSED(len);
|
||||
assert(len >= size * 2 + 1);
|
||||
|
||||
|
||||
@@ -56,6 +56,9 @@ typedef bool PAL_BOL;
|
||||
* since it is 3, across all host kernels. */
|
||||
#define MAX_FDS 3
|
||||
|
||||
/* maximum length of pipe/FIFO name (should be less than Linux sockaddr_un.sun_path = 108) */
|
||||
#define PIPE_NAME_MAX 96
|
||||
|
||||
#ifdef IN_PAL
|
||||
#include <atomic.h>
|
||||
typedef struct atomic_int PAL_REF;
|
||||
@@ -516,9 +519,9 @@ enum PAL_OPTION {
|
||||
* * `%file:...`, `dir:...`: Files or directories on the host file system. If #PAL_CREATE_TRY is
|
||||
* given in `create` flags, the file/directory will be created.
|
||||
* * `dev:...`: Open a device as a stream. For example, `dev:tty` represents the standard I/O.
|
||||
* * `pipe.srv:<ID>`, `pipe:<ID>`, `pipe:`: Open a byte stream that can be used for RPC between
|
||||
* processes. Pipes are located by numeric IDs. The server side of a pipe can accept any number
|
||||
* of connections. If `pipe:` is given as the URI, it will open an anonymous bidirectional pipe.
|
||||
* * `pipe.srv:<name>`, `pipe:<name>`, `pipe:`: Open a byte stream that can be used for RPC between
|
||||
* processes. The server side of a pipe can accept any number of connections. If `pipe:` is given
|
||||
* as the URI (i.e., without a name), it will open an anonymous bidirectional pipe.
|
||||
* * `tcp.srv:<ADDR>:<PORT>`, `tcp:<ADDR>:<PORT>`: Open a TCP socket to listen or connect to
|
||||
* a remote TCP socket.
|
||||
* * `udp.srv:<ADDR>:<PORT>`, `udp:<ADDR>:<PORT>`: Open a UDP socket to listen or connect to
|
||||
|
||||
@@ -38,8 +38,8 @@ typedef __kernel_pid_t pid_t;
|
||||
#include <linux/types.h>
|
||||
#include <linux/un.h>
|
||||
|
||||
static int pipe_addr(int pipeid, struct sockaddr_un* addr) {
|
||||
/* use abstract UNIX sockets for pipes, with name format "@/graphene/12345678" */
|
||||
static int pipe_addr(const char* name, struct sockaddr_un* addr) {
|
||||
/* use abstract UNIX sockets for pipes, with name format "@/graphene/<pipename>" */
|
||||
addr->sun_family = AF_UNIX;
|
||||
memset(addr->sun_path, 0, sizeof(addr->sun_path));
|
||||
|
||||
@@ -48,29 +48,29 @@ static int pipe_addr(int pipeid, struct sockaddr_un* addr) {
|
||||
size_t size = sizeof(addr->sun_path) - 1;
|
||||
|
||||
/* pipe_prefix already contains a slash at the end, so not needed in the format string */
|
||||
int ret = snprintf(str, size, "%s%08x", pal_sec.pipe_prefix, pipeid);
|
||||
int ret = snprintf(str, size, "%s%s", pal_sec.pipe_prefix, name);
|
||||
return ret >= 0 && (size_t)ret < size ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Create a listening abstract UNIX socket as preparation for connecting two ends of a pipe.
|
||||
*
|
||||
* An abstract UNIX socket with name "@/graphene/<pipeid>" is opened for listening. A corresponding
|
||||
* An abstract UNIX socket with name "@/graphene/<pipename>" is opened for listening. A corresponding
|
||||
* PAL handle with type `pipesrv` is created. This PAL handle typically serves only as an
|
||||
* intermediate step to connect two ends of the pipe (`pipecli` and `pipe`). As soon as the other
|
||||
* end of the pipe connects to this listening socket, a new accepted socket and the corresponding
|
||||
* PAL handle are created, and this `pipesrv` handle can be closed.
|
||||
*
|
||||
* \param[out] handle PAL handle of type `pipesrv` with abstract UNIX socket opened for listening.
|
||||
* \param[in] pipeid Integer uniquely identifying the pipe.
|
||||
* \param[in] name String uniquely identifying the pipe.
|
||||
* \param[in] options May contain PAL_OPTION_NONBLOCK.
|
||||
* \return 0 on success, negative PAL error code otherwise.
|
||||
*/
|
||||
static int pipe_listen(PAL_HANDLE* handle, PAL_NUM pipeid, int options) {
|
||||
static int pipe_listen(PAL_HANDLE* handle, const char* name, int options) {
|
||||
int ret;
|
||||
|
||||
struct sockaddr_un addr;
|
||||
ret = pipe_addr(pipeid, &addr);
|
||||
ret = pipe_addr(name, &addr);
|
||||
if (IS_ERR(ret))
|
||||
return -PAL_ERROR_DENIED;
|
||||
|
||||
@@ -92,8 +92,8 @@ static int pipe_listen(PAL_HANDLE* handle, PAL_NUM pipeid, int options) {
|
||||
SET_HANDLE_TYPE(hdl, pipesrv);
|
||||
HANDLE_HDR(hdl)->flags |= RFD(0); /* cannot write to a listening socket */
|
||||
hdl->pipe.fd = ret;
|
||||
hdl->pipe.pipeid = pipeid;
|
||||
hdl->pipe.nonblocking = options & PAL_OPTION_NONBLOCK ? PAL_TRUE : PAL_FALSE;
|
||||
memcpy(&hdl->pipe.name.str, name, sizeof(hdl->pipe.name.str));
|
||||
|
||||
*handle = hdl;
|
||||
return 0;
|
||||
@@ -133,8 +133,8 @@ static int pipe_waitforclient(PAL_HANDLE handle, PAL_HANDLE* client) {
|
||||
SET_HANDLE_TYPE(clnt, pipecli);
|
||||
HANDLE_HDR(clnt)->flags |= RFD(0) | WFD(0);
|
||||
clnt->pipe.fd = ret;
|
||||
clnt->pipe.name = handle->pipe.name;
|
||||
clnt->pipe.nonblocking = PAL_FALSE; /* FIXME: must set nonblocking based on `handle` value */
|
||||
clnt->pipe.pipeid = handle->pipe.pipeid;
|
||||
|
||||
*client = clnt;
|
||||
return 0;
|
||||
@@ -144,20 +144,20 @@ static int pipe_waitforclient(PAL_HANDLE handle, PAL_HANDLE* client) {
|
||||
* \brief Connect to the other end of the pipe and create PAL handle for our end of the pipe.
|
||||
*
|
||||
* This function connects to the other end of the pipe, represented as an abstract UNIX socket
|
||||
* "@/graphene/<pipeid>" opened for listening. When the connection succeeds, a new `pipe` PAL handle
|
||||
* "@/graphene/<pipename>" opened for listening. When the connection succeeds, a new `pipe` PAL handle
|
||||
* is created with the corresponding underlying socket and is returned in `handle`. The other end of
|
||||
* the pipe is typically of type `pipecli`.
|
||||
*
|
||||
* \param[out] handle PAL handle of type `pipe` with abstract UNIX socket connected to another end.
|
||||
* \param[in] pipeid Integer uniquely identifying the pipe.
|
||||
* \param[in] name String uniquely identifying the pipe.
|
||||
* \param[in] options May contain PAL_OPTION_NONBLOCK.
|
||||
* \return 0 on success, negative PAL error code otherwise.
|
||||
*/
|
||||
static int pipe_connect(PAL_HANDLE* handle, PAL_NUM pipeid, int options) {
|
||||
static int pipe_connect(PAL_HANDLE* handle, const char* name, int options) {
|
||||
int ret;
|
||||
|
||||
struct sockaddr_un addr;
|
||||
ret = pipe_addr(pipeid, &addr);
|
||||
ret = pipe_addr(name, &addr);
|
||||
if (IS_ERR(ret))
|
||||
return -PAL_ERROR_DENIED;
|
||||
|
||||
@@ -180,8 +180,8 @@ static int pipe_connect(PAL_HANDLE* handle, PAL_NUM pipeid, int options) {
|
||||
SET_HANDLE_TYPE(hdl, pipe);
|
||||
HANDLE_HDR(hdl)->flags |= RFD(0) | WFD(0);
|
||||
hdl->pipe.fd = ret;
|
||||
hdl->pipe.pipeid = pipeid;
|
||||
hdl->pipe.nonblocking = (options & PAL_OPTION_NONBLOCK) ? PAL_TRUE : PAL_FALSE;
|
||||
memcpy(&hdl->pipe.name.str, name, sizeof(hdl->pipe.name.str));
|
||||
|
||||
*handle = hdl;
|
||||
return 0;
|
||||
@@ -233,17 +233,15 @@ static int pipe_private(PAL_HANDLE* handle, int options) {
|
||||
* ends of an anonymous pipe).
|
||||
*
|
||||
* - `type` is URI_TYPE_PIPE_SRV: create `pipesrv` handle (intermediate listening socket) with
|
||||
* name in the form of "@/graphene/<pipeid>" where pipeid is
|
||||
* derived from `uri` via strtol(). Caller is expected to call
|
||||
* pipe_waitforclient() afterwards.
|
||||
* name in the form of "@/graphene/<uri>". Caller is expected to
|
||||
* call pipe_waitforclient() afterwards.
|
||||
*
|
||||
* - `type` is URI_TYPE_PIPE: create `pipe` handle (connecting socket) with name in the form of
|
||||
* "@/graphene/<pipeid>" where pipeid is derived from `uri` via
|
||||
* strtol().
|
||||
* "@/graphene/<uri>".
|
||||
*
|
||||
* \param[out] handle Created PAL handle of type `pipeprv`, `pipesrv`, or `pipe`.
|
||||
* \param[in] type Can be URI_TYPE_PIPE or URI_TYPE_PIPE_SRV.
|
||||
* \param[in] uri Content is either NUL (for anonymous pipe) or an integer denoting pipeid.
|
||||
* \param[in] uri Content is either NUL (for anonymous pipe) or a string with pipe name.
|
||||
* \param[in] access Not used.
|
||||
* \param[in] share Not used.
|
||||
* \param[in] create Not used.
|
||||
@@ -259,17 +257,14 @@ static int pipe_open(PAL_HANDLE* handle, const char* type, const char* uri, int
|
||||
if (!strcmp_static(type, URI_TYPE_PIPE) && !*uri)
|
||||
return pipe_private(handle, options);
|
||||
|
||||
char* endptr;
|
||||
PAL_NUM pipeid = strtol(uri, &endptr, 10);
|
||||
|
||||
if (*endptr)
|
||||
if (strlen(uri) + 1 > PIPE_NAME_MAX)
|
||||
return -PAL_ERROR_INVAL;
|
||||
|
||||
if (!strcmp_static(type, URI_TYPE_PIPE_SRV))
|
||||
return pipe_listen(handle, pipeid, options);
|
||||
return pipe_listen(handle, uri, options);
|
||||
|
||||
if (!strcmp_static(type, URI_TYPE_PIPE))
|
||||
return pipe_connect(handle, pipeid, options);
|
||||
return pipe_connect(handle, uri, options);
|
||||
|
||||
return -PAL_ERROR_INVAL;
|
||||
}
|
||||
@@ -487,7 +482,7 @@ static int pipe_attrsetbyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) {
|
||||
/*!
|
||||
* \brief Retrieve full URI of PAL handle.
|
||||
*
|
||||
* Full URI is composed of the type and pipeid: "<type>:<pipeid>".
|
||||
* Full URI is composed of the type and pipe name: "<type>:<pipename>".
|
||||
*
|
||||
* \param[in] handle PAL handle of type `pipeprv`, `pipesrv`, `pipecli`, or `pipe`.
|
||||
* \param[out] buffer User-supplied buffer to write URI to.
|
||||
@@ -524,7 +519,7 @@ static int pipe_getname(PAL_HANDLE handle, char* buffer, size_t count) {
|
||||
buffer += prefix_len + 1;
|
||||
count -= prefix_len + 1;
|
||||
|
||||
ret = snprintf(buffer, count, "%lu\n", handle->pipe.pipeid);
|
||||
ret = snprintf(buffer, count, "%s\n", handle->pipe.name.str);
|
||||
if (buffer[ret - 1] != '\n') {
|
||||
memset(buffer, 0, count);
|
||||
return -PAL_ERROR_OVERFLOW;
|
||||
|
||||
@@ -71,6 +71,10 @@ struct pal_handle_thread {
|
||||
void * param;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char str[PIPE_NAME_MAX];
|
||||
} PAL_PIPE_NAME;
|
||||
|
||||
/* RPC streams are encrypted with 256-bit AES keys */
|
||||
typedef uint8_t PAL_SESSION_KEY[32];
|
||||
|
||||
@@ -98,7 +102,7 @@ typedef struct pal_handle
|
||||
|
||||
struct {
|
||||
PAL_IDX fd;
|
||||
PAL_NUM pipeid;
|
||||
PAL_PIPE_NAME name;
|
||||
PAL_BOL nonblocking;
|
||||
} pipe;
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@ typedef __kernel_pid_t pid_t;
|
||||
#include <linux/un.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
static int pipe_addr(int pipeid, struct sockaddr_un* addr) {
|
||||
/* use abstract UNIX sockets for pipes, with name format "@/graphene/12345678" */
|
||||
static int pipe_addr(const char* name, struct sockaddr_un* addr) {
|
||||
/* use abstract UNIX sockets for pipes, with name format "@/graphene/<pipename>" */
|
||||
addr->sun_family = AF_UNIX;
|
||||
memset(addr->sun_path, 0, sizeof(addr->sun_path));
|
||||
|
||||
@@ -50,35 +50,29 @@ static int pipe_addr(int pipeid, struct sockaddr_un* addr) {
|
||||
size_t size = sizeof(addr->sun_path) - 1;
|
||||
|
||||
/* FIXME: Below naming scheme is slightly different from Linux-SGX, not important though */
|
||||
int ret;
|
||||
if (pal_sec.pipe_prefix_id) {
|
||||
ret = snprintf(str, size, GRAPHENE_UNIX_PREFIX_FMT "/%08x",
|
||||
pal_sec.pipe_prefix_id, pipeid);
|
||||
} else {
|
||||
ret = snprintf(str, size, "/graphene/%08x", pipeid);
|
||||
}
|
||||
int ret = snprintf(str, size, "/graphene/%s", name);
|
||||
return ret >= 0 && (size_t)ret < size ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Create a listening abstract UNIX socket as preparation for connecting two ends of a pipe.
|
||||
*
|
||||
* An abstract UNIX socket with name "@/graphene/<pipeid>" is opened for listening. A corresponding
|
||||
* An abstract UNIX socket with name "@/graphene/<pipename>" is opened for listening. A corresponding
|
||||
* PAL handle with type `pipesrv` is created. This PAL handle typically serves only as an
|
||||
* intermediate step to connect two ends of the pipe (`pipecli` and `pipe`). As soon as the other
|
||||
* end of the pipe connects to this listening socket, a new accepted socket and the corresponding
|
||||
* PAL handle are created, and this `pipesrv` handle can be closed.
|
||||
*
|
||||
* \param[out] handle PAL handle of type `pipesrv` with abstract UNIX socket opened for listening.
|
||||
* \param[in] pipeid Integer uniquely identifying the pipe.
|
||||
* \param[in] name String uniquely identifying the pipe.
|
||||
* \param[in] options May contain PAL_OPTION_NONBLOCK.
|
||||
* \return 0 on success, negative PAL error code otherwise.
|
||||
*/
|
||||
static int pipe_listen(PAL_HANDLE* handle, PAL_NUM pipeid, int options) {
|
||||
static int pipe_listen(PAL_HANDLE* handle, const char* name, int options) {
|
||||
int ret;
|
||||
|
||||
struct sockaddr_un addr;
|
||||
ret = pipe_addr(pipeid, &addr);
|
||||
ret = pipe_addr(name, &addr);
|
||||
if (IS_ERR(ret))
|
||||
return -PAL_ERROR_DENIED;
|
||||
|
||||
@@ -109,8 +103,8 @@ static int pipe_listen(PAL_HANDLE* handle, PAL_NUM pipeid, int options) {
|
||||
SET_HANDLE_TYPE(hdl, pipesrv);
|
||||
HANDLE_HDR(hdl)->flags |= RFD(0); /* cannot write to a listening socket */
|
||||
hdl->pipe.fd = fd;
|
||||
hdl->pipe.pipeid = pipeid;
|
||||
hdl->pipe.nonblocking = options & PAL_OPTION_NONBLOCK ? PAL_TRUE : PAL_FALSE;
|
||||
memcpy(&hdl->pipe.name.str, name, sizeof(hdl->pipe.name.str));
|
||||
|
||||
*handle = hdl;
|
||||
return 0;
|
||||
@@ -149,8 +143,8 @@ static int pipe_waitforclient(PAL_HANDLE handle, PAL_HANDLE* client) {
|
||||
SET_HANDLE_TYPE(clnt, pipecli);
|
||||
HANDLE_HDR(clnt)->flags |= RFD(0) | WFD(0);
|
||||
clnt->pipe.fd = newfd;
|
||||
clnt->pipe.name = handle->pipe.name;
|
||||
clnt->pipe.nonblocking = PAL_FALSE; /* FIXME: must set nonblocking based on `handle` value */
|
||||
clnt->pipe.pipeid = handle->pipe.pipeid;
|
||||
|
||||
*client = clnt;
|
||||
return 0;
|
||||
@@ -160,20 +154,20 @@ static int pipe_waitforclient(PAL_HANDLE handle, PAL_HANDLE* client) {
|
||||
* \brief Connect to the other end of the pipe and create PAL handle for our end of the pipe.
|
||||
*
|
||||
* This function connects to the other end of the pipe, represented as an abstract UNIX socket
|
||||
* "@/graphene/<pipeid>" opened for listening. When the connection succeeds, a new `pipe` PAL handle
|
||||
* "@/graphene/<pipename>" opened for listening. When the connection succeeds, a new `pipe` PAL handle
|
||||
* is created with the corresponding underlying socket and is returned in `handle`. The other end of
|
||||
* the pipe is typically of type `pipecli`.
|
||||
*
|
||||
* \param[out] handle PAL handle of type `pipe` with abstract UNIX socket connected to another end.
|
||||
* \param[in] pipeid Integer uniquely identifying the pipe.
|
||||
* \param[in] name String uniquely identifying the pipe.
|
||||
* \param[in] options May contain PAL_OPTION_NONBLOCK.
|
||||
* \return 0 on success, negative PAL error code otherwise.
|
||||
*/
|
||||
static int pipe_connect(PAL_HANDLE* handle, PAL_NUM pipeid, int options) {
|
||||
static int pipe_connect(PAL_HANDLE* handle, const char* name, int options) {
|
||||
int ret;
|
||||
|
||||
struct sockaddr_un addr;
|
||||
ret = pipe_addr(pipeid, &addr);
|
||||
ret = pipe_addr(name, &addr);
|
||||
if (IS_ERR(ret))
|
||||
return -PAL_ERROR_DENIED;
|
||||
|
||||
@@ -198,8 +192,8 @@ static int pipe_connect(PAL_HANDLE* handle, PAL_NUM pipeid, int options) {
|
||||
SET_HANDLE_TYPE(hdl, pipe);
|
||||
HANDLE_HDR(hdl)->flags |= RFD(0) | WFD(0);
|
||||
hdl->pipe.fd = fd;
|
||||
hdl->pipe.pipeid = pipeid;
|
||||
hdl->pipe.nonblocking = (options & PAL_OPTION_NONBLOCK) ? PAL_TRUE : PAL_FALSE;
|
||||
memcpy(&hdl->pipe.name.str, name, sizeof(hdl->pipe.name.str));
|
||||
|
||||
*handle = hdl;
|
||||
return 0;
|
||||
@@ -251,17 +245,15 @@ static int pipe_private(PAL_HANDLE* handle, int options) {
|
||||
* ends of an anonymous pipe).
|
||||
*
|
||||
* - `type` is URI_TYPE_PIPE_SRV: create `pipesrv` handle (intermediate listening socket) with
|
||||
* name in the form of "@/graphene/<pipeid>" where pipeid is
|
||||
* derived from `uri` via strtol(). Caller is expected to call
|
||||
* pipe_waitforclient() afterwards.
|
||||
* name in the form of "@/graphene/<uri>". Caller is expected to
|
||||
* call pipe_waitforclient() afterwards.
|
||||
*
|
||||
* - `type` is URI_TYPE_PIPE: create `pipe` handle (connecting socket) with name in the form of
|
||||
* "@/graphene/<pipeid>" where pipeid is derived from `uri` via
|
||||
* strtol().
|
||||
* "@/graphene/<uri>".
|
||||
*
|
||||
* \param[out] handle Created PAL handle of type `pipeprv`, `pipesrv`, or `pipe`.
|
||||
* \param[in] type Can be URI_TYPE_PIPE or URI_TYPE_PIPE_SRV.
|
||||
* \param[in] uri Content is either NUL (for anonymous pipe) or an integer denoting pipeid.
|
||||
* \param[in] uri Content is either NUL (for anonymous pipe) or a string with pipe name.
|
||||
* \param[in] access Not used.
|
||||
* \param[in] share Not used.
|
||||
* \param[in] create Not used.
|
||||
@@ -277,17 +269,14 @@ static int pipe_open(PAL_HANDLE* handle, const char* type, const char* uri, int
|
||||
if (!strcmp_static(type, URI_TYPE_PIPE) && !*uri)
|
||||
return pipe_private(handle, options);
|
||||
|
||||
char* endptr;
|
||||
PAL_NUM pipeid = strtol(uri, &endptr, 10);
|
||||
|
||||
if (*endptr)
|
||||
if (strlen(uri) + 1 > PIPE_NAME_MAX)
|
||||
return -PAL_ERROR_INVAL;
|
||||
|
||||
if (!strcmp_static(type, URI_TYPE_PIPE_SRV))
|
||||
return pipe_listen(handle, pipeid, options);
|
||||
return pipe_listen(handle, uri, options);
|
||||
|
||||
if (!strcmp_static(type, URI_TYPE_PIPE))
|
||||
return pipe_connect(handle, pipeid, options);
|
||||
return pipe_connect(handle, uri, options);
|
||||
|
||||
return -PAL_ERROR_INVAL;
|
||||
}
|
||||
@@ -509,7 +498,7 @@ static int pipe_attrsetbyhdl(PAL_HANDLE handle, PAL_STREAM_ATTR* attr) {
|
||||
/*!
|
||||
* \brief Retrieve full URI of PAL handle.
|
||||
*
|
||||
* Full URI is composed of the type and pipeid: "<type>:<pipeid>".
|
||||
* Full URI is composed of the type and pipe name: "<type>:<pipename>".
|
||||
*
|
||||
* \param[in] handle PAL handle of type `pipeprv`, `pipesrv`, `pipecli`, or `pipe`.
|
||||
* \param[out] buffer User-supplied buffer to write URI to.
|
||||
@@ -546,7 +535,7 @@ static int pipe_getname(PAL_HANDLE handle, char* buffer, size_t count) {
|
||||
buffer += prefix_len + 1;
|
||||
count -= prefix_len + 1;
|
||||
|
||||
ret = snprintf(buffer, count, "%lu\n", handle->pipe.pipeid);
|
||||
ret = snprintf(buffer, count, "%s\n", handle->pipe.name.str);
|
||||
if (buffer[ret - 1] != '\n') {
|
||||
memset(buffer, 0, count);
|
||||
return -PAL_ERROR_OVERFLOW;
|
||||
|
||||
@@ -59,6 +59,10 @@ typedef struct {
|
||||
PAL_HDR hdr;
|
||||
} PAL_RESERVED_HDR;
|
||||
|
||||
typedef struct {
|
||||
char str[PIPE_NAME_MAX];
|
||||
} PAL_PIPE_NAME;
|
||||
|
||||
typedef struct pal_handle
|
||||
{
|
||||
/* TSAI: Here we define the internal types of PAL_HANDLE
|
||||
@@ -86,7 +90,7 @@ typedef struct pal_handle
|
||||
|
||||
struct {
|
||||
PAL_IDX fd;
|
||||
PAL_NUM pipeid;
|
||||
PAL_PIPE_NAME name;
|
||||
PAL_BOL nonblocking;
|
||||
} pipe;
|
||||
|
||||
|
||||
@@ -44,8 +44,6 @@
|
||||
#define ERRNO INTERNAL_SYSCALL_ERRNO
|
||||
#define ERRNO_P INTERNAL_SYSCALL_ERRNO_P
|
||||
|
||||
#define GRAPHENE_UNIX_PREFIX_FMT "/graphene/%016lx"
|
||||
|
||||
struct timespec;
|
||||
struct timeval;
|
||||
|
||||
|
||||
@@ -62,9 +62,6 @@ extern struct pal_sec {
|
||||
unsigned int process_id;
|
||||
int random_device;
|
||||
|
||||
/* pipes and sockets */
|
||||
unsigned long pipe_prefix_id;
|
||||
|
||||
/* for debugger */
|
||||
void (*_dl_debug_state)(void);
|
||||
struct r_debug* _r_debug;
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "pal_error.h"
|
||||
#include "pal_internal.h"
|
||||
|
||||
static int pipe_listen(PAL_HANDLE* handle, PAL_NUM pipeid, int create) {
|
||||
static int pipe_listen(PAL_HANDLE* handle, const char* name, int options) {
|
||||
return -PAL_ERROR_NOTIMPLEMENTED;
|
||||
}
|
||||
|
||||
@@ -35,41 +35,27 @@ static int pipe_waitforclient(PAL_HANDLE handle, PAL_HANDLE* client) {
|
||||
return -PAL_ERROR_NOTIMPLEMENTED;
|
||||
}
|
||||
|
||||
static int pipe_connect(PAL_HANDLE* handle, PAL_NUM pipeid, PAL_IDX connid, int create) {
|
||||
static int pipe_connect(PAL_HANDLE* handle, const char* name, int options) {
|
||||
return -PAL_ERROR_NOTIMPLEMENTED;
|
||||
}
|
||||
|
||||
static int pipe_private(PAL_HANDLE* handle) {
|
||||
static int pipe_private(PAL_HANDLE* handle, int options) {
|
||||
return -PAL_ERROR_NOTIMPLEMENTED;
|
||||
}
|
||||
|
||||
/* 'open' operation of pipe stream. For each pipe stream, it is identified by a decimal number in
|
||||
URI. There could be two types: pipe and pipe.srv. They behave pretty much the same, except they
|
||||
are two ends of the pipe. */
|
||||
static int pipe_open(PAL_HANDLE* handle, const char* type, const char* uri, int access, int share,
|
||||
int create, int options) {
|
||||
if (!strcmp_static(type, URI_TYPE_PIPE) && !*uri)
|
||||
return pipe_private(handle);
|
||||
return pipe_private(handle, options);
|
||||
|
||||
char* endptr;
|
||||
PAL_NUM pipeid = strtol(uri, &endptr, 10);
|
||||
PAL_IDX connid = 0;
|
||||
|
||||
if (*endptr == ':') {
|
||||
if (create & PAL_CREATE_TRY)
|
||||
return -PAL_ERROR_INVAL;
|
||||
|
||||
connid = strtol(endptr + 1, &endptr, 10);
|
||||
}
|
||||
|
||||
if (*endptr)
|
||||
if (strlen(uri) + 1 > PIPE_NAME_MAX)
|
||||
return -PAL_ERROR_INVAL;
|
||||
|
||||
if (!strcmp_static(type, URI_TYPE_PIPE_SRV))
|
||||
return pipe_listen(handle, pipeid, create);
|
||||
return pipe_listen(handle, uri, options);
|
||||
|
||||
if (!strcmp_static(type, URI_TYPE_PIPE))
|
||||
return pipe_connect(handle, pipeid, connid, create);
|
||||
return pipe_connect(handle, uri, options);
|
||||
|
||||
return -PAL_ERROR_INVAL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user