mirror of
https://github.com/clearlinux/graphene.git
synced 2026-09-07 22:31:51 +00:00
[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:
committed by
Dmitrii Kuvaiskii
parent
9f61dc2871
commit
4b8f74a8d8
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user