I would like to know how memory can be protected without MMU support. I have tried to google it, but have not seen any worthwile papers or research on it. And those which deal with it only deals it for bugs, such as uninitialized pointers and not memory corruption due to a soft error, that is, due to a hardware transient fault corrupting an instruction that writes to a memory location.
The reason I want to know this is because I am working on a proprietary manycore platform without any Memory Protection. Now my question is, can software be used to protect memory, especially for wild writes due to soft erros (as opposed to mistakes by a programmer). Any help on this would be really appreciated.
If you're looking for Runtime memory protection the sane only option is hardware support. Hardware is the only way to intervene in a bad memory access before it can cause damage. Any software solution would be vulnerable to the very memory errors it is trying to protect against.
With software you could possibly implement a verification/detection scheme. You could periodically check portions of memory that the currently running program should not have access and see if they have changed (probably by CRCing these areas). But of course if the rogue program damages the area where the checksums are held, or where the checking program's code is held, then all bets are off.
Even this software checking solution would be more of a debugging utility than a permanent runtime protection. It is likely that a device with no MMU is a small embedded device which won't have the spare cycles to be constantly checking the device's memory.
Usually devices without MMUs are designed to run a single program with no kernel or anything else, and thus there is nothing to protect. If you need to run multiple programs and feel you need protection, you probably need a more advanced piece of hardware that supports the kind of features you're looking for.
If you want software implemented memory protection, then you will need support from your compiler and its associated libraries. I expect that there is one compiler only on this platform and so you should contact the vendor. I wouldn't hold out much hope for a positive response. Even if they had such tools, I would expect the performance of software memory protection to be unacceptable.
MMU less systems are present in several embedded solutions.
The memory is managed by the kernel code. The entire memory (heap) is divided into heap lists of various sizes (heap lists can be of sizes 4 bytes, 8 bytes, 16 bytes ..... upto 1024 bytes)and there's a header attached to each heap block that tells whether the particular heap block is taken or not. So, that when u need to assign a new heap block, you can browse through the heap lists and see which heap blocks are free and can assign them to the requesting application. And the same is the case when you free a particular sized heap block, the headers of that block are updated to reflect that it has been freed.
Now, this implementation has to take care of the scenario when the application requested a particular size of heap block and that size of heap list is full. In that case you break up a block from the next size of heap list or join together smaller sized heap blocks and add to the requested sized heap list.
The implementation is much simpler than it seems.
Depends on what application platform will run. There is technology called Type-Safe Language (ATS, for instance) which can protect from software errors. And such languages may have good performance (again ATS, for instance).
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 5 years ago.
Improve this question
What I understood from reading some web articles is that just like any other program, the host OS allocates X amount of memory to virtual OS and when I start any program on virtual OS, the virtual OS fetches the exact amount of memory needed for the program.
When I shut the virtual OS down, it returns the allocated memory to the host OS.
But what happens if there is a memory leakage in the virtual OS environment? I am starting to learn C, and my professor says that in dynamic memory allocation operations, permanent leakage can happen in the host OS.
But what if it happens in virtual environment? I guess the program will give back ALL of the memory allocated to the host OS when I shut it down, right? What happens when I start the virtual host again the next time? Does the memory leakage show up there permanently?
Just getting afraid before I even start writing my first program in C.
P. S. If I use websites like Repl.it and use memory allocation over there, will it cause damage to my system still?
Memory leak can occur when you allocate some memory (with malloc in C) and you never free that memory, this can happen for a number of reasons.
Now the important thing to understand is that this allocated memory will be released once the process is finished running.
When you setup your VM you set the maximum amount of memory it can consume. When you shut down your VM it will also be released.
You can't cause a "permanent" memory leakage if the program you write doesn't run. If the OS has some always running service with memory leak than it will slow down when it is out of memory but when you restart, all the memory will be released again.
So don't let this stop you, you can't damage your computer and you can always recover it by exiting the program. (or restarting the PC in a worst case scenario
)
EDIT:
As it was mentioned in the comments there is a special scenario when you leak shared memory, in this case exiting the program might not release the memory but I consider this the worst case scenario and a reboot will solve this problem as well. (still not permanent)
This answer is meant to provide a different view point, in addition to the good answer(s) and comments, which I agree with.
I am trying to see the worst case, i.e a way how you could get what you fear.
You probably have an environment which does not match the following assumptions, in that case my construct does of course not apply.
your virtual OS supports "persistence"
(i.e. you can shut it down in a "hibernate" way, it can start with the same running processes and their restored memory content)
your virtualisation engine also supports persistence of the virtual OS
shutting down for persistence in virtual OS is possible with a process occupying a critical amount of memory (sanity checks could prevent this)
virtualisation engine also does not mind the depleted memory and allows persistence
you choose to use persistent shutdown,
rebooting the virtual OS normally would include killing the evil process and reclaiming the memory (this is discussed by other answers and comments, but thanks to MrBlaise for proposing the clarification here)
In this circumstance I imagine that you can have:
a process which has taken (and ran out of) all avaiable memory
but has not crashed or otherwise triggered emergency measures
then this situation is saved for persistence before shutting down, successfully
then you restart the virtual OS
it restores the previous situation, i.e. returns from hiberantion
the restored previous situation contains a still/again running process which has taken all memory
I think this will still only affect the virtual OS, not the host.
Please note that I intentionally made all necessary assumptions just to get the situation you are afraid of. Some of the assumptions are quite "daring".
I imagine for example that anything supporting persistence should have sanity checks, which at least detect the memory issue and ask how to handle.
(By the way, I do not know about virtualisation engines which support persistence, neither whether any do not support it. I am thinking in the generic, theoretical area.
In case I have invented the persistence for virtualisation engines (can't believe it), I claim this as prior art. ;-))
I read on wikipedia that disabling cpu-cache can improve performance:
Marking some memory ranges as non-cacheable can improve performance, by avoiding caching of memory regions that are rarely re-accessed.
When I googled how to do it in c on linux however, I didn't find anything. It's not that I really need this feature but I'm interested anyways.
And do you know of any projects which use this optimization?
Edit: I'm programming for x86_64
That comment about non-caching doesn't mean what you think it means, and where it is used, it isn't usually a user-accessible feature. That is, CPU cache control is typically a privileged operation.
That said...
-- A normal user program can be build with functions who's attributes are "hot" or "cold" to let the compiler tell the loader to group the functions in ways that will utilize the cache most usefully.
-- A normal program can use the madvise() function in linux to tell the paging function various things, including the fact that the memory just used is or is not likely to be used again soon.
-- The kernel itself uses the Memory Type Range Regesters (mtrr) and Page Attribute Table (pat) flags in later kernels, to tell the hardware that particular ranges of memory (such as the memory mapped display buffer, and the various parts of the PCI bus) are not to be cached.
"Normal Data™" such as you are likely to use in any C program will essentially never benefit from marking any of its data not cache-worthy. The performance improvement that not-cached data enjoys is the subsequent absence of the various cache-flush and memory barrier operations that memory mapped devices and display buffers would need almost constantly. Laying a cache over a memory mapped device, for example, would require a cache invalidate command before every read and a cache forced write command after every single write to make sure that the reads and writes happen at the exact moment needed. This would "poison" the cache usage, using up and instantly discarding cache lines (a physically limited resource) in a most unfriendly and unhelpful way.
In the rare case that you write a program that gains access to one of these cache harmful regions -- such as if you wrote part of the X display server on a linux system -- the kernel would have already set the registers for the device and the non-cache behavior would be transparent to you.
There is effectively no time where your normal application grade program is going to benefit from any ability to mark a variable as harmful to cache beyond the various madvise() type of usage.
Even then, the cases were you could gain any benefit are so rare that if you'd ever acutally run into one, the problem set would have included the need and methodology as part of your research and you'd have been told how and why so explicitly you'd never have needed to ask this question.
To go back to the same example again, if you'd been writing the necessary driver, when you'd been reading up on the display adapter hardware or the PCI bus the various flags and techniques would have been documented and discussed in the hardware guide.
There are ways to pull off cache ejection and such from user space with things like the CLCLEAR instruction on an intel platform. These techniques will not improve general performance.
Since it's a privileged operation on a Linux system, you could write a kernel driver that acquired and marked a region of memory as uncacheable and then let you map it into your application. But the need for such a region is so rare, and so likely to be misused, that there isn't a normal methodology for doing it in place.
So how do you do it? You don't, at least not the you that you are today. When you become a kernel driver writer with an intimate specialty knowledge of multi-threaded code and data synchronization issues, you'll know how you could do it, and at that point you'll know why you don't want to except as a last resort.
TL;DR :: because of the way linux uses and manages data and code, there is never a benefit for marking any part of a normal application as uncacheable that doesn't cause more heartbreak than it saves. As such, there is no unprivileged API for doing this.
P.S. Also, that said, someone already pointed to things that lead to this article http://lwn.net/Articles/255364/ which covers ways to make your program very cache friendly and some of the ways that you can do some cache bypass operations very cheaply. For instance use of memset() tends to go around the cache while setting memory, and some operations can "stream past" the cache. This isn't the same thing as what you ask, but once you understand all of that article you'll have a much better understanding of why marking a region of memory as uncachable is usually, as the Jedi say, not the solution you are looking for.
Recently i needed to experiment with uncached memory in a cache-heavy multi-threaded application.
I came up with this kernel module which allows to map uncached memory to userspace.
User process requests uncached memory by calling mmap() on module's character device (see test directory for demo).
What every programmer should know about memory is indeed a must read !
I am interested to know if there is a way to allocate "weak" memory in userspace in common operating systems like Linux, OS X, or Windows (obviously not possible with standard interfaces). What I mean is the sort of an mmap(), which would invalidate the mapping if the OS elects to push the pages out of core.
Say, I want to work with a 10G dataset on a 32-bit system. To get a piece from this dataset, I read it from the file and decompress it to memory[. I would prefer to keep the decompressed versions of the pieces around, if possible, to avoid decompressing the data on each access, but to allow accessing all pieces I must eventually free some data to avoid exhausting the memory/address space.
I can emulate this by gluing a framework on top of malloc() to free the old pieces if malloc() NULLs out, but it deprives other processes of memory and makes them to page out (or pages out the decompressed pieces). Or, I could keep some soft limit in the application, but that seems arbitrary and only alleviates the problem, and is suboptimal if there's free memory around. I feel that this is something that a virtual memory manager in a modern OS should handle.
Any tips and information about how this problem is tackled in other modern applications are appreciated.
No, there is no mechanism in common operating systems that implement the weak userspace memory as you describe.
Weak references come from the domain of garbage collection frameworks where an object/allocation is otherwise abandoned (i.e. has no "strong" references). The weak references will be invalidated/nulled if the garbage collector gets to the allocation before the application attempts to recycle it by assigning the weak reference to a "strong" one.
The functionality you describe in your question and in the subsequent comments could be better and more simply implemented by an application cache that discards "pages" when he cache fills up and overwrites them with newly needed "pages". Be careful to implement mutexes if the cache can be accessed by multiple threads. The mutexes (if needed) are the most exotic thing here. Everything else is pretty standard vanilla programming.
By way of an academic exercise, you could implement the concept you are describing at the kernel level with a device driver meaning the capability would be exposed as a pseudo device. I would be very reluctant to acutally base a production implementation on this pseudo device as it has a negative effect on portability and maintainability, could adversely affect the entire platform's performance and behavior (after all we're talking kernel code here), and would by comparison take a long time to develop and test.
Good luck in your endeavor.
This is purely academical question not related to any OS
We have x86 CPU and operating memory, this memory resembles some memory pool, that consist of addressable memory units that can be read or written to, using their address by MOV instruction of CPU (we can move memory from / to this memory pool).
Given that our program is the kernel, we have a full access to whole this memory pool. However if our program is not running directly on hardware, the kernel creates some "virtual" memory pool which lies somewhere inside the physical memory pool, our process consider it just as the physical memory pool and can write to it, read from it, or change its size usually by calling something like sbrk or brk (on Linux).
My question is, how is this virtual pool implemented? I know I can read whole linux source code and maybe one year I find it, but I can also ask here :)
I suppose that one of these 3 potential solutions is being used:
Interpret the instructions of program (very ineffective and unlikely): the kernel would just read the byte code of program and interpret each instruction individually, eg. if it saw a request to access memory the process isn't allowed to access it wouldn't let it.
Create some OS level API that would need to be used in order to read / write to memory and disallow access to raw memory, which is probably just as ineffective.
Hardware feature (probably best, but have no idea how that works): the kernel would say "dear CPU, now I will send you instructions from some unprivileged process, please restrict your instructions to memory area 0x00ABC023 - 0xDEADBEEF" the CPU wouldn't let the user process do anything wrong with the memory, except for that range approved by kernel.
The reason why am I asking, is to understand if there is any overhead in running program unprivileged behind the kernel (let's not consider overhead caused by multithreading implemented by kernel itself) or while running program natively on CPU (with no OS), as well as overhead in memory access caused by computer virtualization which probably uses similar technique.
You're on the right track when you mention a hardware feature. This is a feature known as protected mode and was introduced to x86 by Intel on the 80286 model. That evolved and changed over time, and currently x86 has 4 modes.
Processors start running in real mode and later a privileged software (ring0, your kernel for example) can switch between these modes.
The virtual addressing is implemented and enforced using the paging mechanism (How does x86 paging work?) supported by the processor.
On a normal system, memory protection is enforced at the MMU, or memory management unit, which is a hardware block that configurably maps virtual to physical addresses. Only the kernel is allowed to directly configure it, and operations which are illegal or go to unmapped pages raise exceptions to the kernel, which can then discipline the offending process or fetch the missing page from disk as appropriate.
A virtual machine typically uses CPU hardware features to trap and emulate privileged operations or those which would too literally interact with hardware state, while allowing ordinary operations to run directly and thus with moderate overall speed penalty. If those are unavailable, the whole thing must be emulated, which is indeed slow.
Im doing some debugging on hardware with a Linux OS.
Now there no way for me to know if any of it works unless I can check the allocated ram that I asked it to write to.
Is there some way that I can check what is in that block or RAM from an external program running in the same OS?
If I could write a little program in C to do that how will I go about it since I cant just go and assign pointers custom addresses ?
Thanks
I think the best way to do what you are asking for is to use a debugger. And you cannot read another programme's memory unless you execute your code in a privileged space (i.e. the kernel), and privileged from the point of view of the CPU. And this because each programme is running in its own virtual memory space (for security concerns) and even the kernel is running in a virtual memory space but it has the privilege to map any physical memory block inside the virtual memory space it is current running. Anyway, I will not explain more in depth how an modern OS manage memory with the underneath hardware, it would be long.
You should really look at using a debugger. Once you environment with your debugger is ready, you should put a break after that memory block allocation so the debugger will stop the programme there and so you can inspect that freshly allocated memory block as you wish. Depending on whether you use an IDE or not, it can be very easy to use a debugger ;)
/dev/mem could come to use. It is a device file that is an image of the physical memory (including non-RAM memory). It's generally used to read/write memory of peripheral devices.
By mmap()ing to it, you could access physical memory.
See this linux documentation project page
memedit is a handy utility to display and change memory content for testing purposes.
It's main purpose is to display SoC hardware registers but it could be used to display RAM. It is based on mmap() mechanism. It could be good starting point to write custom application.