0

I'm using mmap() in my custom thread local memory allocator in order to reduce heap fragmentation.

For security reasons, it would be nice to detect if some memory breaks the boundary of its thread. Is it possible to make memory read-only for all other threads, so that I get a segmentation fault, when accessed by another thread.

Cosinus
  • 534
  • 4
  • 10
  • 10
    Oh, it's very simple. Use processes instead of threads. – EOF Oct 08 '20 at 08:48
  • 1
    What exactly do you want to protect against? Buffer overflows? Or are you merely concerned about invalid cross-thread access on (valid) shared memory? Because if the latter, then the easiest solution is to allocate separate memory regions *per thread*. If the former, then EOF’s solution is the easiest. – Konrad Rudolph Oct 08 '20 at 08:53
  • @KonradRudolph, I have a lot of shared memory. And I'm using `libevent` and `sqlite3`. Some of the thread local data will be copied into the shared space. – Cosinus Oct 08 '20 at 08:59
  • 1
    Have you considered using mprotect() in the thread allowed to use the memory region ? For example, each time the thread access the memory, it sets PROT_READ/WRITE and when it does not access the memory region, it set PROT_READ. Of course, you need to serialize the access to the memory region with a mutex or a "multiple read/one write" mechanism as discussed in : https://stackoverflow.com/questions/27860685/how-to-make-a-multiple-read-single-write-lock-from-more-basic-synchronization-pr – Rachid K. Oct 08 '20 at 09:09
  • @Cosinus “Some of the thread local data will be copied into the shared space.” — Without knowing your specifics, *this* sounds like the problem. While it’s a widespread practice in legacy C applications there should never be write access from multiple threads to shared memory, except via well-defined, encapsulated data structures. – Konrad Rudolph Oct 08 '20 at 09:22
  • @KonradRudolph, when I use processes instead of threads for a webserver with a sqlite backend, I cannot use `fork()` because then I have to open/close the db connection for every request. – Cosinus Oct 08 '20 at 10:23
  • 1
    @Cosinus You can *totally* use `fork` with SQLite, you just have to open separate connections in all child processes, or you use IPC to communicate with a single process which performs synchronised database queries. Synchronisation is a fundamental technique to prevent race conditions. — That said, my previous comment was about using *threads*, not forking processes. The same still applies: when using *any* kind of concurrency you need to think carefully about synchronisation of shared resources. Directly sharing memory for write access is *never* appropriate. – Konrad Rudolph Oct 08 '20 at 10:33
  • On Linux you can have many options between `fork()` and `pthread_create()`, you can choose what you want to share with a child and what not. Read the `clone()` man page. – 12431234123412341234123 Oct 08 '20 at 11:10

0 Answers0