sgx_socket.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "platform_api_vmcore.h"
  6. #include "platform_api_extension.h"
  7. #ifndef SGX_DISABLE_WASI
  8. #define TRACE_OCALL_FAIL() os_printf("ocall %s failed!\n", __FUNCTION__)
  9. /** OCALLs prototypes **/
  10. int
  11. ocall_accept(int *p_ret, int sockfd, void *addr, uint32_t *addrlen,
  12. uint32_t addr_size);
  13. int
  14. ocall_bind(int *p_ret, int sockfd, const void *addr, uint32_t addrlen);
  15. int
  16. ocall_close(int *p_ret, int fd);
  17. int
  18. ocall_connect(int *p_ret, int sockfd, void *addr, uint32_t addrlen);
  19. int
  20. ocall_fcntl_long(int *p_ret, int fd, int cmd, long arg);
  21. int
  22. ocall_getsockname(int *p_ret, int sockfd, void *addr, uint32_t *addrlen,
  23. uint32_t addr_size);
  24. int
  25. ocall_getsockopt(int *p_ret, int sockfd, int level, int optname, void *val_buf,
  26. unsigned int val_buf_size, void *len_buf);
  27. int
  28. ocall_listen(int *p_ret, int sockfd, int backlog);
  29. int
  30. ocall_recv(int *p_ret, int sockfd, void *buf, size_t len, int flags);
  31. int
  32. ocall_recvmsg(ssize_t *p_ret, int sockfd, void *msg_buf,
  33. unsigned int msg_buf_size, int flags);
  34. int
  35. ocall_send(int *p_ret, int sockfd, const void *buf, size_t len, int flags);
  36. int
  37. ocall_sendmsg(ssize_t *p_ret, int sockfd, void *msg_buf,
  38. unsigned int msg_buf_size, int flags);
  39. int
  40. ocall_setsockopt(int *p_ret, int sockfd, int level, int optname, void *optval,
  41. unsigned int optlen);
  42. int
  43. ocall_shutdown(int *p_ret, int sockfd, int how);
  44. int
  45. ocall_socket(int *p_ret, int domain, int type, int protocol);
  46. /** OCALLs prototypes end **/
  47. /** In-enclave implementation of POSIX functions **/
  48. static bool
  49. is_little_endian()
  50. {
  51. long i = 0x01020304;
  52. unsigned char *c = (unsigned char *)&i;
  53. return (*c == 0x04) ? true : false;
  54. }
  55. static void
  56. swap32(uint8 *pData)
  57. {
  58. uint8 value = *pData;
  59. *pData = *(pData + 3);
  60. *(pData + 3) = value;
  61. value = *(pData + 1);
  62. *(pData + 1) = *(pData + 2);
  63. *(pData + 2) = value;
  64. }
  65. static void
  66. swap16(uint8 *pData)
  67. {
  68. uint8 value = *pData;
  69. *(pData) = *(pData + 1);
  70. *(pData + 1) = value;
  71. }
  72. uint32
  73. htonl(uint32 value)
  74. {
  75. uint32 ret;
  76. if (is_little_endian()) {
  77. ret = value;
  78. swap32((uint8 *)&ret);
  79. return ret;
  80. }
  81. return value;
  82. }
  83. uint32
  84. ntohl(uint32 value)
  85. {
  86. return htonl(value);
  87. }
  88. uint16
  89. htons(uint16 value)
  90. {
  91. uint16 ret;
  92. if (is_little_endian()) {
  93. ret = value;
  94. swap16((uint8 *)&ret);
  95. return ret;
  96. }
  97. return value;
  98. }
  99. static uint16
  100. ntohs(uint16 value)
  101. {
  102. return htons(value);
  103. }
  104. /* Coming from musl, under MIT license */
  105. static int
  106. hexval(unsigned c)
  107. {
  108. if (c - '0' < 10)
  109. return c - '0';
  110. c |= 32;
  111. if (c - 'a' < 6)
  112. return c - 'a' + 10;
  113. return -1;
  114. }
  115. /* Coming from musl, under MIT license */
  116. static int
  117. inet_pton(int af, const char *restrict s, void *restrict a0)
  118. {
  119. uint16_t ip[8];
  120. unsigned char *a = a0;
  121. int i, j, v, d, brk = -1, need_v4 = 0;
  122. if (af == AF_INET) {
  123. for (i = 0; i < 4; i++) {
  124. for (v = j = 0; j < 3 && isdigit(s[j]); j++)
  125. v = 10 * v + s[j] - '0';
  126. if (j == 0 || (j > 1 && s[0] == '0') || v > 255)
  127. return 0;
  128. a[i] = v;
  129. if (s[j] == 0 && i == 3)
  130. return 1;
  131. if (s[j] != '.')
  132. return 0;
  133. s += j + 1;
  134. }
  135. return 0;
  136. }
  137. else if (af != AF_INET6) {
  138. errno = EAFNOSUPPORT;
  139. return -1;
  140. }
  141. if (*s == ':' && *++s != ':')
  142. return 0;
  143. for (i = 0;; i++) {
  144. if (s[0] == ':' && brk < 0) {
  145. brk = i;
  146. ip[i & 7] = 0;
  147. if (!*++s)
  148. break;
  149. if (i == 7)
  150. return 0;
  151. continue;
  152. }
  153. for (v = j = 0; j < 4 && (d = hexval(s[j])) >= 0; j++)
  154. v = 16 * v + d;
  155. if (j == 0)
  156. return 0;
  157. ip[i & 7] = v;
  158. if (!s[j] && (brk >= 0 || i == 7))
  159. break;
  160. if (i == 7)
  161. return 0;
  162. if (s[j] != ':') {
  163. if (s[j] != '.' || (i < 6 && brk < 0))
  164. return 0;
  165. need_v4 = 1;
  166. i++;
  167. break;
  168. }
  169. s += j + 1;
  170. }
  171. if (brk >= 0) {
  172. memmove(ip + brk + 7 - i, ip + brk, 2 * (i + 1 - brk));
  173. for (j = 0; j < 7 - i; j++)
  174. ip[brk + j] = 0;
  175. }
  176. for (j = 0; j < 8; j++) {
  177. *a++ = ip[j] >> 8;
  178. *a++ = ip[j];
  179. }
  180. if (need_v4 && inet_pton(AF_INET, (void *)s, a - 4) <= 0)
  181. return 0;
  182. return 1;
  183. }
  184. static int
  185. inet_addr(const char *p)
  186. {
  187. struct in_addr a;
  188. if (!inet_pton(AF_INET, p, &a))
  189. return -1;
  190. return a.s_addr;
  191. }
  192. /** In-enclave implementation of POSIX functions end **/
  193. static int
  194. textual_addr_to_sockaddr(const char *textual, int port, struct sockaddr_in *out)
  195. {
  196. assert(textual);
  197. out->sin_family = AF_INET;
  198. out->sin_port = htons(port);
  199. out->sin_addr.s_addr = inet_addr(textual);
  200. return BHT_OK;
  201. }
  202. int
  203. socket(int domain, int type, int protocol)
  204. {
  205. int ret;
  206. if (ocall_socket(&ret, domain, type, protocol) != SGX_SUCCESS) {
  207. TRACE_OCALL_FAIL();
  208. return -1;
  209. }
  210. if (ret == -1)
  211. errno = get_errno();
  212. return ret;
  213. }
  214. int
  215. getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen)
  216. {
  217. int ret;
  218. unsigned int val_buf_size = *optlen;
  219. if (ocall_getsockopt(&ret, sockfd, level, optname, optval, val_buf_size,
  220. (void *)optlen)
  221. != SGX_SUCCESS) {
  222. TRACE_OCALL_FAIL();
  223. return -1;
  224. }
  225. if (ret == -1)
  226. errno = get_errno();
  227. return ret;
  228. }
  229. ssize_t
  230. sendmsg(int sockfd, const struct msghdr *msg, int flags)
  231. {
  232. ssize_t ret;
  233. int i;
  234. char *p;
  235. struct msghdr *msg1;
  236. uint64 total_size = sizeof(struct msghdr) + (uint64)msg->msg_namelen
  237. + (uint64)msg->msg_controllen;
  238. total_size += sizeof(struct iovec) * (msg->msg_iovlen);
  239. for (i = 0; i < msg->msg_iovlen; i++) {
  240. total_size += msg->msg_iov[i].iov_len;
  241. }
  242. if (total_size >= UINT32_MAX)
  243. return -1;
  244. msg1 = BH_MALLOC((uint32)total_size);
  245. if (msg1 == NULL)
  246. return -1;
  247. p = (char *)(uintptr_t)sizeof(struct msghdr);
  248. if (msg->msg_name != NULL) {
  249. msg1->msg_name = p;
  250. memcpy((uintptr_t)p + (char *)msg1, msg->msg_name,
  251. (size_t)msg->msg_namelen);
  252. p += msg->msg_namelen;
  253. }
  254. if (msg->msg_control != NULL) {
  255. msg1->msg_control = p;
  256. memcpy((uintptr_t)p + (char *)msg1, msg->msg_control,
  257. (size_t)msg->msg_control);
  258. p += msg->msg_controllen;
  259. }
  260. if (msg->msg_iov != NULL) {
  261. msg1->msg_iov = (struct iovec *)p;
  262. p += (uintptr_t)(sizeof(struct iovec) * (msg->msg_iovlen));
  263. for (i = 0; i < msg->msg_iovlen; i++) {
  264. msg1->msg_iov[i].iov_base = p;
  265. msg1->msg_iov[i].iov_len = msg->msg_iov[i].iov_len;
  266. memcpy((uintptr_t)p + (char *)msg1, msg->msg_iov[i].iov_base,
  267. (size_t)(msg->msg_iov[i].iov_len));
  268. p += msg->msg_iov[i].iov_len;
  269. }
  270. }
  271. if (ocall_sendmsg(&ret, sockfd, (void *)msg1, (uint32)total_size, flags)
  272. != SGX_SUCCESS) {
  273. TRACE_OCALL_FAIL();
  274. return -1;
  275. }
  276. if (ret == -1)
  277. errno = get_errno();
  278. return ret;
  279. }
  280. ssize_t
  281. recvmsg(int sockfd, struct msghdr *msg, int flags)
  282. {
  283. ssize_t ret;
  284. int i;
  285. char *p;
  286. struct msghdr *msg1;
  287. uint64 total_size = sizeof(struct msghdr) + (uint64)msg->msg_namelen
  288. + (uint64)msg->msg_controllen;
  289. total_size += sizeof(struct iovec) * (msg->msg_iovlen);
  290. for (i = 0; i < msg->msg_iovlen; i++) {
  291. total_size += msg->msg_iov[i].iov_len;
  292. }
  293. if (total_size >= UINT32_MAX)
  294. return -1;
  295. msg1 = BH_MALLOC((uint32)total_size);
  296. if (msg1 == NULL)
  297. return -1;
  298. memset(msg1, 0, total_size);
  299. p = (char *)(uintptr_t)sizeof(struct msghdr);
  300. if (msg->msg_name != NULL) {
  301. msg1->msg_name = p;
  302. p += msg->msg_namelen;
  303. }
  304. if (msg->msg_control != NULL) {
  305. msg1->msg_control = p;
  306. p += msg->msg_controllen;
  307. }
  308. if (msg->msg_iov != NULL) {
  309. msg1->msg_iov = (struct iovec *)p;
  310. p += (uintptr_t)(sizeof(struct iovec) * (msg->msg_iovlen));
  311. for (i = 0; i < msg->msg_iovlen; i++) {
  312. msg1->msg_iov[i].iov_base = p;
  313. msg1->msg_iov[i].iov_len = msg->msg_iov[i].iov_len;
  314. p += msg->msg_iov[i].iov_len;
  315. }
  316. }
  317. if (ocall_recvmsg(&ret, sockfd, (void *)msg1, (uint32)total_size, flags)
  318. != SGX_SUCCESS) {
  319. TRACE_OCALL_FAIL();
  320. return -1;
  321. }
  322. p = (char *)(uintptr_t)(sizeof(struct msghdr));
  323. if (msg1->msg_name != NULL) {
  324. memcpy(msg->msg_name, (uintptr_t)p + (char *)msg1,
  325. (size_t)msg1->msg_namelen);
  326. p += msg1->msg_namelen;
  327. }
  328. if (msg1->msg_control != NULL) {
  329. memcpy(msg->msg_control, (uintptr_t)p + (char *)msg1,
  330. (size_t)msg1->msg_control);
  331. p += msg->msg_controllen;
  332. }
  333. if (msg1->msg_iov != NULL) {
  334. p += (uintptr_t)(sizeof(struct iovec) * (msg1->msg_iovlen));
  335. for (i = 0; i < msg1->msg_iovlen; i++) {
  336. memcpy(msg->msg_iov[i].iov_base, (uintptr_t)p + (char *)msg1,
  337. (size_t)(msg1->msg_iov[i].iov_len));
  338. p += msg1->msg_iov[i].iov_len;
  339. }
  340. }
  341. if (ret == -1)
  342. errno = get_errno();
  343. return ret;
  344. }
  345. int
  346. shutdown(int sockfd, int how)
  347. {
  348. int ret;
  349. if (ocall_shutdown(&ret, sockfd, how) != SGX_SUCCESS) {
  350. TRACE_OCALL_FAIL();
  351. return -1;
  352. }
  353. if (ret == -1)
  354. errno = get_errno();
  355. return ret;
  356. }
  357. int
  358. os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
  359. unsigned int *addrlen)
  360. {
  361. struct sockaddr addr_tmp;
  362. unsigned int len = sizeof(struct sockaddr);
  363. if (ocall_accept(sock, server_sock, &addr_tmp, &len, len) != SGX_SUCCESS) {
  364. TRACE_OCALL_FAIL();
  365. return -1;
  366. }
  367. if (*sock < 0) {
  368. errno = get_errno();
  369. return BHT_ERROR;
  370. }
  371. return BHT_OK;
  372. }
  373. int
  374. os_socket_bind(bh_socket_t socket, const char *host, int *port)
  375. {
  376. struct sockaddr_in addr;
  377. struct linger ling;
  378. unsigned int socklen;
  379. int ret;
  380. assert(host);
  381. assert(port);
  382. ling.l_onoff = 1;
  383. ling.l_linger = 0;
  384. if (ocall_fcntl_long(&ret, socket, F_SETFD, FD_CLOEXEC) != SGX_SUCCESS) {
  385. TRACE_OCALL_FAIL();
  386. return -1;
  387. }
  388. if (ret < 0) {
  389. goto fail;
  390. }
  391. if (ocall_setsockopt(&ret, socket, SOL_SOCKET, SO_LINGER, &ling,
  392. sizeof(ling))
  393. != SGX_SUCCESS) {
  394. TRACE_OCALL_FAIL();
  395. return -1;
  396. }
  397. if (ret < 0) {
  398. goto fail;
  399. }
  400. addr.sin_addr.s_addr = inet_addr(host);
  401. addr.sin_port = htons(*port);
  402. addr.sin_family = AF_INET;
  403. if (ocall_bind(&ret, socket, &addr, sizeof(addr)) != SGX_SUCCESS) {
  404. TRACE_OCALL_FAIL();
  405. return -1;
  406. }
  407. if (ret < 0) {
  408. goto fail;
  409. }
  410. socklen = sizeof(addr);
  411. if (ocall_getsockname(&ret, socket, (void *)&addr, &socklen, socklen)
  412. != SGX_SUCCESS) {
  413. TRACE_OCALL_FAIL();
  414. return -1;
  415. }
  416. if (ret == -1) {
  417. goto fail;
  418. }
  419. *port = ntohs(addr.sin_port);
  420. return BHT_OK;
  421. fail:
  422. errno = get_errno();
  423. return BHT_ERROR;
  424. }
  425. int
  426. os_socket_close(bh_socket_t socket)
  427. {
  428. int ret;
  429. if (ocall_close(&ret, socket) != SGX_SUCCESS) {
  430. TRACE_OCALL_FAIL();
  431. return -1;
  432. }
  433. if (ret == -1)
  434. errno = get_errno();
  435. return ret;
  436. }
  437. int
  438. os_socket_connect(bh_socket_t socket, const char *addr, int port)
  439. {
  440. struct sockaddr_in addr_in = { 0 };
  441. socklen_t addr_len = sizeof(struct sockaddr_in);
  442. int ret = 0;
  443. if ((ret = textual_addr_to_sockaddr(addr, port, &addr_in)) < 0) {
  444. return ret;
  445. }
  446. if (ocall_connect(&ret, socket, &addr_in, addr_len) != SGX_SUCCESS) {
  447. TRACE_OCALL_FAIL();
  448. return -1;
  449. }
  450. if (ret == -1)
  451. errno = get_errno();
  452. return ret;
  453. }
  454. int
  455. os_socket_create(bh_socket_t *sock, bool is_ipv4, bool is_tcp)
  456. {
  457. int af;
  458. if (!sock) {
  459. return BHT_ERROR;
  460. }
  461. if (is_ipv4) {
  462. af = AF_INET;
  463. }
  464. else {
  465. errno = ENOSYS;
  466. return BHT_ERROR;
  467. }
  468. if (is_tcp) {
  469. if (ocall_socket(sock, af, SOCK_STREAM, IPPROTO_TCP) != SGX_SUCCESS) {
  470. TRACE_OCALL_FAIL();
  471. return -1;
  472. }
  473. }
  474. else {
  475. if (ocall_socket(sock, af, SOCK_DGRAM, 0) != SGX_SUCCESS) {
  476. TRACE_OCALL_FAIL();
  477. return -1;
  478. }
  479. }
  480. if (*sock == -1) {
  481. errno = get_errno();
  482. return BHT_ERROR;
  483. }
  484. return BHT_OK;
  485. }
  486. int
  487. os_socket_inet_network(bool is_ipv4, const char *cp,
  488. bh_inet_network_output_t *out)
  489. {
  490. if (!cp)
  491. return BHT_ERROR;
  492. if (is_ipv4) {
  493. if (inet_pton(AF_INET, cp, &out->ipv4) != 1) {
  494. return BHT_ERROR;
  495. }
  496. /* Note: ntohl(INADDR_NONE) == INADDR_NONE */
  497. out->ipv4 = ntohl(out->ipv4);
  498. }
  499. else {
  500. if (inet_pton(AF_INET6, cp, out->ipv6) != 1) {
  501. return BHT_ERROR;
  502. }
  503. for (int i = 0; i < 8; i++) {
  504. out->ipv6[i] = ntohs(out->ipv6[i]);
  505. }
  506. }
  507. return BHT_OK;
  508. }
  509. int
  510. os_socket_listen(bh_socket_t socket, int max_client)
  511. {
  512. int ret;
  513. if (ocall_listen(&ret, socket, max_client) != SGX_SUCCESS) {
  514. TRACE_OCALL_FAIL();
  515. return -1;
  516. }
  517. if (ret == -1)
  518. errno = get_errno();
  519. return ret;
  520. }
  521. int
  522. os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
  523. {
  524. int ret;
  525. if (ocall_recv(&ret, socket, buf, len, 0) != SGX_SUCCESS) {
  526. errno = ENOSYS;
  527. return -1;
  528. }
  529. if (ret == -1)
  530. errno = get_errno();
  531. return ret;
  532. }
  533. int
  534. os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
  535. {
  536. int ret;
  537. if (ocall_send(&ret, socket, buf, len, 0) != SGX_SUCCESS) {
  538. errno = ENOSYS;
  539. return -1;
  540. }
  541. if (ret == -1)
  542. errno = get_errno();
  543. return ret;
  544. }
  545. int
  546. os_socket_shutdown(bh_socket_t socket)
  547. {
  548. return shutdown(socket, O_RDWR);
  549. }
  550. int
  551. os_socket_addr_resolve(const char *host, const char *service,
  552. uint8_t *hint_is_tcp, uint8_t *hint_is_ipv4,
  553. bh_addr_info_t *addr_info, size_t addr_info_size,
  554. size_t *max_info_size)
  555. {
  556. errno = ENOSYS;
  557. return BHT_ERROR;
  558. }
  559. int
  560. os_socket_addr_local(bh_socket_t socket, uint8_t *buf, size_t buflen,
  561. uint16_t *port, uint8_t *is_ipv4)
  562. {
  563. errno = ENOSYS;
  564. return BHT_ERROR;
  565. }
  566. int
  567. os_socket_addr_remote(bh_socket_t socket, uint8_t *buf, size_t buflen,
  568. uint16_t *port, uint8_t *is_ipv4)
  569. {
  570. errno = ENOSYS;
  571. return BHT_ERROR;
  572. }
  573. #endif