mirror of
https://github.com/clearlinux/graphene.git
synced 2026-09-06 22:01:29 +00:00
[LibOS] Allow zero size read/write on pipes/sockets/eventfds
Previously, zero size read/write on PAL streams of pipes/sockets/eventfds was avoided due to PAL_ERROR_ZEROSIZE. But now PAL allows this, so allow LibOS to issue zero size reads/writes.
This commit is contained in:
committed by
Dmitrii Kuvaiskii
parent
7495dffda7
commit
93eb9bc595
@@ -741,7 +741,7 @@ static ssize_t map_write (struct shim_handle * hdl, const void * buf, size_t cou
|
||||
|
||||
PAL_NUM pal_ret = DkStreamWrite(hdl->pal_handle, file->marker, count, (void *) buf, NULL);
|
||||
|
||||
if (!pal_ret) {
|
||||
if (pal_ret == PAL_STREAM_ERROR) {
|
||||
ret = -PAL_ERRNO;
|
||||
goto out;
|
||||
}
|
||||
@@ -819,7 +819,7 @@ static ssize_t chroot_read (struct shim_handle * hdl, void * buf, size_t count)
|
||||
}
|
||||
|
||||
PAL_NUM pal_ret = DkStreamRead(hdl->pal_handle, file->marker, count, buf, NULL, 0);
|
||||
if (pal_ret > 0) {
|
||||
if (pal_ret != PAL_STREAM_ERROR) {
|
||||
if (__builtin_add_overflow(pal_ret, 0, &ret))
|
||||
BUG();
|
||||
if (file->type != FILE_TTY && __builtin_add_overflow(file->marker, pal_ret, &file->marker))
|
||||
@@ -869,7 +869,7 @@ static ssize_t chroot_write (struct shim_handle * hdl, const void * buf, size_t
|
||||
}
|
||||
|
||||
PAL_NUM pal_ret = DkStreamWrite(hdl->pal_handle, file->marker, count, (void *) buf, NULL);
|
||||
if (pal_ret > 0) {
|
||||
if (pal_ret != PAL_STREAM_ERROR) {
|
||||
if (__builtin_add_overflow(pal_ret, 0, &ret))
|
||||
BUG();
|
||||
if (file->type != FILE_TTY && __builtin_add_overflow(file->marker, pal_ret, &file->marker))
|
||||
@@ -1032,8 +1032,8 @@ static int chroot_readdir(struct shim_dentry* dent, struct shim_dirent** dirent)
|
||||
|
||||
while (1) {
|
||||
/* DkStreamRead for directory will return as many entries as fits into the buffer. */
|
||||
size_t bytes = DkStreamRead(pal_hdl, 0, buf_size, buf, NULL, 0);
|
||||
if (!bytes) {
|
||||
PAL_NUM bytes = DkStreamRead(pal_hdl, 0, buf_size, buf, NULL, 0);
|
||||
if (bytes == PAL_STREAM_ERROR) {
|
||||
if (PAL_NATIVE_ERRNO == PAL_ERROR_ENDOFSTREAM) {
|
||||
/* End of directory listing */
|
||||
ret = 0;
|
||||
|
||||
@@ -31,36 +31,26 @@
|
||||
#include <shim_fs.h>
|
||||
|
||||
static ssize_t eventfd_read(struct shim_handle* hdl, void* buf, size_t count) {
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
if (count < sizeof(uint64_t))
|
||||
return -EINVAL;
|
||||
|
||||
PAL_NUM bytes = DkStreamRead(hdl->pal_handle, 0, count, buf, NULL, 0);
|
||||
|
||||
if (bytes <= 0)
|
||||
if (bytes == PAL_STREAM_ERROR)
|
||||
return -PAL_ERRNO;
|
||||
|
||||
assert((ssize_t ) bytes == sizeof(uint64_t));
|
||||
|
||||
return (ssize_t) bytes;
|
||||
}
|
||||
|
||||
static ssize_t eventfd_write(struct shim_handle* hdl, const void* buf, size_t count) {
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
if (count < sizeof(uint64_t))
|
||||
return -EINVAL;
|
||||
|
||||
PAL_NUM bytes = DkStreamWrite(hdl->pal_handle, 0, count, (void *) buf, NULL);
|
||||
|
||||
if (bytes <= 0)
|
||||
if (bytes == PAL_STREAM_ERROR)
|
||||
return -PAL_ERRNO;
|
||||
|
||||
assert((ssize_t ) bytes == sizeof(uint64_t));
|
||||
|
||||
return (ssize_t) bytes;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,28 +40,20 @@
|
||||
#include <linux/stat.h>
|
||||
|
||||
static ssize_t pipe_read(struct shim_handle* hdl, void* buf, size_t count) {
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
PAL_NUM bytes = DkStreamRead(hdl->pal_handle, 0, count, buf, NULL, 0);
|
||||
|
||||
if (!bytes)
|
||||
if (bytes == PAL_STREAM_ERROR)
|
||||
return -PAL_ERRNO;
|
||||
|
||||
assert((ssize_t)bytes > 0);
|
||||
return (ssize_t)bytes;
|
||||
}
|
||||
|
||||
static ssize_t pipe_write(struct shim_handle* hdl, const void* buf, size_t count) {
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
PAL_NUM bytes = DkStreamWrite(hdl->pal_handle, 0, count, (void*)buf, NULL);
|
||||
|
||||
if (!bytes)
|
||||
if (bytes == PAL_STREAM_ERROR)
|
||||
return -PAL_ERRNO;
|
||||
|
||||
assert((ssize_t)bytes > 0);
|
||||
return (ssize_t)bytes;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,9 +45,6 @@ static int socket_close(struct shim_handle* hdl) {
|
||||
static ssize_t socket_read(struct shim_handle* hdl, void* buf, size_t count) {
|
||||
struct shim_sock_handle* sock = &hdl->info.sock;
|
||||
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
lock(&hdl->lock);
|
||||
|
||||
if (sock->sock_type == SOCK_STREAM && sock->sock_state != SOCK_ACCEPTED &&
|
||||
@@ -68,7 +65,7 @@ static ssize_t socket_read(struct shim_handle* hdl, void* buf, size_t count) {
|
||||
|
||||
PAL_NUM bytes = DkStreamRead(hdl->pal_handle, 0, count, buf, NULL, 0);
|
||||
|
||||
if (!bytes)
|
||||
if (bytes == PAL_STREAM_ERROR)
|
||||
switch (PAL_NATIVE_ERRNO) {
|
||||
case PAL_ERROR_ENDOFSTREAM:
|
||||
return 0;
|
||||
@@ -81,7 +78,6 @@ static ssize_t socket_read(struct shim_handle* hdl, void* buf, size_t count) {
|
||||
}
|
||||
}
|
||||
|
||||
assert((ssize_t)bytes > 0);
|
||||
return (ssize_t)bytes;
|
||||
}
|
||||
|
||||
@@ -106,12 +102,9 @@ static ssize_t socket_write(struct shim_handle* hdl, const void* buf, size_t cou
|
||||
|
||||
unlock(&hdl->lock);
|
||||
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
PAL_NUM bytes = DkStreamWrite(hdl->pal_handle, 0, count, (void*)buf, NULL);
|
||||
|
||||
if (!bytes) {
|
||||
if (bytes == PAL_STREAM_ERROR) {
|
||||
int err;
|
||||
switch (PAL_NATIVE_ERRNO) {
|
||||
case PAL_ERROR_CONNFAILED:
|
||||
@@ -127,7 +120,6 @@ static ssize_t socket_write(struct shim_handle* hdl, const void* buf, size_t cou
|
||||
return -err;
|
||||
}
|
||||
|
||||
assert((ssize_t)bytes > 0);
|
||||
return (ssize_t)bytes;
|
||||
}
|
||||
|
||||
|
||||
@@ -311,10 +311,10 @@ int send_ipc_message(struct shim_ipc_msg* msg, struct shim_ipc_port* port) {
|
||||
size_t bytes = 0;
|
||||
|
||||
do {
|
||||
size_t ret =
|
||||
PAL_NUM ret =
|
||||
DkStreamWrite(port->pal_handle, 0, total_bytes - bytes, (void*)msg + bytes, NULL);
|
||||
|
||||
if (!ret) {
|
||||
if (ret == PAL_STREAM_ERROR) {
|
||||
if (PAL_ERRNO == EINTR || PAL_ERRNO == EAGAIN || PAL_ERRNO == EWOULDBLOCK)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -557,10 +557,10 @@ static int receive_ipc_message(struct shim_ipc_port* port) {
|
||||
msg = tmp_buf;
|
||||
}
|
||||
|
||||
size_t read = DkStreamRead(port->pal_handle, /*offset=*/0, expected_size - bytes + readahead,
|
||||
PAL_NUM read = DkStreamRead(port->pal_handle, /*offset=*/0, expected_size - bytes + readahead,
|
||||
(void *) msg + bytes, NULL, 0);
|
||||
|
||||
if (!read) {
|
||||
if (read == PAL_STREAM_ERROR) {
|
||||
if (PAL_ERRNO == EINTR || PAL_ERRNO == EAGAIN || PAL_ERRNO == EWOULDBLOCK)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -500,10 +500,10 @@ static int send_checkpoint_on_stream (PAL_HANDLE stream,
|
||||
size_t bytes = 0;
|
||||
|
||||
do {
|
||||
size_t ret = DkStreamWrite(stream, 0, total_bytes - bytes,
|
||||
PAL_NUM ret = DkStreamWrite(stream, 0, total_bytes - bytes,
|
||||
(void *) store->base + bytes, NULL);
|
||||
|
||||
if (!ret) {
|
||||
if (ret == PAL_STREAM_ERROR) {
|
||||
if (PAL_ERRNO == EINTR || PAL_ERRNO == EAGAIN ||
|
||||
PAL_ERRNO == EWOULDBLOCK)
|
||||
continue;
|
||||
@@ -520,9 +520,9 @@ static int send_checkpoint_on_stream (PAL_HANDLE stream,
|
||||
void * mem_addr = mem_entries[i]->addr;
|
||||
bytes = 0;
|
||||
do {
|
||||
size_t ret = DkStreamWrite(stream, 0, mem_size - bytes,
|
||||
PAL_NUM ret = DkStreamWrite(stream, 0, mem_size - bytes,
|
||||
mem_addr + bytes, NULL);
|
||||
if (!ret) {
|
||||
if (ret == PAL_STREAM_ERROR) {
|
||||
if (PAL_ERRNO == EINTR || PAL_ERRNO == EAGAIN ||
|
||||
PAL_ERRNO == EWOULDBLOCK)
|
||||
continue;
|
||||
@@ -929,7 +929,7 @@ int do_migrate_process (int (*migrate) (struct shim_cp_store *,
|
||||
int ret = 0;
|
||||
struct shim_process * new_process = NULL;
|
||||
struct newproc_header hdr;
|
||||
size_t bytes;
|
||||
PAL_NUM bytes;
|
||||
PAL_HANDLE gipc_hdl = NULL;
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
|
||||
@@ -1073,7 +1073,7 @@ int do_migrate_process (int (*migrate) (struct shim_cp_store *,
|
||||
* notify the process to start receiving the checkpoint.
|
||||
*/
|
||||
bytes = DkStreamWrite(proc, 0, sizeof(struct newproc_header), &hdr, NULL);
|
||||
if (!bytes) {
|
||||
if (bytes == PAL_STREAM_ERROR) {
|
||||
ret = -PAL_ERRNO;
|
||||
debug("failed writing to process stream (ret = %d)\n", ret);
|
||||
goto out;
|
||||
@@ -1120,7 +1120,7 @@ int do_migrate_process (int (*migrate) (struct shim_cp_store *,
|
||||
struct newproc_response res;
|
||||
bytes = DkStreamRead(proc, 0, sizeof(struct newproc_response), &res,
|
||||
NULL, 0);
|
||||
if (bytes == 0) {
|
||||
if (bytes == PAL_STREAM_ERROR) {
|
||||
ret = -PAL_ERRNO;
|
||||
goto out;
|
||||
}
|
||||
@@ -1257,11 +1257,11 @@ int do_migration (struct newproc_cp_header * hdr, void ** cpptr)
|
||||
} else {
|
||||
size_t total_bytes = 0;
|
||||
while (total_bytes < size) {
|
||||
int bytes = DkStreamRead(PAL_CB(parent_process), 0,
|
||||
size - total_bytes,
|
||||
(void *) base + total_bytes, NULL, 0);
|
||||
PAL_NUM bytes = DkStreamRead(PAL_CB(parent_process), 0,
|
||||
size - total_bytes,
|
||||
(void *) base + total_bytes, NULL, 0);
|
||||
|
||||
if (!bytes) {
|
||||
if (bytes == PAL_STREAM_ERROR) {
|
||||
if (PAL_ERRNO == EINTR || PAL_ERRNO == EAGAIN ||
|
||||
PAL_ERRNO == EWOULDBLOCK)
|
||||
continue;
|
||||
|
||||
+21
-19
@@ -101,7 +101,6 @@ static int pal_errno_to_unix_errno [PAL_ERROR_NATIVE_COUNT + 1] = {
|
||||
/* PAL_ERROR_ENDOFSTREAM */ 0,
|
||||
/* PAL_ERROR_NOTSERVER */ EINVAL,
|
||||
/* PAL_ERROR_NOTCONNECTION */ ENOTCONN,
|
||||
/* PAL_ERROR_ZEROSIZE */ 0,
|
||||
/* PAL_ERROR_CONNFAILED */ ECONNRESET,
|
||||
/* PAL_ERROR_ADDRNOTEXIST */ EADDRNOTAVAIL,
|
||||
/* PAL_ERROR_AFNOSUPPORT */ EAFNOSUPPORT,
|
||||
@@ -617,10 +616,10 @@ static int init_newproc (struct newproc_header * hdr)
|
||||
{
|
||||
BEGIN_PROFILE_INTERVAL();
|
||||
|
||||
int bytes = DkStreamRead(PAL_CB(parent_process), 0,
|
||||
sizeof(struct newproc_header), hdr,
|
||||
NULL, 0);
|
||||
if (!bytes)
|
||||
PAL_NUM bytes = DkStreamRead(PAL_CB(parent_process), 0,
|
||||
sizeof(struct newproc_header), hdr,
|
||||
NULL, 0);
|
||||
if (bytes == PAL_STREAM_ERROR)
|
||||
return -PAL_ERRNO;
|
||||
|
||||
SAVE_PROFILE_INTERVAL(child_wait_header);
|
||||
@@ -788,9 +787,10 @@ noreturn void* shim_init (int argc, void * args)
|
||||
struct newproc_response res;
|
||||
res.child_vmid = cur_process.vmid;
|
||||
res.failure = 0;
|
||||
if (!DkStreamWrite(PAL_CB(parent_process), 0,
|
||||
sizeof(struct newproc_response),
|
||||
&res, NULL))
|
||||
PAL_NUM ret = DkStreamWrite(PAL_CB(parent_process), 0,
|
||||
sizeof(struct newproc_response),
|
||||
&res, NULL);
|
||||
if (ret == PAL_STREAM_ERROR)
|
||||
shim_do_exit(-PAL_ERRNO);
|
||||
}
|
||||
|
||||
@@ -1231,20 +1231,22 @@ int message_confirm (const char * message, const char * options)
|
||||
return -EACCES;
|
||||
}
|
||||
|
||||
#define WRITE(buf, len) \
|
||||
({ int _ret = DkStreamWrite(hdl, 0, len, (void*)(buf), NULL); \
|
||||
_ret ? : -PAL_ERRNO; })
|
||||
|
||||
#define READ(buf, len) \
|
||||
({ int _ret = DkStreamRead(hdl, 0, len, buf, NULL, 0); \
|
||||
_ret ? : -PAL_ERRNO; })
|
||||
|
||||
if ((ret = WRITE(message, strlen(message))) < 0)
|
||||
PAL_NUM pal_ret;
|
||||
pal_ret = DkStreamWrite(hdl, 0, strlen(message), (void*)message, NULL);
|
||||
if (pal_ret == PAL_STREAM_ERROR) {
|
||||
ret = -PAL_ERRNO;
|
||||
goto out;
|
||||
if ((ret = WRITE(option_str, noptions * 2 + 3)) < 0)
|
||||
}
|
||||
pal_ret = DkStreamWrite(hdl, 0, noptions * 2 + 3, option_str, NULL);
|
||||
if (pal_ret == PAL_STREAM_ERROR) {
|
||||
ret = -PAL_ERRNO;
|
||||
goto out;
|
||||
if ((ret = READ(&answer, 1)) < 0)
|
||||
}
|
||||
pal_ret = DkStreamRead(hdl, 0, 1, &answer, NULL, 0);
|
||||
if (pal_ret == PAL_STREAM_ERROR) {
|
||||
ret = -PAL_ERRNO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
DkObjectClose(hdl);
|
||||
|
||||
@@ -832,8 +832,12 @@ static int __load_msg_persist(struct shim_msg_handle* msgq, bool readmsg) {
|
||||
|
||||
size_t bytes = DkStreamRead(file, 0, sizeof(struct msg_handle_backup), &mback, NULL, 0);
|
||||
|
||||
if (bytes == PAL_STREAM_ERROR) {
|
||||
ret = -PAL_ERRNO;
|
||||
goto out;
|
||||
}
|
||||
if (bytes < sizeof(struct msg_handle_backup)) {
|
||||
ret = bytes ? -EFAULT : -PAL_ERRNO;
|
||||
ret = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
@@ -1057,14 +1057,14 @@ static ssize_t do_sendmsg(int fd, struct iovec* bufs, int nbufs, int flags,
|
||||
ret = 0;
|
||||
|
||||
for (int i = 0; i < nbufs; i++) {
|
||||
ret = DkStreamWrite(pal_hdl, 0, bufs[i].iov_len, bufs[i].iov_base, uri);
|
||||
PAL_NUM pal_ret = DkStreamWrite(pal_hdl, 0, bufs[i].iov_len, bufs[i].iov_base, uri);
|
||||
|
||||
if (!ret) {
|
||||
if (pal_ret == PAL_STREAM_ERROR) {
|
||||
ret = (PAL_NATIVE_ERRNO == PAL_ERROR_STREAMEXIST) ? -ECONNABORTED : -PAL_ERRNO;
|
||||
break;
|
||||
}
|
||||
|
||||
bytes += ret;
|
||||
bytes += pal_ret;
|
||||
}
|
||||
|
||||
if (bytes)
|
||||
@@ -1189,15 +1189,14 @@ static ssize_t do_recvmsg(int fd, struct iovec* bufs, int nbufs, int flags, stru
|
||||
ret = 0;
|
||||
|
||||
for (int i = 0; i < nbufs; i++) {
|
||||
ret = DkStreamRead(pal_hdl, 0, bufs[i].iov_len, bufs[i].iov_base, uri,
|
||||
uri ? SOCK_URI_SIZE : 0);
|
||||
PAL_NUM pal_ret = DkStreamRead(pal_hdl, 0, bufs[i].iov_len, bufs[i].iov_base, uri, uri ? SOCK_URI_SIZE : 0);
|
||||
|
||||
if (!ret) {
|
||||
if (pal_ret == PAL_STREAM_ERROR) {
|
||||
ret = (PAL_NATIVE_ERRNO == PAL_ERROR_STREAMNOTEXIST) ? -ECONNABORTED : -PAL_ERRNO;
|
||||
break;
|
||||
}
|
||||
|
||||
bytes += ret;
|
||||
bytes += pal_ret;
|
||||
|
||||
if (!addr || !bytes || address_received)
|
||||
continue;
|
||||
|
||||
@@ -74,7 +74,7 @@ int get_norm_path(const char* path, char* buf, size_t* size_ptr) {
|
||||
|
||||
size_t size = *size_ptr;
|
||||
if (!size) {
|
||||
return -PAL_ERROR_ZEROSIZE;
|
||||
return -PAL_ERROR_INVAL;
|
||||
}
|
||||
/* reserve 1 byte for ending '\0' */
|
||||
size--;
|
||||
|
||||
Reference in New Issue
Block a user