enclave_ocalls.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792
  1. /* -*- mode:c; c-file-style:"k&r"; c-basic-offset: 4; tab-width:4; indent-tabs-mode:nil; mode:auto-fill; fill-column:78; -*- */
  2. /* vim: set ts=4 sw=4 et tw=78 fo=cqt wm=0: */
  3. /*
  4. * This is for enclave to make ocalls to untrusted runtime.
  5. */
  6. #include "pal_linux.h"
  7. #include "pal_internal.h"
  8. #include "pal_debug.h"
  9. #include "enclave_ocalls.h"
  10. #include "ocall_types.h"
  11. #include "ecall_types.h"
  12. #include <api.h>
  13. #include <asm/errno.h>
  14. #define OCALLOC(val, type, len) do { \
  15. void * _tmp = sgx_ocalloc(len); \
  16. if (_tmp == NULL) { \
  17. OCALL_EXIT(); \
  18. return -PAL_ERROR_DENIED; /* TODO: remove this control-flow obfuscation */ \
  19. } \
  20. (val) = (type) _tmp; \
  21. } while (0)
  22. int printf(const char * fmt, ...);
  23. #define SGX_OCALL(code, ms) sgx_ocall(code, ms)
  24. #define OCALL_EXIT() \
  25. do { \
  26. sgx_ocfree(); \
  27. } while (0)
  28. #define ALLOC_IN_USER(ptr, size) \
  29. ({ \
  30. typeof(ptr) tmp = ptr; \
  31. if (sgx_is_within_enclave(ptr, size)) { \
  32. OCALLOC(tmp, typeof(tmp), size); \
  33. }; tmp; \
  34. })
  35. #define COPY_TO_USER(ptr, size) \
  36. ({ \
  37. typeof(ptr) tmp = ptr; \
  38. if (sgx_is_within_enclave(ptr, size)) { \
  39. OCALLOC(tmp, typeof(tmp), size); \
  40. memcpy((void *) tmp, ptr, size); \
  41. }; tmp; \
  42. })
  43. #define COPY_FROM_USER(var, user_var, size) \
  44. ({ \
  45. int _ret = 0; \
  46. if (var != user_var) { \
  47. if (sgx_is_within_enclave(user_var, size) || \
  48. !sgx_is_within_enclave(var, size)) { \
  49. _ret = -PAL_ERROR_DENIED; \
  50. } else { \
  51. _ret = 0; \
  52. memcpy(var, user_var, size); \
  53. } \
  54. } _ret; \
  55. })
  56. int ocall_exit(void)
  57. {
  58. int retval = 0;
  59. SGX_OCALL(OCALL_EXIT, NULL);
  60. /* never reach here */
  61. return retval;
  62. }
  63. int ocall_print_string (const char * str, unsigned int length)
  64. {
  65. int retval = 0;
  66. ms_ocall_print_string_t * ms;
  67. OCALLOC(ms, ms_ocall_print_string_t *, sizeof(*ms));
  68. if (!str || length <= 0) {
  69. OCALL_EXIT();
  70. return -PAL_ERROR_DENIED;
  71. }
  72. ms->ms_str = COPY_TO_USER(str, length);
  73. ms->ms_length = length;
  74. retval = SGX_OCALL(OCALL_PRINT_STRING, ms);
  75. OCALL_EXIT();
  76. return retval;
  77. }
  78. int ocall_alloc_untrusted (uint64_t size, void ** mem)
  79. {
  80. int retval = 0;
  81. ms_ocall_alloc_untrusted_t * ms;
  82. OCALLOC(ms, ms_ocall_alloc_untrusted_t *, sizeof(*ms));
  83. ms->ms_size = size;
  84. retval = SGX_OCALL(OCALL_ALLOC_UNTRUSTED, ms);
  85. if (!retval) {
  86. if (sgx_is_within_enclave(ms->ms_mem, size)) {
  87. OCALL_EXIT();
  88. return -PAL_ERROR_DENIED;
  89. }
  90. *mem = ms->ms_mem;
  91. }
  92. OCALL_EXIT();
  93. return retval;
  94. }
  95. int ocall_map_untrusted (int fd, uint64_t offset,
  96. uint64_t size, unsigned short prot,
  97. void ** mem)
  98. {
  99. int retval = 0;
  100. ms_ocall_map_untrusted_t * ms;
  101. OCALLOC(ms, ms_ocall_map_untrusted_t *, sizeof(*ms));
  102. ms->ms_fd = fd;
  103. ms->ms_offset = offset;
  104. ms->ms_size = size;
  105. ms->ms_prot = prot;
  106. retval = SGX_OCALL(OCALL_MAP_UNTRUSTED, ms);
  107. if (!retval) {
  108. if (sgx_is_within_enclave(ms->ms_mem, size)) {
  109. OCALL_EXIT();
  110. return -PAL_ERROR_DENIED;
  111. }
  112. *mem = ms->ms_mem;
  113. }
  114. OCALL_EXIT();
  115. return retval;
  116. }
  117. int ocall_unmap_untrusted (const void * mem, uint64_t size)
  118. {
  119. int retval = 0;
  120. if (sgx_is_within_enclave(mem, size)) {
  121. OCALL_EXIT();
  122. return -PAL_ERROR_INVAL;
  123. }
  124. ms_ocall_unmap_untrusted_t * ms;
  125. OCALLOC(ms, ms_ocall_unmap_untrusted_t *, sizeof(*ms));
  126. ms->ms_mem = mem;
  127. ms->ms_size = size;
  128. retval = SGX_OCALL(OCALL_UNMAP_UNTRUSTED, ms);
  129. OCALL_EXIT();
  130. return retval;
  131. }
  132. int ocall_cpuid (unsigned int leaf, unsigned int subleaf,
  133. unsigned int values[4])
  134. {
  135. int retval = 0;
  136. ms_ocall_cpuid_t * ms;
  137. OCALLOC(ms, ms_ocall_cpuid_t *, sizeof(*ms));
  138. ms->ms_leaf = leaf;
  139. ms->ms_subleaf = subleaf;
  140. retval = SGX_OCALL(OCALL_CPUID, ms);
  141. if (!retval) {
  142. values[0] = ms->ms_values[0];
  143. values[1] = ms->ms_values[1];
  144. values[2] = ms->ms_values[2];
  145. values[3] = ms->ms_values[3];
  146. }
  147. OCALL_EXIT();
  148. return retval;
  149. }
  150. int ocall_open (const char * pathname, int flags, unsigned short mode)
  151. {
  152. int retval = 0;
  153. int len = pathname ? strlen(pathname) + 1 : 0;
  154. ms_ocall_open_t * ms;
  155. OCALLOC(ms, ms_ocall_open_t *, sizeof(*ms));
  156. ms->ms_pathname = COPY_TO_USER(pathname, len);
  157. ms->ms_flags = flags;
  158. ms->ms_mode = mode;
  159. retval = SGX_OCALL(OCALL_OPEN, ms);
  160. OCALL_EXIT();
  161. return retval;
  162. }
  163. int ocall_close (int fd)
  164. {
  165. int retval = 0;
  166. ms_ocall_close_t *ms;
  167. OCALLOC(ms, ms_ocall_close_t *, sizeof(*ms));
  168. ms->ms_fd = fd;
  169. retval = SGX_OCALL(OCALL_CLOSE, ms);
  170. OCALL_EXIT();
  171. return retval;
  172. }
  173. int ocall_read (int fd, void * buf, unsigned int count)
  174. {
  175. int retval = 0;
  176. void * obuf = NULL;
  177. if (count > 4096) {
  178. retval = ocall_alloc_untrusted(ALLOC_ALIGNUP(count), &obuf);
  179. if (retval < 0)
  180. return retval;
  181. }
  182. ms_ocall_read_t * ms;
  183. OCALLOC(ms, ms_ocall_read_t *, sizeof(*ms));
  184. ms->ms_fd = fd;
  185. if (obuf)
  186. ms->ms_buf = obuf;
  187. else
  188. OCALLOC(ms->ms_buf, void *, count);
  189. ms->ms_count = count;
  190. retval = SGX_OCALL(OCALL_READ, ms);
  191. if (retval > 0)
  192. memcpy(buf, ms->ms_buf, retval);
  193. OCALL_EXIT();
  194. if (obuf)
  195. ocall_unmap_untrusted(obuf, ALLOC_ALIGNUP(count));
  196. return retval;
  197. }
  198. int ocall_write (int fd, const void * buf, unsigned int count)
  199. {
  200. int retval = 0;
  201. void * obuf = NULL;
  202. if (count > 4096) {
  203. retval = ocall_alloc_untrusted(ALLOC_ALIGNUP(count), &obuf);
  204. if (retval < 0)
  205. return retval;
  206. }
  207. ms_ocall_write_t * ms;
  208. OCALLOC(ms, ms_ocall_write_t *, sizeof(*ms));
  209. ms->ms_fd = fd;
  210. if (obuf) {
  211. ms->ms_buf = obuf;
  212. memcpy(obuf, buf, count);
  213. } else {
  214. ms->ms_buf = COPY_TO_USER(buf, count);
  215. }
  216. ms->ms_count = count;
  217. retval = SGX_OCALL(OCALL_WRITE, ms);
  218. OCALL_EXIT();
  219. if (obuf)
  220. ocall_unmap_untrusted(obuf, ALLOC_ALIGNUP(count));
  221. return retval;
  222. }
  223. int ocall_fstat (int fd, struct stat * buf)
  224. {
  225. int retval = 0;
  226. ms_ocall_fstat_t * ms;
  227. OCALLOC(ms, ms_ocall_fstat_t *, sizeof(*ms));
  228. ms->ms_fd = fd;
  229. retval = SGX_OCALL(OCALL_FSTAT, ms);
  230. if (!retval)
  231. memcpy(buf, &ms->ms_stat, sizeof(struct stat));
  232. OCALL_EXIT();
  233. return retval;
  234. }
  235. int ocall_fionread (int fd)
  236. {
  237. int retval = 0;
  238. ms_ocall_fionread_t * ms;
  239. OCALLOC(ms, ms_ocall_fionread_t *, sizeof(*ms));
  240. ms->ms_fd = fd;
  241. retval = SGX_OCALL(OCALL_FIONREAD, ms);
  242. OCALL_EXIT();
  243. return retval;
  244. }
  245. int ocall_fsetnonblock (int fd, int nonblocking)
  246. {
  247. int retval = 0;
  248. ms_ocall_fsetnonblock_t * ms;
  249. OCALLOC(ms, ms_ocall_fsetnonblock_t *, sizeof(*ms));
  250. ms->ms_fd = fd;
  251. ms->ms_nonblocking = nonblocking;
  252. retval = SGX_OCALL(OCALL_FSETNONBLOCK, ms);
  253. OCALL_EXIT();
  254. return retval;
  255. }
  256. int ocall_fchmod (int fd, unsigned short mode)
  257. {
  258. int retval = 0;
  259. ms_ocall_fchmod_t * ms;
  260. OCALLOC(ms, ms_ocall_fchmod_t *, sizeof(*ms));
  261. ms->ms_fd = fd;
  262. ms->ms_mode = mode;
  263. retval = SGX_OCALL(OCALL_FCHMOD, ms);
  264. OCALL_EXIT();
  265. return retval;
  266. }
  267. int ocall_fsync (int fd)
  268. {
  269. int retval = 0;
  270. ms_ocall_fsync_t * ms;
  271. OCALLOC(ms, ms_ocall_fsync_t *, sizeof(*ms));
  272. ms->ms_fd = fd;
  273. retval = SGX_OCALL(OCALL_FSYNC, ms);
  274. OCALL_EXIT();
  275. return retval;
  276. }
  277. int ocall_ftruncate (int fd, uint64_t length)
  278. {
  279. int retval = 0;
  280. ms_ocall_ftruncate_t * ms;
  281. OCALLOC(ms, ms_ocall_ftruncate_t *, sizeof(*ms));
  282. ms->ms_fd = fd;
  283. ms->ms_length = length;
  284. retval = SGX_OCALL(OCALL_FTRUNCATE, ms);
  285. OCALL_EXIT();
  286. return retval;
  287. }
  288. int ocall_mkdir (const char * pathname, unsigned short mode)
  289. {
  290. int retval = 0;
  291. int len = pathname ? strlen(pathname) + 1 : 0;
  292. ms_ocall_mkdir_t * ms;
  293. OCALLOC(ms, ms_ocall_mkdir_t *, sizeof(*ms));
  294. ms->ms_pathname = COPY_TO_USER(pathname, len);
  295. ms->ms_mode = mode;
  296. retval = SGX_OCALL(OCALL_MKDIR, ms);
  297. OCALL_EXIT();
  298. return retval;
  299. }
  300. int ocall_getdents (int fd, struct linux_dirent64 * dirp, unsigned int size)
  301. {
  302. int retval = 0;
  303. ms_ocall_getdents_t * ms;
  304. OCALLOC(ms, ms_ocall_getdents_t *, sizeof(*ms));
  305. ms->ms_fd = fd;
  306. ms->ms_dirp = ALLOC_IN_USER(dirp, size);
  307. ms->ms_size = size;
  308. retval = SGX_OCALL(OCALL_GETDENTS, ms);
  309. if (retval > 0)
  310. COPY_FROM_USER(dirp, ms->ms_dirp, retval);
  311. OCALL_EXIT();
  312. return retval;
  313. }
  314. int ocall_wake_thread (void * tcs)
  315. {
  316. return SGX_OCALL(OCALL_WAKE_THREAD, tcs);
  317. }
  318. int ocall_create_process (const char * uri,
  319. int nargs, const char ** args,
  320. int procfds[3],
  321. unsigned int * pid)
  322. {
  323. int retval = 0;
  324. int ulen = uri ? strlen(uri) + 1 : 0;
  325. ms_ocall_create_process_t * ms;
  326. OCALLOC(ms, ms_ocall_create_process_t *,
  327. sizeof(*ms) + sizeof(const char *) * nargs);
  328. ms->ms_uri = uri ? COPY_TO_USER(uri, ulen) : NULL;
  329. ms->ms_nargs = nargs;
  330. for (int i = 0 ; i < nargs ; i++) {
  331. int len = args[i] ? strlen(args[i]) + 1 : 0;
  332. ms->ms_args[i] = args[i] ? COPY_TO_USER(args[i], len) : NULL;
  333. }
  334. retval = SGX_OCALL(OCALL_CREATE_PROCESS, ms);
  335. if (!retval) {
  336. if (pid)
  337. *pid = ms->ms_pid;
  338. procfds[0] = ms->ms_proc_fds[0];
  339. procfds[1] = ms->ms_proc_fds[1];
  340. procfds[2] = ms->ms_proc_fds[2];
  341. }
  342. OCALL_EXIT();
  343. return retval;
  344. }
  345. int ocall_futex (int * futex, int op, int val,
  346. const uint64_t * timeout)
  347. {
  348. int retval = 0;
  349. ms_ocall_futex_t * ms;
  350. OCALLOC(ms, ms_ocall_futex_t *, sizeof(*ms));
  351. if (sgx_is_within_enclave(futex, sizeof(int))) {
  352. OCALL_EXIT();
  353. return -PAL_ERROR_INVAL;
  354. }
  355. ms->ms_futex = futex;
  356. ms->ms_op = op;
  357. ms->ms_val = val;
  358. ms->ms_timeout = timeout ? *timeout : OCALL_NO_TIMEOUT;
  359. retval = SGX_OCALL(OCALL_FUTEX, ms);
  360. OCALL_EXIT();
  361. return retval;
  362. }
  363. int ocall_socketpair (int domain, int type, int protocol,
  364. int sockfds[2])
  365. {
  366. int retval = 0;
  367. ms_ocall_socketpair_t * ms;
  368. OCALLOC(ms, ms_ocall_socketpair_t *, sizeof(*ms));
  369. ms->ms_domain = domain;
  370. ms->ms_type = type;
  371. ms->ms_protocol = protocol;
  372. retval = SGX_OCALL(OCALL_SOCKETPAIR, ms);
  373. if (!retval) {
  374. sockfds[0] = ms->ms_sockfds[0];
  375. sockfds[1] = ms->ms_sockfds[1];
  376. }
  377. OCALL_EXIT();
  378. return retval;
  379. }
  380. int ocall_sock_listen (int domain, int type, int protocol,
  381. struct sockaddr * addr, unsigned int * addrlen,
  382. struct sockopt * sockopt)
  383. {
  384. int retval = 0;
  385. unsigned int bind_len = *addrlen;
  386. ms_ocall_sock_listen_t * ms;
  387. OCALLOC(ms, ms_ocall_sock_listen_t *, sizeof(*ms));
  388. ms->ms_domain = domain;
  389. ms->ms_type = type;
  390. ms->ms_protocol = protocol;
  391. ms->ms_addr = COPY_TO_USER(addr, bind_len);
  392. ms->ms_addrlen = bind_len;
  393. retval = SGX_OCALL(OCALL_SOCK_LISTEN, ms);
  394. if (retval >= 0) {
  395. if (addrlen && (
  396. sgx_is_within_enclave(ms->ms_addr, bind_len) ||
  397. ms->ms_addrlen > bind_len)) {
  398. OCALL_EXIT();
  399. return -PAL_ERROR_DENIED;
  400. }
  401. if (addr) {
  402. COPY_FROM_USER(addr, ms->ms_addr, ms->ms_addrlen);
  403. *addrlen = ms->ms_addrlen;
  404. }
  405. if (sockopt)
  406. *sockopt = ms->ms_sockopt;
  407. }
  408. OCALL_EXIT();
  409. return retval;
  410. }
  411. int ocall_sock_accept (int sockfd, struct sockaddr * addr,
  412. unsigned int * addrlen, struct sockopt * sockopt)
  413. {
  414. int retval = 0;
  415. unsigned int len = addrlen ? *addrlen : 0;
  416. ms_ocall_sock_accept_t * ms;
  417. OCALLOC(ms, ms_ocall_sock_accept_t *, sizeof(*ms));
  418. ms->ms_sockfd = sockfd;
  419. ms->ms_addr = COPY_TO_USER(addr, len);
  420. ms->ms_addrlen = len;
  421. retval = SGX_OCALL(OCALL_SOCK_ACCEPT, ms);
  422. if (retval >= 0) {
  423. if (len && (sgx_is_within_enclave(ms->ms_addr, len) ||
  424. ms->ms_addrlen > len)) {
  425. OCALL_EXIT();
  426. return -PAL_ERROR_DENIED;
  427. }
  428. if (addr) {
  429. COPY_FROM_USER(addr, ms->ms_addr, ms->ms_addrlen);
  430. *addrlen = ms->ms_addrlen;
  431. }
  432. if (sockopt)
  433. *sockopt = ms->ms_sockopt;
  434. }
  435. OCALL_EXIT();
  436. return retval;
  437. }
  438. int ocall_sock_connect (int domain, int type, int protocol,
  439. const struct sockaddr * addr,
  440. unsigned int addrlen,
  441. struct sockaddr * bind_addr,
  442. unsigned int * bind_addrlen, struct sockopt * sockopt)
  443. {
  444. int retval = 0;
  445. unsigned int bind_len = bind_addrlen ? *bind_addrlen : 0;
  446. ms_ocall_sock_connect_t * ms;
  447. OCALLOC(ms, ms_ocall_sock_connect_t *, sizeof(*ms));
  448. ms->ms_domain = domain;
  449. ms->ms_type = type;
  450. ms->ms_protocol = protocol;
  451. ms->ms_addr = COPY_TO_USER(addr, addrlen);
  452. ms->ms_addrlen = addrlen;
  453. ms->ms_bind_addr = bind_addr ? COPY_TO_USER(bind_addr, bind_len) : NULL;
  454. ms->ms_bind_addrlen = bind_len;
  455. retval = SGX_OCALL(OCALL_SOCK_CONNECT, ms);
  456. if (retval >= 0) {
  457. if (bind_len && (
  458. sgx_is_within_enclave(ms->ms_bind_addr, bind_len) ||
  459. ms->ms_bind_addrlen > bind_len)) {
  460. OCALL_EXIT();
  461. return -PAL_ERROR_DENIED;
  462. }
  463. if (bind_addr) {
  464. COPY_FROM_USER(bind_addr, ms->ms_bind_addr,
  465. ms->ms_bind_addrlen);
  466. *bind_addrlen = ms->ms_bind_addrlen;
  467. }
  468. if (sockopt)
  469. *sockopt = ms->ms_sockopt;
  470. }
  471. OCALL_EXIT();
  472. return retval;
  473. }
  474. int ocall_sock_recv (int sockfd, void * buf, unsigned int count,
  475. struct sockaddr * addr, unsigned int * addrlen)
  476. {
  477. int retval = 0;
  478. unsigned int len = addrlen ? *addrlen : 0;
  479. ms_ocall_sock_recv_t * ms;
  480. OCALLOC(ms, ms_ocall_sock_recv_t *, sizeof(*ms));
  481. ms->ms_sockfd = sockfd;
  482. ms->ms_buf = ALLOC_IN_USER(buf, count);
  483. ms->ms_count = count;
  484. ms->ms_addr = addr ? ALLOC_IN_USER(addr, len) : NULL;
  485. ms->ms_addrlen = len;
  486. retval = SGX_OCALL(OCALL_SOCK_RECV, ms);
  487. if (retval >= 0) {
  488. if (len && (sgx_is_within_enclave(ms->ms_addr, len) ||
  489. ms->ms_addrlen > len)) {
  490. OCALL_EXIT();
  491. return -PAL_ERROR_DENIED;
  492. }
  493. COPY_FROM_USER(buf, ms->ms_buf, retval);
  494. COPY_FROM_USER(addr, ms->ms_addr, ms->ms_addrlen);
  495. if (addrlen)
  496. *addrlen = ms->ms_addrlen;
  497. }
  498. OCALL_EXIT();
  499. return retval;
  500. }
  501. int ocall_sock_send (int sockfd, const void * buf, unsigned int count,
  502. const struct sockaddr * addr, unsigned int addrlen)
  503. {
  504. int retval = 0;
  505. ms_ocall_sock_send_t * ms;
  506. OCALLOC(ms, ms_ocall_sock_send_t *, sizeof(*ms));
  507. ms->ms_sockfd = sockfd;
  508. ms->ms_buf = COPY_TO_USER(buf, count);
  509. ms->ms_count = count;
  510. ms->ms_addr = addr ? COPY_TO_USER(addr, addrlen) : NULL;
  511. ms->ms_addrlen = addrlen;
  512. retval = SGX_OCALL(OCALL_SOCK_SEND, ms);
  513. OCALL_EXIT();
  514. return retval;
  515. }
  516. int ocall_sock_recv_fd (int sockfd, void * buf, unsigned int count,
  517. unsigned int * fds, unsigned int * nfds)
  518. {
  519. int retval = 0;
  520. ms_ocall_sock_recv_fd_t * ms;
  521. OCALLOC(ms, ms_ocall_sock_recv_fd_t *, sizeof(*ms));
  522. ms->ms_sockfd = sockfd;
  523. ms->ms_buf = ALLOC_IN_USER(buf, count);
  524. ms->ms_count = count;
  525. ms->ms_fds = fds ? ALLOC_IN_USER(fds, sizeof(int) * (*nfds)) : NULL;
  526. ms->ms_nfds = *nfds;
  527. retval = SGX_OCALL(OCALL_SOCK_RECV_FD, ms);
  528. if (retval >= 0) {
  529. if (sgx_is_within_enclave(ms->ms_fds, sizeof(int) * (*nfds)) ||
  530. ms->ms_nfds > (*nfds)) {
  531. OCALL_EXIT();
  532. return -PAL_ERROR_DENIED;
  533. }
  534. COPY_FROM_USER(buf, ms->ms_buf, retval);
  535. COPY_FROM_USER(fds, ms->ms_fds, sizeof(int) * ms->ms_nfds);
  536. *nfds = ms->ms_nfds;
  537. }
  538. OCALL_EXIT();
  539. return retval;
  540. }
  541. int ocall_sock_send_fd (int sockfd, const void * buf, unsigned int count,
  542. const unsigned int * fds, unsigned int nfds)
  543. {
  544. int retval = 0;
  545. ms_ocall_sock_send_fd_t * ms;
  546. OCALLOC(ms, ms_ocall_sock_send_fd_t *, sizeof(*ms));
  547. ms->ms_sockfd = sockfd;
  548. ms->ms_buf = COPY_TO_USER(buf, count);
  549. ms->ms_count = count;
  550. ms->ms_fds = fds ? COPY_TO_USER(fds, sizeof(int) * nfds) : NULL;
  551. ms->ms_nfds = nfds;
  552. retval = SGX_OCALL(OCALL_SOCK_SEND_FD, ms);
  553. OCALL_EXIT();
  554. return retval;
  555. }
  556. int ocall_sock_setopt (int sockfd, int level, int optname,
  557. const void * optval, unsigned int optlen)
  558. {
  559. int retval = 0;
  560. ms_ocall_sock_setopt_t * ms;
  561. OCALLOC(ms, ms_ocall_sock_setopt_t *, sizeof(*ms));
  562. ms->ms_sockfd = sockfd;
  563. ms->ms_level = level;
  564. ms->ms_optname = optname;
  565. ms->ms_optval = COPY_TO_USER(optval, optlen);
  566. ms->ms_optlen = optlen;
  567. retval = SGX_OCALL(OCALL_SOCK_SETOPT, ms);
  568. OCALL_EXIT();
  569. return retval;
  570. }
  571. int ocall_sock_shutdown (int sockfd, int how)
  572. {
  573. int retval = 0;
  574. ms_ocall_sock_shutdown_t * ms;
  575. OCALLOC(ms, ms_ocall_sock_shutdown_t *, sizeof(*ms));
  576. ms->ms_sockfd = sockfd;
  577. ms->ms_how = how;
  578. retval = SGX_OCALL(OCALL_SOCK_SHUTDOWN, ms);
  579. OCALL_EXIT();
  580. return retval;
  581. }
  582. int ocall_gettime (unsigned long * microsec)
  583. {
  584. int retval = 0;
  585. ms_ocall_gettime_t * ms;
  586. OCALLOC(ms, ms_ocall_gettime_t *, sizeof(*ms));
  587. retval = SGX_OCALL(OCALL_GETTIME, ms);
  588. if (!retval)
  589. *microsec = ms->ms_microsec;
  590. OCALL_EXIT();
  591. return retval;
  592. }
  593. int ocall_sleep (unsigned long * microsec)
  594. {
  595. int retval = 0;
  596. ms_ocall_sleep_t * ms;
  597. OCALLOC(ms, ms_ocall_sleep_t *, sizeof(*ms));
  598. ms->ms_microsec = microsec ? *microsec : 0;
  599. retval = SGX_OCALL(OCALL_SLEEP, ms);
  600. if (microsec) {
  601. if (!retval)
  602. *microsec = 0;
  603. else if (retval == -EINTR)
  604. *microsec = ms->ms_microsec;
  605. }
  606. OCALL_EXIT();
  607. return retval;
  608. }
  609. int ocall_poll (struct pollfd * fds, int nfds, uint64_t * timeout)
  610. {
  611. int retval = 0;
  612. ms_ocall_poll_t * ms;
  613. OCALLOC(ms, ms_ocall_poll_t *, sizeof(*ms));
  614. ms->ms_fds = COPY_TO_USER(fds, sizeof(struct pollfd) * nfds);
  615. ms->ms_nfds = nfds;
  616. ms->ms_timeout = timeout ? *timeout : OCALL_NO_TIMEOUT;
  617. retval = SGX_OCALL(OCALL_POLL, ms);
  618. if (retval == -EINTR && timeout)
  619. *timeout = ms->ms_timeout;
  620. if (retval >= 0)
  621. COPY_FROM_USER(fds, ms->ms_fds, sizeof(struct pollfd) * nfds);
  622. OCALL_EXIT();
  623. return retval;
  624. }
  625. int ocall_rename (const char * oldpath, const char * newpath)
  626. {
  627. int retval = 0;
  628. int oldlen = oldpath ? strlen(oldpath) + 1 : 0;
  629. int newlen = newpath ? strlen(newpath) + 1 : 0;
  630. ms_ocall_rename_t * ms;
  631. OCALLOC(ms, ms_ocall_rename_t *, sizeof(*ms));
  632. ms->ms_oldpath = COPY_TO_USER(oldpath, oldlen);
  633. ms->ms_newpath = COPY_TO_USER(newpath, newlen);
  634. retval = SGX_OCALL(OCALL_RENAME, ms);
  635. OCALL_EXIT();
  636. return retval;
  637. }
  638. int ocall_delete (const char * pathname)
  639. {
  640. int retval = 0;
  641. int len = pathname ? strlen(pathname) + 1 : 0;
  642. ms_ocall_delete_t * ms;
  643. OCALLOC(ms, ms_ocall_delete_t *, sizeof(*ms));
  644. ms->ms_pathname = COPY_TO_USER(pathname, len);
  645. retval = SGX_OCALL(OCALL_DELETE, ms);
  646. OCALL_EXIT();
  647. return retval;
  648. }
  649. int ocall_load_debug(const char * command)
  650. {
  651. int retval = 0;
  652. int len = strlen(command);
  653. const char * ms = COPY_TO_USER(command, len + 1);
  654. retval = SGX_OCALL(OCALL_LOAD_DEBUG, (void *) ms);
  655. OCALL_EXIT();
  656. return retval;
  657. }