[PAL/Linux-SGX] Allow ocall_sock_send/recv to allocate on heap

ocall_sock_recv/send copied/allocated buffers on untrusted stack.
If buffer sizes were large, the stack overflowed. This patch
allocates buffers on untrusted heap if size is too large.
This commit is contained in:
smherwig
2019-04-28 12:43:05 -07:00
committed by Dmitrii Kuvaiskii
parent 9f61dc2871
commit 4b8f74a8d8
+38 -4
View File
@@ -581,12 +581,23 @@ int ocall_sock_recv (int sockfd, void * buf, unsigned int count,
struct sockaddr * addr, unsigned int * addrlen)
{
int retval = 0;
void *obuf = NULL;
unsigned int len = addrlen ? *addrlen : 0;
if ((count + len) > 4096) {
retval = ocall_alloc_untrusted(ALLOC_ALIGNUP(count), &obuf);
if (retval < 0)
return retval;
}
ms_ocall_sock_recv_t * ms;
OCALLOC(ms, ms_ocall_sock_recv_t *, sizeof(*ms));
ms->ms_sockfd = sockfd;
ms->ms_buf = ALLOC_IN_USER(buf, count);
if (obuf)
ms->ms_buf = obuf;
else
ms->ms_buf = ALLOC_IN_USER(buf, count);
ms->ms_count = count;
ms->ms_addr = addr ? ALLOC_IN_USER(addr, len) : NULL;
ms->ms_addrlen = len;
@@ -595,8 +606,8 @@ int ocall_sock_recv (int sockfd, void * buf, unsigned int count,
if (retval >= 0) {
if (len && (!sgx_is_completely_outside_enclave(ms->ms_addr, len) ||
ms->ms_addrlen > len)) {
OCALL_EXIT();
return -EPERM;
retval = -EPERM;
goto done;
}
COPY_FROM_USER(buf, ms->ms_buf, retval);
@@ -604,7 +615,13 @@ int ocall_sock_recv (int sockfd, void * buf, unsigned int count,
if (addrlen)
*addrlen = ms->ms_addrlen;
}
done:
OCALL_EXIT();
if (obuf)
ocall_unmap_untrusted(obuf, ALLOC_ALIGNUP(count));
return retval;
}
@@ -612,17 +629,34 @@ int ocall_sock_send (int sockfd, const void * buf, unsigned int count,
const struct sockaddr * addr, unsigned int addrlen)
{
int retval = 0;
void *obuf = NULL;
if ((count + addrlen) > 4096) {
retval = ocall_alloc_untrusted(ALLOC_ALIGNUP(count), &obuf);
if (retval < 0)
return retval;
}
ms_ocall_sock_send_t * ms;
OCALLOC(ms, ms_ocall_sock_send_t *, sizeof(*ms));
ms->ms_sockfd = sockfd;
ms->ms_buf = COPY_TO_USER(buf, count);
if (obuf) {
ms->ms_buf = obuf;
memcpy(obuf, buf, count);
} else {
ms->ms_buf = COPY_TO_USER(buf, count);
}
ms->ms_count = count;
ms->ms_addr = addr ? COPY_TO_USER(addr, addrlen) : NULL;
ms->ms_addrlen = addrlen;
retval = SGX_OCALL(OCALL_SOCK_SEND, ms);
OCALL_EXIT();
if (obuf)
ocall_unmap_untrusted(obuf, ALLOC_ALIGNUP(count));
return retval;
}