Seccomp_test.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "util/log/FileWriterLog.h"
  16. #include "memory/Allocator.h"
  17. #include "memory/MallocAllocator.h"
  18. #include "util/Seccomp.h"
  19. #include "util/events/EventBase.h"
  20. #include "util/events/Process.h"
  21. #include "util/events/Pipe.h"
  22. #include "util/events/Timeout.h"
  23. #include "util/CString.h"
  24. #include "crypto/random/Random.h"
  25. struct Context
  26. {
  27. struct Iface iface;
  28. struct Allocator* alloc;
  29. struct EventBase* eventBase;
  30. Identity
  31. };
  32. static void childComplete(void* vEventBase)
  33. {
  34. EventBase_endLoop((struct EventBase*)vEventBase);
  35. }
  36. static void onConnectionChild(struct Pipe* p, int status)
  37. {
  38. // hax
  39. struct Allocator* alloc = (struct Allocator*) p->userData;
  40. struct Log* logger = p->logger;
  41. Seccomp_dropPermissions(alloc, logger, NULL);
  42. Assert_true(Seccomp_isWorking());
  43. struct Message* ok = Message_new(0, 512, alloc);
  44. Message_push(ok, "OK", 3, NULL);
  45. struct Iface iface = { .send = NULL };
  46. Iface_plumb(&p->iface, &iface);
  47. Iface_send(&iface, ok);
  48. // just set a timeout long enough that we're pretty sure the parent will get the message
  49. // before we quit.
  50. Timeout_setInterval(childComplete, p->base, 10, p->base, alloc);
  51. }
  52. static void timeout(void* vNULL)
  53. {
  54. Assert_true(!"timed out");
  55. }
  56. static int child(char* pipeName, struct Allocator* alloc, struct Log* logger)
  57. {
  58. struct EventBase* eb = EventBase_new(alloc);
  59. struct Pipe* pipe = Pipe_named(Pipe_PATH, pipeName, eb, NULL, alloc);
  60. pipe->onConnection = onConnectionChild;
  61. pipe->logger = logger;
  62. pipe->userData = alloc;
  63. Timeout_setTimeout(timeout, eb, 2000, eb, alloc);
  64. EventBase_beginLoop(eb);
  65. return 0;
  66. }
  67. static Iface_DEFUN receiveMessageParent(struct Message* msg, struct Iface* iface)
  68. {
  69. struct Context* ctx = Identity_check((struct Context*) iface);
  70. Assert_true(msg->length == 3);
  71. Assert_true(!Bits_memcmp(msg->bytes, "OK", 3));
  72. EventBase_endLoop(ctx->eventBase);
  73. return 0;
  74. }
  75. int main(int argc, char** argv)
  76. {
  77. struct Allocator* alloc = MallocAllocator_new(20000);
  78. struct Log* logger = FileWriterLog_new(stdout, alloc);
  79. if (!Seccomp_exists()) {
  80. Log_debug(logger, "Seccomp not supported on this system");
  81. return 0;
  82. }
  83. if (argc > 3 && !CString_strcmp("Seccomp_test", argv[1]) && !CString_strcmp("child", argv[2])) {
  84. child(argv[3], alloc, logger);
  85. Allocator_free(alloc);
  86. return 0;
  87. }
  88. struct EventBase* eb = EventBase_new(alloc);
  89. struct Random* rand = Random_new(alloc, logger, NULL);
  90. char name[32] = {0};
  91. Random_base32(rand, (uint8_t*)name, 31);
  92. struct Context* ctx = Allocator_calloc(alloc, sizeof(struct Context), 1);
  93. Identity_set(ctx);
  94. ctx->alloc = alloc;
  95. ctx->iface.send = receiveMessageParent;
  96. ctx->eventBase = eb;
  97. struct Pipe* pipe = Pipe_named(Pipe_PATH, name, eb, NULL, alloc);
  98. pipe->logger = logger;
  99. Iface_plumb(&ctx->iface, &pipe->iface);
  100. char* path = Process_getPath(alloc);
  101. char* args[] = { "Seccomp_test", "child", name, NULL };
  102. Assert_true(!Process_spawn(path, args, eb, alloc, NULL));
  103. Timeout_setTimeout(timeout, NULL, 2000, eb, alloc);
  104. EventBase_beginLoop(eb);
  105. return 0;
  106. }