sandbox.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #include "xs.h"
  2. #include "snac.h"
  3. #if defined(__OpenBSD__)
  4. void sbox_enter(const char *basedir)
  5. {
  6. const char *address = xs_dict_get(srv_config, "address");
  7. int smail = !xs_is_true(xs_dict_get(srv_config, "disable_email_notifications"));
  8. if (xs_is_true(xs_dict_get(srv_config, "disable_openbsd_security"))) {
  9. srv_log(xs_dup("OpenBSD security disabled by admin"));
  10. return;
  11. }
  12. srv_debug(1, xs_fmt("Calling unveil()"));
  13. unveil(basedir, "rwc");
  14. unveil("/tmp", "rwc");
  15. unveil("/etc/resolv.conf", "r");
  16. unveil("/etc/hosts", "r");
  17. unveil("/etc/ssl/openssl.cnf", "r");
  18. unveil("/etc/ssl/cert.pem", "r");
  19. unveil("/usr/share/zoneinfo", "r");
  20. if (smail)
  21. unveil("/usr/sbin/sendmail", "x");
  22. if (*address == '/')
  23. unveil(address, "rwc");
  24. unveil(NULL, NULL);
  25. srv_debug(1, xs_fmt("Calling pledge()"));
  26. xs *p = xs_str_new("stdio rpath wpath cpath flock inet proc dns fattr");
  27. if (smail)
  28. p = xs_str_cat(p, " exec");
  29. if (*address == '/')
  30. p = xs_str_cat(p, " unix");
  31. pledge(p, NULL);
  32. }
  33. #elif defined(__linux__)
  34. #if defined(WITH_LINUX_SANDBOX)
  35. #include <unistd.h>
  36. #define LL_PRINTERR(fmt, ...) srv_debug(0, xs_fmt(fmt, __VA_ARGS__))
  37. #include "landloc.h"
  38. static
  39. LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail) {
  40. const unsigned long long
  41. rd = LANDLOCK_ACCESS_FS_READ_DIR,
  42. rf = LANDLOCK_ACCESS_FS_READ_FILE,
  43. w = LANDLOCK_ACCESS_FS_WRITE_FILE |
  44. LANDLOCK_ACCESS_FS_TRUNCATE_COMPAT,
  45. c = LANDLOCK_ACCESS_FS_MAKE_DIR |
  46. LANDLOCK_ACCESS_FS_MAKE_REG |
  47. LANDLOCK_ACCESS_FS_TRUNCATE_COMPAT |
  48. LANDLOCK_ACCESS_FS_MAKE_SYM |
  49. LANDLOCK_ACCESS_FS_REMOVE_DIR |
  50. LANDLOCK_ACCESS_FS_REMOVE_FILE |
  51. LANDLOCK_ACCESS_FS_REFER_COMPAT,
  52. s = LANDLOCK_ACCESS_FS_MAKE_SOCK,
  53. x = LANDLOCK_ACCESS_FS_EXECUTE;
  54. char *resolved_path = NULL;
  55. LL_PATH(basedir, rf|rd|w|c);
  56. LL_PATH("/tmp", rf|rd|w|c);
  57. #ifndef WITHOUT_SHM
  58. LL_PATH("/dev/shm", rf|w|c );
  59. #endif
  60. LL_PATH("/dev/urandom", rf );
  61. LL_PATH("/etc/resolv.conf", rf );
  62. LL_PATH("/etc/hosts", rf );
  63. LL_PATH("/etc/ssl", rf|rd );
  64. if ((resolved_path = realpath("/etc/ssl/cert.pem", NULL))) {
  65. /* some distros like cert.pem to be a symlink */
  66. LL_PATH(resolved_path, rf );
  67. free(resolved_path);
  68. }
  69. LL_PATH("/usr/share/zoneinfo", rf );
  70. if (mtime("/etc/pki") > 0)
  71. LL_PATH("/etc/pki", rf );
  72. if (*address == '/') {
  73. /* the directory holding the socket must be allowed */
  74. xs *l = xs_split(address, "/");
  75. l = xs_list_del(l, -1);
  76. xs *sdir = xs_join(l, "/");
  77. LL_PATH(sdir, s);
  78. }
  79. if (smail && mtime("/usr/sbin/sendmail") > 0)
  80. LL_PATH("/usr/sbin/sendmail", x);
  81. if (*address != '/') {
  82. unsigned short listen_port = xs_number_get(xs_dict_get(srv_config, "port"));
  83. LL_PORT(listen_port, LANDLOCK_ACCESS_NET_BIND_TCP_COMPAT);
  84. }
  85. LL_PORT(80, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
  86. LL_PORT(443, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
  87. } LL_END
  88. void sbox_enter(const char *basedir)
  89. {
  90. const char *address = xs_dict_get(srv_config, "address");
  91. int smail = !xs_is_true(xs_dict_get(srv_config, "disable_email_notifications"));
  92. if (xs_is_true(xs_dict_get(srv_config, "disable_sandbox"))) {
  93. srv_debug(1, xs_dup("Linux sandbox disabled by admin"));
  94. return;
  95. }
  96. if (sbox_enter_linux_(basedir, address, smail) == 0)
  97. srv_debug(1, xs_dup("Linux sandbox enabled"));
  98. else
  99. srv_debug(1, xs_dup("Linux sandbox failed"));
  100. }
  101. #else /* defined(WITH_LINUX_SANDBOX) */
  102. void sbox_enter(const char *basedir)
  103. {
  104. (void)basedir;
  105. srv_debug(1, xs_fmt("Linux sandbox not compiled in"));
  106. }
  107. #endif
  108. #else
  109. /* other OSs: dummy sbox_enter() */
  110. void sbox_enter(const char *basedir)
  111. {
  112. (void)basedir;
  113. }
  114. #endif /* __OpenBSD__ */