manifest.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  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. #define _GNU_SOURCE 1
  4. #ifndef __GNUC__
  5. #define __GNUC__ 1
  6. #endif
  7. #include <linux/unistd.h>
  8. #include <asm/mman.h>
  9. #include <stdint.h>
  10. #include <stddef.h>
  11. #include <sys/socket.h>
  12. #include <fcntl.h>
  13. #include <asm-errno.h>
  14. #include "../../security/Linux/utils.h"
  15. #include "graphene.h"
  16. static const char * __get_path (struct config_store * config, const char * key)
  17. {
  18. char uri[CONFIG_MAX];
  19. if (get_config(config, key, uri, CONFIG_MAX) <= 0 ||
  20. !is_file_uri(uri))
  21. return NULL;
  22. return file_uri_to_path(uri, strlen(uri));
  23. }
  24. #define PRELOAD_MAX 16
  25. int get_preload_paths (struct config_store * config, const char *** paths)
  26. {
  27. char cfgbuf[CONFIG_MAX];
  28. if (get_config(config, "loader.preload", cfgbuf, CONFIG_MAX) <= 0)
  29. return 0;
  30. const char * p = cfgbuf, * n;
  31. const char * preload_paths[PRELOAD_MAX];
  32. int npreload = 0;
  33. while (*p && npreload < PRELOAD_MAX) {
  34. for (n = p ; *n && *n != ',' ; n++);
  35. if (!is_file_uri(p))
  36. goto next;
  37. if (!(preload_paths[npreload++] = file_uri_to_path(p, n - p)))
  38. return -ENOMEM;
  39. next:
  40. p = *n ? n + 1 : n;
  41. }
  42. *paths = malloc(sizeof(const char *) * npreload);
  43. if (!(*paths))
  44. return -ENOMEM;
  45. memcpy((*paths), preload_paths, sizeof(const char *) * npreload);
  46. return npreload;
  47. }
  48. int get_fs_paths (struct config_store * config, const char *** paths)
  49. {
  50. const char * root_path = __get_path(config, "fs.mount.root.uri");
  51. if (!root_path)
  52. return 0;
  53. char keys[CONFIG_MAX];
  54. int nkeys;
  55. if ((nkeys = get_config_entries(config, "fs.mount.other", keys,
  56. CONFIG_MAX)) < 0)
  57. nkeys = 0;
  58. *paths = malloc(sizeof(const char *) * (1 + nkeys));
  59. if (!(*paths))
  60. return -ENOMEM;
  61. (*paths)[0] = root_path;
  62. int npaths = 1;
  63. if (!nkeys)
  64. goto out;
  65. char key[CONFIG_MAX], * k = keys, * n;
  66. fast_strcpy(key, "fs.mount.other.", 15);
  67. for (int i = 0 ; i < nkeys ; i++) {
  68. for (n = k ; *n ; n++);
  69. int len = n - k;
  70. fast_strcpy(key + 15, k, len);
  71. fast_strcpy(key + 15 + len, ".uri", 4);
  72. const char * path = __get_path(config, key);
  73. if (path)
  74. (*paths)[npaths++] = path;
  75. k = n + 1;
  76. }
  77. out:
  78. return npaths;
  79. }
  80. int get_net_rules (struct config_store * config,
  81. struct graphene_net_policy ** net_rules)
  82. {
  83. char keys[CONFIG_MAX];
  84. int nkeys;
  85. if ((nkeys = get_config_entries(config, "net.rules", keys,
  86. CONFIG_MAX)) < 0)
  87. return 0;
  88. struct graphene_net_policy * rules =
  89. malloc(sizeof(struct graphene_net_policy) * nkeys);
  90. if (!rules)
  91. return -ENOMEM;
  92. int nrules = 0;
  93. char key[CONFIG_MAX], * k = keys, * n;
  94. fast_strcpy(key, "net.rules.", 10);
  95. for (int i = 0 ; i < nkeys ; i++) {
  96. struct graphene_net_policy * r = &rules[nrules];
  97. char cfgbuf[CONFIG_MAX];
  98. for (n = k ; *n ; n++);
  99. int len = n - k;
  100. fast_strcpy(key + 10, k, len);
  101. key[10 + len] = 0;
  102. int cfglen = get_config(config, key, cfgbuf, CONFIG_MAX);
  103. if (cfglen <= 0)
  104. goto next;
  105. char * bind_addr;
  106. unsigned short bind_port_begin, bind_port_end;
  107. char * conn_addr;
  108. unsigned short conn_port_begin, conn_port_end;
  109. char * c = cfgbuf, * end = cfgbuf + cfglen;
  110. char * num;
  111. int family = AF_INET;
  112. bind_addr = c;
  113. if (*c == '[') {
  114. family = AF_INET6;
  115. bind_addr++;
  116. for ( ; c < end && *c != ']' ; c++);
  117. if (c == end)
  118. goto next;
  119. *(c++) = 0;
  120. if (c == end || *c != ':')
  121. goto next;
  122. } else {
  123. for ( ; c < end && *c != ':' ; c++);
  124. if (c == end)
  125. goto next;
  126. }
  127. *(c++) = 0;
  128. if (c == end)
  129. goto next;
  130. num = c;
  131. for ( ; c < end && *c >= '0' && *c <= '9' ; c++);
  132. if (c == num || c == end)
  133. goto next;
  134. bind_port_begin = atoi(num);
  135. if (*c == '-') {
  136. num = (++c);
  137. for ( ; c < end && *c >= '0' && *c <= '9' ; c++);
  138. if (c == num || c == end)
  139. goto next;
  140. bind_port_end = atoi(num);
  141. } else {
  142. bind_port_end = bind_port_begin;
  143. }
  144. if (*c != ':')
  145. goto next;
  146. c++;
  147. conn_addr = c;
  148. if (*c == '[') {
  149. if (family != AF_INET6)
  150. goto next;
  151. conn_addr++;
  152. for ( ; c < end && *c != ']' ; c++);
  153. if (c == end)
  154. goto next;
  155. *(c++) = 0;
  156. if (c == end || *c != ':')
  157. goto next;
  158. } else {
  159. if (family != AF_INET)
  160. goto next;
  161. for ( ; c < end && *c != ':' ; c++);
  162. if (c == end)
  163. goto next;
  164. }
  165. *(c++) = 0;
  166. if (c == end)
  167. goto next;
  168. num = c;
  169. for ( ; c < end && *c >= '0' && *c <= '9' ; c++);
  170. if (c == num)
  171. goto next;
  172. conn_port_begin = atoi(num);
  173. if (c < end && *c == '-') {
  174. num = (++c);
  175. for ( ; c < end && *c >= '0' && *c <= '9' ; c++);
  176. if (c == num)
  177. goto next;
  178. conn_port_end = atoi(num);
  179. } else {
  180. conn_port_end = conn_port_begin;
  181. }
  182. if (c != end)
  183. goto next;
  184. c++;
  185. r->family = family;
  186. if (inet_pton(family, bind_addr, &r->local.addr) < 0)
  187. goto next;
  188. r->local.port_begin = bind_port_begin;
  189. r->local.port_end = bind_port_end;
  190. if (inet_pton(family, conn_addr, &r->peer.addr) < 0)
  191. goto next;
  192. r->peer.port_begin = conn_port_begin;
  193. r->peer.port_end = conn_port_end;
  194. nrules++;
  195. next:
  196. k = n + 1;
  197. }
  198. *net_rules = rules;
  199. return nrules;
  200. }
  201. int ioctl_set_graphene (struct config_store * config, int ndefault,
  202. const struct graphene_user_policy * default_policies)
  203. {
  204. int ro = GRAPHENE_FS_READ, rw = ro | GRAPHENE_FS_WRITE;
  205. int ret = 0;
  206. const char ** preload_paths = NULL;
  207. const char ** fs_paths = NULL;
  208. struct graphene_net_policy * net_rules = NULL;
  209. int npreload = 0, nfs = 0, net = 0;
  210. int fd = -1;
  211. int n = 0;
  212. npreload = get_preload_paths(config, &preload_paths);
  213. if (npreload < 0) {
  214. ret = npreload;
  215. goto out;
  216. }
  217. nfs = get_fs_paths(config, &fs_paths);
  218. if (nfs < 0) {
  219. ret = nfs;
  220. goto out;
  221. }
  222. net = get_net_rules(config, &net_rules);
  223. if (net < 0) {
  224. ret = net;
  225. goto out;
  226. }
  227. struct graphene_policies * p =
  228. __alloca(sizeof(struct graphene_policies) +
  229. sizeof(struct graphene_user_policy) *
  230. (ndefault + npreload + nfs + net));
  231. memcpy(&p->policies[n], default_policies,
  232. sizeof(struct graphene_user_policy) * ndefault);
  233. n += ndefault;
  234. for (int i = 0 ; i < npreload ; i++) {
  235. p->policies[n].type = GRAPHENE_FS_PATH | ro;
  236. p->policies[n].value = preload_paths[i];
  237. n++;
  238. }
  239. for (int i = 0 ; i < nfs ; i++) {
  240. p->policies[n].type = GRAPHENE_FS_RECURSIVE | rw;
  241. p->policies[n].value = fs_paths[i];
  242. n++;
  243. }
  244. for (int i = 0 ; i < net ; i++) {
  245. p->policies[n].type = GRAPHENE_NET_RULE;
  246. p->policies[n].value = &net_rules[i];
  247. n++;
  248. }
  249. p->npolicies = n;
  250. fd = INLINE_SYSCALL(open, 3, GRAPHENE_FILE, O_RDONLY, 0);
  251. if (IS_ERR(fd)) {
  252. ret = -ERRNO(fd);
  253. goto out;
  254. }
  255. ret = INLINE_SYSCALL(ioctl, 3, fd, GRAPHENE_SET_TASK, p);
  256. ret = IS_ERR(ret) ? -ERRNO(ret) : 0;
  257. out:
  258. if (fd != -1)
  259. INLINE_SYSCALL(close, 1, fd);
  260. if (preload_paths) {
  261. for (int i = 0 ; i < npreload ; i++)
  262. free((void *) preload_paths[i]);
  263. free(preload_paths);
  264. }
  265. if (fs_paths) {
  266. for (int i = 0 ; i < nfs ; i++)
  267. free((void *) fs_paths[i]);
  268. free(fs_paths);
  269. }
  270. if (net_rules)
  271. free(net_rules);
  272. return ret;
  273. }