sandbox.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #ifdef WITHOUT_SANDBOX
  2. void sbox_enter(const char *basedir)
  3. {
  4. /* nothing to do */
  5. (void)basedir;
  6. }
  7. #else /* WITHOUT_SANDBOX */
  8. #include "xs.h"
  9. #include "snac.h"
  10. #include <unistd.h>
  11. #if defined (__linux__)
  12. #define LL_PRINTERR(fmt, ...) srv_debug(0, xs_fmt(fmt, __VA_ARGS__))
  13. #include "landloc.h"
  14. static
  15. LL_BEGIN(sbox_enter_linux_, const char* basedir, const char *address, int smail) {
  16. const unsigned long long
  17. rd = LANDLOCK_ACCESS_FS_READ_DIR,
  18. rf = LANDLOCK_ACCESS_FS_READ_FILE,
  19. w = LANDLOCK_ACCESS_FS_WRITE_FILE |
  20. LANDLOCK_ACCESS_FS_TRUNCATE_COMPAT,
  21. c = LANDLOCK_ACCESS_FS_MAKE_DIR |
  22. LANDLOCK_ACCESS_FS_MAKE_REG |
  23. LANDLOCK_ACCESS_FS_TRUNCATE_COMPAT |
  24. LANDLOCK_ACCESS_FS_MAKE_SYM |
  25. LANDLOCK_ACCESS_FS_REMOVE_DIR |
  26. LANDLOCK_ACCESS_FS_REMOVE_FILE |
  27. LANDLOCK_ACCESS_FS_REFER_COMPAT,
  28. s = LANDLOCK_ACCESS_FS_MAKE_SOCK,
  29. x = LANDLOCK_ACCESS_FS_EXECUTE;
  30. LL_PATH(basedir, rf|rd|w|c);
  31. LL_PATH("/tmp", rf|rd|w|c);
  32. #ifndef WITHOUT_SHM
  33. LL_PATH("/dev/shm", rf|w|c );
  34. #endif
  35. LL_PATH("/etc/resolv.conf", rf );
  36. LL_PATH("/etc/hosts", rf );
  37. LL_PATH("/etc/ssl", rf );
  38. LL_PATH("/usr/share/zoneinfo", rf );
  39. if (mtime("/etc/pki") > 0)
  40. LL_PATH("/etc/pki", rf );
  41. if (*address == '/')
  42. LL_PATH(address, s);
  43. if (smail)
  44. LL_PATH("/usr/sbin/sendmail", x);
  45. if (*address != '/') {
  46. unsigned short listen_port = xs_number_get(xs_dict_get(srv_config, "port"));
  47. LL_PORT(listen_port, LANDLOCK_ACCESS_NET_BIND_TCP_COMPAT);
  48. }
  49. LL_PORT(80, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
  50. LL_PORT(443, LANDLOCK_ACCESS_NET_CONNECT_TCP_COMPAT);
  51. } LL_END
  52. #endif
  53. void sbox_enter(const char *basedir)
  54. {
  55. if (xs_is_true(xs_dict_get(srv_config, "disable_openbsd_security"))) {
  56. srv_log(xs_dup("disable_openbsd_security is deprecated. Use disable_sandbox instead."));
  57. return;
  58. }
  59. if (xs_is_true(xs_dict_get(srv_config, "disable_sandbox"))) {
  60. srv_debug(0, xs_dup("Sandbox disabled by admin"));
  61. return;
  62. }
  63. const char *address = xs_dict_get(srv_config, "address");
  64. int smail = !xs_is_true(xs_dict_get(srv_config, "disable_email_notifications"));
  65. #if defined (__OpenBSD__)
  66. srv_debug(1, xs_fmt("Calling unveil()"));
  67. unveil(basedir, "rwc");
  68. unveil("/tmp", "rwc");
  69. unveil("/etc/resolv.conf", "r");
  70. unveil("/etc/hosts", "r");
  71. unveil("/etc/ssl/openssl.cnf", "r");
  72. unveil("/etc/ssl/cert.pem", "r");
  73. unveil("/usr/share/zoneinfo", "r");
  74. if (smail)
  75. unveil("/usr/sbin/sendmail", "x");
  76. if (*address == '/')
  77. unveil(address, "rwc");
  78. unveil(NULL, NULL);
  79. srv_debug(1, xs_fmt("Calling pledge()"));
  80. xs *p = xs_str_new("stdio rpath wpath cpath flock inet proc dns fattr");
  81. if (smail)
  82. p = xs_str_cat(p, " exec");
  83. if (*address == '/')
  84. p = xs_str_cat(p, " unix");
  85. pledge(p, NULL);
  86. xs_free(p);
  87. #elif defined (__linux__)
  88. if (sbox_enter_linux_(basedir, address, smail) == 0)
  89. srv_log(xs_dup("landlocked"));
  90. else
  91. srv_log(xs_dup("landlocking failed"));
  92. #endif
  93. }
  94. #endif /* WITHOUT_SANDBOX */