libc_wasi.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. /*
  2. * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include <stdio.h>
  6. #include "bh_platform.h"
  7. #include "wasm_export.h"
  8. typedef struct {
  9. const char *dir_list[8];
  10. uint32 dir_list_size;
  11. const char *map_dir_list[8];
  12. uint32 map_dir_list_size;
  13. const char *env_list[8];
  14. uint32 env_list_size;
  15. const char *addr_pool[8];
  16. uint32 addr_pool_size;
  17. const char *ns_lookup_pool[8];
  18. uint32 ns_lookup_pool_size;
  19. } libc_wasi_parse_context_t;
  20. typedef enum {
  21. LIBC_WASI_PARSE_RESULT_OK = 0,
  22. LIBC_WASI_PARSE_RESULT_NEED_HELP,
  23. LIBC_WASI_PARSE_RESULT_BAD_PARAM
  24. } libc_wasi_parse_result_t;
  25. static void
  26. libc_wasi_print_help(void)
  27. {
  28. printf(" --env=<env> Pass wasi environment variables with "
  29. "\"key=value\"\n");
  30. printf(" to the program, for example:\n");
  31. printf(" --env=\"key1=value1\" "
  32. "--env=\"key2=value2\"\n");
  33. printf(" --dir=<dir> Grant wasi access to the given host "
  34. "directories\n");
  35. printf(" to the program, for example:\n");
  36. printf(" --dir=<dir1> --dir=<dir2>\n");
  37. printf(" --map-dir=<guest::host> Grant wasi access to the given host "
  38. "directories\n");
  39. printf(" to the program at a specific guest "
  40. "path, for example:\n");
  41. printf(" --map-dir=<guest-path1::host-path1> "
  42. "--map-dir=<guest-path2::host-path2>\n");
  43. printf(" --addr-pool=<addrs> Grant wasi access to the given network "
  44. "addresses in\n");
  45. printf(" CIDR notation to the program, separated "
  46. "with ',',\n");
  47. printf(" for example:\n");
  48. printf(" --addr-pool=1.2.3.4/15,2.3.4.5/16\n");
  49. printf(" --allow-resolve=<domain> Allow the lookup of the specific domain "
  50. "name or domain\n");
  51. printf(" name suffixes using a wildcard, for "
  52. "example:\n");
  53. printf(" --allow-resolve=example.com # allow the "
  54. "lookup of the specific domain\n");
  55. printf(" --allow-resolve=*.example.com # allow "
  56. "the lookup of all subdomains\n");
  57. printf(" --allow-resolve=* # allow any lookup\n");
  58. }
  59. static bool
  60. validate_env_str(char *env)
  61. {
  62. char *p = env;
  63. int key_len = 0;
  64. while (*p != '\0' && *p != '=') {
  65. key_len++;
  66. p++;
  67. }
  68. if (*p != '=' || key_len == 0)
  69. return false;
  70. return true;
  71. }
  72. libc_wasi_parse_result_t
  73. libc_wasi_parse(char *arg, libc_wasi_parse_context_t *ctx)
  74. {
  75. if (!strncmp(arg, "--dir=", 6)) {
  76. if (arg[6] == '\0')
  77. return LIBC_WASI_PARSE_RESULT_NEED_HELP;
  78. if (ctx->dir_list_size >= sizeof(ctx->dir_list) / sizeof(char *)) {
  79. printf("Only allow max dir number %d\n",
  80. (int)(sizeof(ctx->dir_list) / sizeof(char *)));
  81. return LIBC_WASI_PARSE_RESULT_BAD_PARAM;
  82. }
  83. ctx->dir_list[ctx->dir_list_size++] = arg + 6;
  84. }
  85. else if (!strncmp(arg, "--map-dir=", 10)) {
  86. if (arg[10] == '\0')
  87. return LIBC_WASI_PARSE_RESULT_NEED_HELP;
  88. if (ctx->map_dir_list_size
  89. >= sizeof(ctx->map_dir_list) / sizeof(char *)) {
  90. printf("Only allow max map dir number %d\n",
  91. (int)(sizeof(ctx->map_dir_list) / sizeof(char *)));
  92. return 1;
  93. }
  94. ctx->map_dir_list[ctx->map_dir_list_size++] = arg + 10;
  95. }
  96. else if (!strncmp(arg, "--env=", 6)) {
  97. char *tmp_env;
  98. if (arg[6] == '\0')
  99. return LIBC_WASI_PARSE_RESULT_NEED_HELP;
  100. if (ctx->env_list_size >= sizeof(ctx->env_list) / sizeof(char *)) {
  101. printf("Only allow max env number %d\n",
  102. (int)(sizeof(ctx->env_list) / sizeof(char *)));
  103. return LIBC_WASI_PARSE_RESULT_BAD_PARAM;
  104. }
  105. tmp_env = arg + 6;
  106. if (validate_env_str(tmp_env))
  107. ctx->env_list[ctx->env_list_size++] = tmp_env;
  108. else {
  109. printf("Wasm parse env string failed: expect \"key=value\", "
  110. "got \"%s\"\n",
  111. tmp_env);
  112. return LIBC_WASI_PARSE_RESULT_NEED_HELP;
  113. }
  114. }
  115. /* TODO: parse the configuration file via --addr-pool-file */
  116. else if (!strncmp(arg, "--addr-pool=", strlen("--addr-pool="))) {
  117. /* like: --addr-pool=100.200.244.255/30 */
  118. char *token = NULL;
  119. if ('\0' == arg[12])
  120. return LIBC_WASI_PARSE_RESULT_NEED_HELP;
  121. token = strtok(arg + strlen("--addr-pool="), ",");
  122. while (token) {
  123. if (ctx->addr_pool_size
  124. >= sizeof(ctx->addr_pool) / sizeof(char *)) {
  125. printf("Only allow max address number %d\n",
  126. (int)(sizeof(ctx->addr_pool) / sizeof(char *)));
  127. return LIBC_WASI_PARSE_RESULT_BAD_PARAM;
  128. }
  129. ctx->addr_pool[ctx->addr_pool_size++] = token;
  130. token = strtok(NULL, ";");
  131. }
  132. }
  133. else if (!strncmp(arg, "--allow-resolve=", 16)) {
  134. if (arg[16] == '\0')
  135. return LIBC_WASI_PARSE_RESULT_NEED_HELP;
  136. if (ctx->ns_lookup_pool_size
  137. >= sizeof(ctx->ns_lookup_pool) / sizeof(ctx->ns_lookup_pool[0])) {
  138. printf("Only allow max ns lookup number %d\n",
  139. (int)(sizeof(ctx->ns_lookup_pool)
  140. / sizeof(ctx->ns_lookup_pool[0])));
  141. return LIBC_WASI_PARSE_RESULT_BAD_PARAM;
  142. }
  143. ctx->ns_lookup_pool[ctx->ns_lookup_pool_size++] = arg + 16;
  144. }
  145. else {
  146. return LIBC_WASI_PARSE_RESULT_NEED_HELP;
  147. }
  148. return LIBC_WASI_PARSE_RESULT_OK;
  149. }
  150. void
  151. libc_wasi_init(wasm_module_t wasm_module, int argc, char **argv,
  152. libc_wasi_parse_context_t *ctx)
  153. {
  154. wasm_runtime_set_wasi_args(wasm_module, ctx->dir_list, ctx->dir_list_size,
  155. ctx->map_dir_list, ctx->map_dir_list_size,
  156. ctx->env_list, ctx->env_list_size, argv, argc);
  157. wasm_runtime_set_wasi_addr_pool(wasm_module, ctx->addr_pool,
  158. ctx->addr_pool_size);
  159. wasm_runtime_set_wasi_ns_lookup_pool(wasm_module, ctx->ns_lookup_pool,
  160. ctx->ns_lookup_pool_size);
  161. }