Sujet : Re: Memory protection between compilation units?
De : ifonly (at) *nospam* youknew.org (Opus)
Groupes : comp.lang.cDate : 11. Jun 2025, 16:19:36
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <102c6q8$21qfn$1@dont-email.me>
References : 1
User-Agent : Mozilla Thunderbird
On 11/06/2025 15:32, Mateusz Viste wrote:
This might not be a strictly C question, but it definitely concerns all
C programmers.
(...)
This raises a question: how can such corruptions be detected sooner?
Protected mode prevents interference between programs but doesn’t
safeguard a program from corrupting itself. Is there a way to enforce
memory protection between module files of the same program? After all,
static objects shouldn't be accessible outside their compilation unit.
This is an interesting question, indeed not specific to C.
This would require fine-grained memory protection, something that would require hardware support. Most OSs that implement some kind of "processes" use memory protection to isolate processes, but that's not more fine-grained than that.
So the short answer is: you have no means of doing this with current OSs, hardware and languages.
Language-wise, the options to make memory corruption less likely is to implement bounds checking and other mechanisms like that.
In C, to avoid out-of-bounds access of arrays, you could check all your array accesses dynamically (by checking indices). But that would require using the right array length for checking, which you may also get wrong, as this would be "manual".
There is a proposed extension for the RISC-V ISA called CHERI that offers the kind of fine-grained memory protection that could fit your purpose here. This is a topic that is certainly being investigated. But nothing available outside of research for now.
To answer your question in a more practical way, I would rewrite your code snippet as something like the following, making it safer and clearer to maintain:
#define SOCKS_LEN 65536 // or (1U << 16), whatever better expresses the intent.
static int *socks[SOCKS_LEN];
void update_my_socks(int *sock, int val) {
socks[val % SOCKS_LEN] = sock;
}
Note that the modulo (% SOCKS_LEN) will be compiled as a mask by the compiler if SOCKS_LEN is a power of two. So no need to bother with trying to hand-optimize it. But the code above also works if SOCKS_LEN is not a power of two. That's robust.
Second note: you chose to wrap indices around to handle possible out-of-bounds accesses. That may or may not be a good idea depending on the exact context. You may alternatively want to do nothing if val is out of bounds:
void update_my_socks(int *sock, int val) {
if (val >= SOCKS_LEN)
return;
socks[val] = sock;
}
Of course, if you want to be able to handle the case where there is an error, you may also want to return an error from update_my_socks() instead of having a function returning nothing. Or call some specific error function. Your pick.