enclave_ocalls.c 21 KB

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