asymmetric priviledges for sharing anonymous mmapped data between processes
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
asymmetric priviledges for sharing anonymous mmapped data between processes
Hey,
So, I've been reading for a while trying to figure this one out. What I want to do is this:
1. mmap some memory anonymously
2. fork a child
3. have the child lose write abilities for some of the memory mapped, but allow the parent to maintain them
If it worked, I figure it would look something like this:
Code:
void* rv = mmap(0, num_bytes, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0);
if(rv == MAP_FAILED){
// handle error
}
if(fork()){
// we are the parent...
// do some stuff
}
else {
// we are the child, drop priviledges irreversibly
if(mprotect(rv, num_bytes, PROT_READ) == -1){
// handle error
}
// do more child things
}
Obviously, the above code has some problems. First, if there is a shared object I believe that permissions are probably shared so that the parent and child both would have the same permissions. Second, I don't want the child to be able to undo the mprotect. I'd like to be able to run untrusted code as the client. I'm sure someone that knows more about this stuff can probably help me. I've poured over the syscalls, but clearly I've missed something. Thanks in advance!
I looked in man 7 capabilities. It is good to know about capget and capset, but none of the capabilities seemed to be what I need. Thanks though, that was a good read that I probably should have done earlier. Particularly interesting that "file system support for attaching capabilities to an executable file, so that a process gains those capabilities when the file is execed" is not implemented. I liked that discussion. Thanks.
Did you know that with file-backed mmap you could map it twice: once R/W and once R/O? You can map as both in the parent, then unmap the R/W right after fork, before the untrusted code is executed. As far as I know, you can't change the R/O mapping to a R/W mapping with mprotect. You also might consider using a setuid program in conjunction. This would allow you to either protect the underlying file if used with mmap or the share itself if you decide to use shmget (also a consideration.)
ta0kira
PS I'd go with a file-backed mmap if I were you. shm* has the risk of leaving a hanging memory segment even after all processes using it have exited. One process has to flag it for deletion, which then locks out all other mappings to it. It's a real pain, but you don't have to back it with a file. Not worth the trade in my opinion. The last time I used it I had to write a script that I'd call periodically during development to clean up the stray segments.
That makes a lot of sense. Your example code is very helpful. I wish I'd been able to find a code sample like the one you gave on my own, but I guess that is why forums exist! Thanks a lot.
You're welcome. It helps me, too, since a lot of what I know about *nix programming is a result of figuring out answers to questions in this forum that I have no previous experience with. This one was actually an answer to a similar virtual machine question from a while ago.
ta0kira
Yes, that did sound bad. I didn't mean "I answer questions not knowing what I'm talking about." I mean I've learned a whole lot from questions like "why doesn't this work..." when it has to do with something I haven't used; I figure out why it doesn't work and provide a legitimate answer. Or, "how can I get this functionality..."; I figure out how it can be done, only providing an answer when I've gotten the requested result (e.g. I haven't written an emulator, but I figured out how to have separate R/W and R/O access to the same memory specifically to answer a question.) But my advice-giving always comes from things I have experience with unless I say otherwise specifically. Generally the only things I "learn for the question" are for fixing specific run-time bugs and figuring out how functionality can be implemented, but that normally requires me to use all of my other experience that the asker might not have. It mostly just results in me learning new libc functions or e.g. learning how to socket program to see why a client can't read from a server; if my answer solves the problem it doesn't matter when I learned it, just that I haven't given unsubstantiated advice. If I'm the least bit uncertain about my answer then I point that out, also. You know, it's like the IT guy who fixes the office computers. Half the time he won't know how to fix a problem but he'll learn how to for that specific situation (maybe a bad analogy since sometimes IT fixes are worse than the problem .) Does that help? Thanks for calling me out! Everyone needs that once in a while (some more often.)
ta0kira
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.