1

For my university project I need to WRITE protect the whole address space of the process. I was reading the /proc/self/maps file and parsing the mapping.

So for each entry of the format 08048000-0804c000 r-xp 00000000 08:03 7971106 /bin/cat, I am reading the first two entry(here 08048000 & 0804c000), converting them to decimal. Lets assume the decimal equivalent is A & B respectively. Then I do mprotect((int*)A, B-A, PROT_READ). But this approach is giving me segmentation fault. I can't find out what I did wrong here. May be I've some knowledge gap here which is causing the problem. Someone can give me some suggestions?

azizulhakim
  • 658
  • 7
  • 24

1 Answers1

1

Assuming that your implementation is correct, I'd still expect to see segmentation faults.

After all, you're telling the kernel that you don't want to be allowed to write to any part of your memory. Afterwards, you'll just continue to run your process and the next time you try to write anything at all you'll get a segmentation fault because that's no longer allowed.

That'll most likely be when you return from mprotect() after "protecting" the stack.

Thinking a bit more, it's even possible that you're getting segmentation faults while executing memory (i.e. a shared lib, or your executable code) after you've "protected" it.

In fact, all of the bits of memory where it's safe to apply read-only / do-not-execute flags already have those flags set.

I suspect that's the insight this univerity project was meant to give you.

Kristof Provost
  • 26,018
  • 2
  • 26
  • 28
  • Thanks for your reply. Yes you are right on your points. But actually inside the mprotect() handler, I am removing the protection from the memory location being addressed, re-executing the memory accessing instruction, and then again applying the protection. Actually the goal of the project is to keep track of changes in address space so that I can backtrack to some previous application state. So the technique should have worked without any segmentation fault. Don't you think so? – azizulhakim Nov 28 '13 at 10:21
  • If I understand you correctly and you're trying to handle the memory access fault inside the SIGSEGV signal handler (mprotect() doesn't have a callback) you're still running against the same problem. You'd take a second segmentation fault just trying to set up the stack for the signal handler, or at least when calling mprotect() the second time. I don't think there's any way to do this without keeping at least some of the memory writable. – Kristof Provost Nov 28 '13 at 11:04
  • Is there any other easy alternative to handle the problem we are having? – azizulhakim Nov 28 '13 at 21:32
  • I'd look at ptrace(). That's what gdb uses. You could also try taking a look at Valgrind as it's solving a similar problem. – Kristof Provost Nov 29 '13 at 06:38
  • So does it imply that we can't protect the whole address with mprotect? If that is the case, which portion we can protect without any problem? – azizulhakim Dec 02 '13 at 02:05
  • I'd start by trying to protect everything except for the stack. That one needs to remain read/write. Also make sure to keep the execture permission on everything which currently has it. – Kristof Provost Dec 02 '13 at 06:29
  • Break out gdb and look at a core dump. See where it's crashing. Then you'll know what it's trying to read/write/execute. – Kristof Provost Dec 06 '13 at 06:45