Is there any way to determine whether a buffer received as a void* pointer comes from the stack or has been allocated with any other mechansim (vmalloc, kmalloc, ...)?
In other words, is there any API or trick, similar to is_vmalloc_addr, to know if the buffer comes from the stack?
See object_is_on_stack() at include/linux/sched.h. Hope this helps.
Related
My textbook says that following:
Once the operating system decides to create a new process, it
allocates space for all elements of the process image; therefore, the
OS must know how much space is needed for the private user address
space (programs and data) and the user stack.
As I understand it, the stack contains functions and local variables. And since much of the input into functions and the data resulting from any associated computations cannot be known at compile-time, the OS must allocate a static amount of memory to serve as the stack.
Given this, how does the OS determine at compile-time the sufficient amount of memory required by constituents of the stack? Given the dramatic variability of programs, I cannot imagine how the OS achieves this task. It would seem that if one tried to allocate a fixed amount of memory as the stack at compile-time, it would regularly result in either too much or too little memory. However, I presume that there is an effective mechanism in place to deal with this (to allocate an appropriate amount of memory as the stack); otherwise, stack overflows would be a common occurrence.
I would greatly appreciate it if someone could please take the time to clarify this concept.
I think you have never heard of stack overflow.
The short answer is that it cannot determine at compile time. Because if it was possible to calculate the amount of stack memory required at compile-time, there would be no such thing as stack overflow occuring as the compiler would simply give an error telling that the amount of stack memory required exceeds the limit.
Consider the simple function:
int foo()
{
return foo();
}
the function will compile successfully. But will result in stack overflow.
The stack size is normally determined by the linker. Most linkers have options for setting the stack size. The stack is then created by the program loader along with the rest of the program's address space as it reads the instructions from the executable file.
I'm doing a project where I need full control over the address space of the process. I need to move the thread's stack away from where it currently is to a predefined area chosen by me, because I need to deallocate the original stack memory. I couldn't find anything on how to do this, only how to deal with the stack size, but that's not what I need. I have two ideas how to do this, none of them being ideal:
Set ESP and EBP to my predefined area and update the stack base and stack limit fields in the thread's TEB. This sounds like a bad idea since it's hard to know if there are other places I would have to update as well, let alone the possibility of the kernel keeping bookkeeping information internally about the stack's location.
Reserve memory everywhere to basically force a new thread's stack to be allocated in the space that I've left available. This is an awful idea, I know.
Is it at all possible to do something like this? It doesn't have to be the same thread.
Edit: Anything will do as long I get to deallocate the original stack and decide the new/old stack's new location. So copying/moving the stack, killing the old thread and starting a new one with a stack at a predefined location etc. should do just fine. I don't need the old thread, I just need a way to force a thread to run at a certain location (already solved) and have its stack in a safe location decided by me. So in that case it's fine to discard the old stack data as currently I don't depend on it.
If you want to free the the system allocate stack you are opening a can of worms. The problem is that you need to know the structure of all the stack frames above your thread. These frames could reference addresses on the stack so deleting them could cause all kinds of problems.
You could create a thread with a 1-page stack and not deallocate it. Then allocate your own block of memory and move its address into the stack pointer register. in your top level thread routine.
I'm a computer undergraduate taking operating systems course. For my assignment, I am required to implement a simple thread management system.
I'm in the process of creating a struct for a TCB. According to my lecture notes, what I could have in my TCB are:
registers,
program counter,
stack pointer,
thread ID and
process ID
Now according to my lecture notes, each thread should have its own stack. And my problem is this:
Just by storing the stack pointer, can I keep a unique stack per thread? If I did so, won't one stack of a thread over write other's stack?
How can I prevent that? Limit the stack for each thread??? Please tell me how this is usually done in a normal operating system.
Please help. Thanks in advance.
The OS may control stack growth by monitoring page faults from inaccessible pages located around the stack portion of the address space. This can help with detection of stack overflows by small amounts.
But if you move the stack pointer way outside the stack region of the address space and use it to access memory, you may step into the global variables or into the heap or the code or another thread's stack and corrupt whatever's there.
Threads run in the same address space for a reason, to share code and data between one another with minimal overhead and their stacks usually aren't excepted from sharing, from being accessible.
The OS is generally unable to do anything about preventing programs from stack overflows and corruptions and helping them to recover from those. The OS simply doesn't and can't know how an arbitrary program works and what it's supposed to do, hence it can't know when things start going wrong and what to do about them. The only thing the OS can do is just terminate a program that's doing something very wrong like trying to access inaccessible resources (memory, system registers, etc) or execute invalid or inaccessible instructions.
I am having some trouble finding some suitable examples to solve my problem. I want to share 4K (4096) byte of data between user and kernel space. I found many ideas which says I have to allocate memory from kernel and mmap it in user-space. Can someone provide an example on how to do it in Linux 2.6.38. Is there any good document which explains it?
Thanks in advance.
Your proposed way is one way, but as userspace is not within your control (meaning any userspace program have a possibility of poking into the kernel), you are opening up the opportunities for malicious attack from userspace. This kernel-based memory-sharing-with-userspace is also described here:
http://www.scs.ch/~frey/linux/memorymap.html
Instead, how about allocating memory in userspace, and then from kernel use the API copy_from_user() and copy_to_user() to copy to/from userspace memory? If u want to share the memory among the different processes, then u can always use IPC related API to allocate and define the memory, eg shmget() etc. And in this case there are lots of sample codes within the kernel source itself.
eg.
fs/checksum.c: missing = __copy_from_user(dst, src, len);
Let's say I have an allocation in memory containing a string, "ABCDEFG", but I only have a pointer to the 'E'. Is it possible, on win32, to free that block, given a pointer that is within the block, but not at the start? Any allocation method would work, but a Heap* function would be the path of least resistance.
If not a native solution, have there been any custom memory managers written which offer this feature?
EDIT: This isn't an excuse to be sloppy. I'm developing an automatic memory management system using 100% compile-time metadata. This odd requirement seems to be the only thing standing in the way of getting it working, and even then it's needed only for data types based on arrays (which are slicable).
It would be possible for the memory allocation routines in the runtime library to check a given memory address against the beginning and end of every allocated block. That search accomplished, it would be easy to release the block from the beginning.
Even with clever algorithms behind it, this would incur some kind of search with each memory deallocation. And why? Just to support erroneous programs too stupid to keep track of the beginning of the blocks of memory they allocated?
The standard C idiom thrives on treating blocks of allocated memory like arrays. The pointer returned from *alloc is a pointer to the beginning of an array, and the pointer can be used with subscripts to access any element of that array, subscripts starting at 0. This has worked well enough for 40 years that I can't think of a sensible reason to introduce a change here.
I suppose if you know what the malloc() guard blocks look like, you could write a function that backs up from the pointer you pass it until it finds a 'best guess' of the original memory address and then calls free(). Why not just keep a copy of the base pointer around?
If you use VirtualAlloc to allocate memory, you can use VirtualQuery to figure out which block a pointer belongs to. Once you have the base address, you can pass this to VirtualFree to free the entire block.