enclave_ocalls.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778
  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. #define OCALL_EXIT() \
  25. do { \
  26. sgx_ocfree(); \
  27. } while (0)
  28. #define ALLOC_IN_USER(var, size) \
  29. ({ \
  30. typeof(var) tmp = var; \
  31. if (sgx_is_within_enclave(var, size)) { \
  32. OCALLOC(tmp, typeof(tmp), size); \
  33. }; tmp; \
  34. })
  35. #define COPY_TO_USER(var, size) \
  36. ({ \
  37. typeof(var) tmp = var; \
  38. if (sgx_is_within_enclave(var, size)) { \
  39. OCALLOC(tmp, typeof(tmp), size); \
  40. memcpy((void *) tmp, var, 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 (unsigned int 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, unsigned int 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. const struct sockaddr * addr, unsigned int addrlen,
  382. struct sockopt * sockopt)
  383. {
  384. int retval = 0;
  385. ms_ocall_sock_listen_t * ms;
  386. OCALLOC(ms, ms_ocall_sock_listen_t *, sizeof(*ms));
  387. ms->ms_domain = domain;
  388. ms->ms_type = type;
  389. ms->ms_protocol = protocol;
  390. ms->ms_addr = COPY_TO_USER(addr, addrlen);
  391. ms->ms_addrlen = addrlen;
  392. retval = SGX_OCALL(OCALL_SOCK_LISTEN, ms);
  393. if (retval >= 0)
  394. *sockopt = ms->ms_sockopt;
  395. OCALL_EXIT();
  396. return retval;
  397. }
  398. int ocall_sock_accept (int sockfd, struct sockaddr * addr,
  399. unsigned int * addrlen, struct sockopt * sockopt)
  400. {
  401. int retval = 0;
  402. unsigned int len = addrlen ? *addrlen : 0;
  403. ms_ocall_sock_accept_t * ms;
  404. OCALLOC(ms, ms_ocall_sock_accept_t *, sizeof(*ms));
  405. ms->ms_sockfd = sockfd;
  406. ms->ms_addr = COPY_TO_USER(addr, len);
  407. ms->ms_addrlen = len;
  408. retval = SGX_OCALL(OCALL_SOCK_ACCEPT, ms);
  409. if (retval >= 0) {
  410. if (len && (sgx_is_within_enclave(ms->ms_addr, len) ||
  411. ms->ms_addrlen > len)) {
  412. OCALL_EXIT();
  413. return -PAL_ERROR_DENIED;
  414. }
  415. if (addr) {
  416. COPY_FROM_USER(addr, ms->ms_addr, ms->ms_addrlen);
  417. *addrlen = ms->ms_addrlen;
  418. }
  419. if (sockopt)
  420. *sockopt = ms->ms_sockopt;
  421. }
  422. OCALL_EXIT();
  423. return retval;
  424. }
  425. int ocall_sock_connect (int domain, int type, int protocol,
  426. const struct sockaddr * addr,
  427. unsigned int addrlen,
  428. struct sockaddr * bind_addr,
  429. unsigned int * bind_addrlen, struct sockopt * sockopt)
  430. {
  431. int retval = 0;
  432. unsigned int bind_len = bind_addrlen ? *bind_addrlen : 0;
  433. ms_ocall_sock_connect_t * ms;
  434. OCALLOC(ms, ms_ocall_sock_connect_t *, sizeof(*ms));
  435. ms->ms_domain = domain;
  436. ms->ms_type = type;
  437. ms->ms_protocol = protocol;
  438. ms->ms_addr = COPY_TO_USER(addr, addrlen);
  439. ms->ms_addrlen = addrlen;
  440. ms->ms_bind_addr = bind_addr ? COPY_TO_USER(bind_addr, bind_len) : NULL;
  441. ms->ms_bind_addrlen = bind_len;
  442. retval = SGX_OCALL(OCALL_SOCK_CONNECT, ms);
  443. if (retval >= 0) {
  444. if (bind_len && (
  445. sgx_is_within_enclave(ms->ms_bind_addr, bind_len) ||
  446. ms->ms_bind_addrlen > bind_len)) {
  447. OCALL_EXIT();
  448. return -PAL_ERROR_DENIED;
  449. }
  450. if (bind_addr) {
  451. COPY_FROM_USER(bind_addr, ms->ms_bind_addr,
  452. ms->ms_bind_addrlen);
  453. *bind_addrlen = ms->ms_bind_addrlen;
  454. }
  455. if (sockopt)
  456. *sockopt = ms->ms_sockopt;
  457. }
  458. OCALL_EXIT();
  459. return retval;
  460. }
  461. int ocall_sock_recv (int sockfd, void * buf, unsigned int count,
  462. struct sockaddr * addr, unsigned int * addrlen)
  463. {
  464. int retval = 0;
  465. unsigned int len = addrlen ? *addrlen : 0;
  466. ms_ocall_sock_recv_t * ms;
  467. OCALLOC(ms, ms_ocall_sock_recv_t *, sizeof(*ms));
  468. ms->ms_sockfd = sockfd;
  469. ms->ms_buf = ALLOC_IN_USER(buf, count);
  470. ms->ms_count = count;
  471. ms->ms_addr = addr ? ALLOC_IN_USER(addr, len) : NULL;
  472. ms->ms_addrlen = len;
  473. retval = SGX_OCALL(OCALL_SOCK_RECV, ms);
  474. if (retval >= 0) {
  475. if (len && (sgx_is_within_enclave(ms->ms_addr, len) ||
  476. ms->ms_addrlen > len)) {
  477. OCALL_EXIT();
  478. return -PAL_ERROR_DENIED;
  479. }
  480. COPY_FROM_USER(buf, ms->ms_buf, retval);
  481. COPY_FROM_USER(addr, ms->ms_addr, ms->ms_addrlen);
  482. if (addrlen)
  483. *addrlen = ms->ms_addrlen;
  484. }
  485. OCALL_EXIT();
  486. return retval;
  487. }
  488. int ocall_sock_send (int sockfd, const void * buf, unsigned int count,
  489. const struct sockaddr * addr, unsigned int addrlen)
  490. {
  491. int retval = 0;
  492. ms_ocall_sock_send_t * ms;
  493. OCALLOC(ms, ms_ocall_sock_send_t *, sizeof(*ms));
  494. ms->ms_sockfd = sockfd;
  495. ms->ms_buf = COPY_TO_USER(buf, count);
  496. ms->ms_count = count;
  497. ms->ms_addr = addr ? COPY_TO_USER(addr, addrlen) : NULL;
  498. ms->ms_addrlen = addrlen;
  499. retval = SGX_OCALL(OCALL_SOCK_SEND, ms);
  500. OCALL_EXIT();
  501. return retval;
  502. }
  503. int ocall_sock_recv_fd (int sockfd, void * buf, unsigned int count,
  504. unsigned int * fds, unsigned int * nfds)
  505. {
  506. int retval = 0;
  507. ms_ocall_sock_recv_fd_t * ms;
  508. OCALLOC(ms, ms_ocall_sock_recv_fd_t *, sizeof(*ms));
  509. ms->ms_sockfd = sockfd;
  510. ms->ms_buf = ALLOC_IN_USER(buf, count);
  511. ms->ms_count = count;
  512. ms->ms_fds = fds ? ALLOC_IN_USER(fds, sizeof(int) * (*nfds)) : NULL;
  513. ms->ms_nfds = *nfds;
  514. retval = SGX_OCALL(OCALL_SOCK_RECV_FD, ms);
  515. if (retval >= 0) {
  516. if (sgx_is_within_enclave(ms->ms_fds, sizeof(int) * (*nfds)) ||
  517. ms->ms_nfds > (*nfds)) {
  518. OCALL_EXIT();
  519. return -PAL_ERROR_DENIED;
  520. }
  521. COPY_FROM_USER(buf, ms->ms_buf, retval);
  522. COPY_FROM_USER(fds, ms->ms_fds, sizeof(int) * ms->ms_nfds);
  523. *nfds = ms->ms_nfds;
  524. }
  525. OCALL_EXIT();
  526. return retval;
  527. }
  528. int ocall_sock_send_fd (int sockfd, const void * buf, unsigned int count,
  529. const unsigned int * fds, unsigned int nfds)
  530. {
  531. int retval = 0;
  532. ms_ocall_sock_send_fd_t * ms;
  533. OCALLOC(ms, ms_ocall_sock_send_fd_t *, sizeof(*ms));
  534. ms->ms_sockfd = sockfd;
  535. ms->ms_buf = COPY_TO_USER(buf, count);
  536. ms->ms_count = count;
  537. ms->ms_fds = fds ? COPY_TO_USER(fds, sizeof(int) * nfds) : NULL;
  538. ms->ms_nfds = nfds;
  539. retval = SGX_OCALL(OCALL_SOCK_SEND_FD, ms);
  540. OCALL_EXIT();
  541. return retval;
  542. }
  543. int ocall_sock_setopt (int sockfd, int level, int optname,
  544. const void * optval, unsigned int optlen)
  545. {
  546. int retval = 0;
  547. ms_ocall_sock_setopt_t * ms;
  548. OCALLOC(ms, ms_ocall_sock_setopt_t *, sizeof(*ms));
  549. ms->ms_sockfd = sockfd;
  550. ms->ms_level = level;
  551. ms->ms_optname = optname;
  552. ms->ms_optval = COPY_TO_USER(optval, optlen);
  553. ms->ms_optlen = optlen;
  554. retval = SGX_OCALL(OCALL_SOCK_SETOPT, ms);
  555. OCALL_EXIT();
  556. return retval;
  557. }
  558. int ocall_sock_shutdown (int sockfd, int how)
  559. {
  560. int retval = 0;
  561. ms_ocall_sock_shutdown_t * ms;
  562. OCALLOC(ms, ms_ocall_sock_shutdown_t *, sizeof(*ms));
  563. ms->ms_sockfd = sockfd;
  564. ms->ms_how = how;
  565. retval = SGX_OCALL(OCALL_SOCK_SHUTDOWN, ms);
  566. OCALL_EXIT();
  567. return retval;
  568. }
  569. int ocall_gettime (unsigned long * microsec)
  570. {
  571. int retval = 0;
  572. ms_ocall_gettime_t * ms;
  573. OCALLOC(ms, ms_ocall_gettime_t *, sizeof(*ms));
  574. retval = SGX_OCALL(OCALL_GETTIME, ms);
  575. if (!retval)
  576. *microsec = ms->ms_microsec;
  577. OCALL_EXIT();
  578. return retval;
  579. }
  580. int ocall_sleep (unsigned long * microsec)
  581. {
  582. int retval = 0;
  583. ms_ocall_sleep_t * ms;
  584. OCALLOC(ms, ms_ocall_sleep_t *, sizeof(*ms));
  585. ms->ms_microsec = microsec ? *microsec : 0;
  586. retval = SGX_OCALL(OCALL_SLEEP, ms);
  587. if (microsec) {
  588. if (!retval)
  589. *microsec = 0;
  590. else if (retval == -EINTR)
  591. *microsec = ms->ms_microsec;
  592. }
  593. OCALL_EXIT();
  594. return retval;
  595. }
  596. int ocall_poll (struct pollfd * fds, int nfds, uint64_t * timeout)
  597. {
  598. int retval = 0;
  599. ms_ocall_poll_t * ms;
  600. OCALLOC(ms, ms_ocall_poll_t *, sizeof(*ms));
  601. ms->ms_fds = COPY_TO_USER(fds, sizeof(struct pollfd) * nfds);
  602. ms->ms_nfds = nfds;
  603. ms->ms_timeout = timeout ? *timeout : OCALL_NO_TIMEOUT;
  604. retval = SGX_OCALL(OCALL_POLL, ms);
  605. if (retval == -EINTR && timeout)
  606. *timeout = ms->ms_timeout;
  607. if (retval >= 0)
  608. COPY_FROM_USER(fds, ms->ms_fds, sizeof(struct pollfd) * nfds);
  609. OCALL_EXIT();
  610. return retval;
  611. }
  612. int ocall_rename (const char * oldpath, const char * newpath)
  613. {
  614. int retval = 0;
  615. int oldlen = oldpath ? strlen(oldpath) + 1 : 0;
  616. int newlen = newpath ? strlen(newpath) + 1 : 0;
  617. ms_ocall_rename_t * ms;
  618. OCALLOC(ms, ms_ocall_rename_t *, sizeof(*ms));
  619. ms->ms_oldpath = COPY_TO_USER(oldpath, oldlen);
  620. ms->ms_newpath = COPY_TO_USER(newpath, newlen);
  621. retval = SGX_OCALL(OCALL_RENAME, ms);
  622. OCALL_EXIT();
  623. return retval;
  624. }
  625. int ocall_delete (const char * pathname)
  626. {
  627. int retval = 0;
  628. int len = pathname ? strlen(pathname) + 1 : 0;
  629. ms_ocall_delete_t * ms;
  630. OCALLOC(ms, ms_ocall_delete_t *, sizeof(*ms));
  631. ms->ms_pathname = COPY_TO_USER(pathname, len);
  632. retval = SGX_OCALL(OCALL_DELETE, ms);
  633. OCALL_EXIT();
  634. return retval;
  635. }
  636. int ocall_load_debug(const char * command)
  637. {
  638. int retval = 0;
  639. int len = strlen(command);
  640. const char * ms = COPY_TO_USER(command, len + 1);
  641. retval = SGX_OCALL(OCALL_LOAD_DEBUG, (void *) ms);
  642. OCALL_EXIT();
  643. return retval;
  644. }