I'd like to translate the delegate members .ptr and .funcptr to an absolute address that matches something in the executable image in DRAM.
The goal is not to call, neither to modify, but rather to allow the target to disassemble itself at run-time, when its own image is loaded in DRAM.
So far it already works with global functions.
Is it possible ?
The address of a delegate is the value of the .funcptr property. The type of this property is a bit misleading - it is of type function and does not list the hidden argument that is actually expected for passing the context in, but for just getting the address, you can ignore the type (explicitly casting to void* or size_t if you like to change the type) and just look at the address.
This isn't the address in physical memory, you'd have to ask the operating system for that, but since the virtual address it gives is automatically translated by the processor, it is most likely what you want anyway.
Related
I am trying to get an idea on how does memory mapping take place using the system call mmap.
So far I know mmap takes arguments from the user and returns a logical address of where the file is stored. When the user tries to access it takes this address to the map table converts it to a a physical address and carries the operation as requested.
However I found articles as code example and Theoretical explanation
What it mentions is the memory mapping is carried out as:
A. Using system call mmap ()
B. file operations using (struct file *filp, struct vm_area_struct *vma)
What I am trying to figure out is:
How the arguments passed in the mmap system call are used in the struct vm_area_struct *vma) More generally how are these 2 related.
for instance: the struct vm_area_struct has arguments such as starting address, ending address permissions,etc. How are the values sent by the user used to fill values of these variables.
I am trying to write a driver so, Does the kernal fill the values for variables in the structure for us and I simply use it to call and pass values to remap_pfn_range
And a more fundamental question, why is a different file systems operation needed. The fact that mmap returns the virtual address means that it has already achieved a mapping doesnt it ?
Finally I am not that clear about how the entire process would work in user as well as kernal space. Any documentation explaining the process in details would be helpful.
I am developing a simple device driver for study. With a lot of testing, I am creating so many errors which finally leads my computer to blue screen. I am sure that the reason for this is memory crash. So now I want to check if my code can access to Kernel memory before going further.
My question is what function can check whether it is accessible or not in kernel memory. For instance, there is a pointer structure with two fields and I want to access the first field which is also a pointer but do now know whether it really has an accessible value or just trash value.
In this given context, I need to check it out to make sure that I am not getting blue screen.
Thanks in advance!
this is impossible for kernel memory. you must know exactly are kernel address is valid and will be valid during access. if you get address from user mode - you can and must use ProbeForRead or ProbeForWrite. but this is only for user-mode buffer. for any kernel memory (even valid and resident) this function just raise exception. from invalid access to kernel memory address no any protection. try - except handler not help here - you just got PAGE_FAULT_IN_NONPAGED_AREA bug check
For instance, there is a pointer structure with two fields and I want
to access the first field which is also a pointer but do now know
whether it really has an accessible value or just trash value.
from where you got this pointer ? who fill this structure ? you must not check. you must know at begin that this pointer is valid and context of structure will be valid during time you use it. otherwise your code already wrong and buggy
In LDD3's example, access_ok() is placed at the beginning of ioctl method of a kernel module to check whether a pointer passed from userspace is valid. It is correct when userspace application calls ioctl() system call, and passes it an address of a variable. In some cases, however, ioctl() system call is invoked with a value instead of a pointer as third argument and finally the second argument of access_ok() in kernel module.
I've tried to pass an integer as access_ok()'s second argument and it works fine. No error was reported. But I don't very sure that is this usage correct?
For example, if I invoke ioctl() in userspace with it's third argument to be '3'. Then, in ioctl() method of struct file_operations, access_ok() will receive 3 as it's second argument. Because the access_ok() expects a pointer, so it translates 3 to be a userspace pointer. Obversely, it's wrong...
Actually, access_ok's check is rough. Description of the function (in the source file) say:
Note that, depending on architecture, this function probably just
checks that the pointer is in the user space range - after calling
this function, memory access functions may still return -EFAULT.
E.g., according to source arch/x86/include/asm/uaccess.h, on x86 access_ok just checks that given address points to the lower area (because kernel besides in the upper area). So, it returns true for address equal to 3.
It is copy_from_user/copy_to_user who return a final verdict about user memory accessibility.
Userspace programs can give you any random value as a pointer, so access_ok() must be able to handle any random value.
So it is definitely OK to call access_ok() with a non-pointer value.
However, unless you are actually going to try to access that memory location, calling access_ok() is utterly pointless.
(For that matter, you should, if possible, avoid access_ok() and just check the actual userspace accesses (get_user() etc.) for errors.)
I have one doubt in ip_rt_ioctl function
In case of route addition, first a copy_from_user is made for the structure struct rtentry and then the copied data from is subsequently used in rtentry_to_fib_config function, including the rtentry.rt_dev field which usually is the device name.
My understanding is copy_from_user does a shallow copy. So since the rtentry.rt_dev field is again a character pointer. So likely the contents of the pointer will not get copied.
Hence even after copy the device name will be pointer to the user space address.
So is it right to access the user space address from kernel space ?
It's OK to refer to user-space address from kernel-space while kernel is bound to that process' context (this is true for syscall handlers). In that case, proper page table is set and it's safe to refer to user process' memory.
However, you should always check validity of address or use copy_from_user() that does that.
I have some code (which I cannot change) that I need to get working in a native Win32 environment. This code calls mmap() and munmap(), so I have created those functions using CreateFileMapping(), MapViewOfFile(), etc., to accomplish the same thing. Initially this works fine, and the code is able to access files as expected. Unfortunately the code goes on to munmap() selected parts of the file that it no longer needs.
x = mmap(0, size, PROT_READ, MAP_SHARED, fd, 0);
...
munmap(x, hdr_size);
munmap(x + foo, bar);
...
Unfortunately, when you pass a pointer into the middle of the mapped range to UnmapViewOfFile() it destroys the entire mapping. Even worse, I can't see how I would be able to detect that this is a partial un-map request and just ignore it.
I have tried calling VirtualFree() on the range but, unsurprisingly, this produces ERROR_INVALID_PARAMETER.
I'm beginning to think that I will have to use static/global variables to track all the open memory mappings so that I can detect and ignore partial unmappings, but I hope you have a better idea...
edit:
Since I wasn't explicit enough above: the docs for UnMapViewOfFile do not accurately reflect the behavior of that function.
Un-mapping the whole view and remapping pieces is not a good solution because you can only suggest a base address for a new mapping, you can't really control it. The semantics of munmap() don't allow for a change to the base address of the still-mapped portion.
What I really need is a way to find the base address and size of a already-mapped memory area.
edit2: Now that I restate the problem that way, it looks like the VirtualQuery() function will suffice.
It is quite explicit in the MSDN Library docs for UnmapViewOfFile:
lpBaseAddress A pointer to the
base address of the mapped view of a
file that is to be unmapped. This
value must be identical to the value
returned by a previous call to the
MapViewOfFile or MapViewOfFileEx
function.
You changing the mapping by unmapping the old one and creating a new one. Unmapping bits and pieces isn't well supported, nor would it have any useful side-effects from a memory management point of view. You don't want to risk getting the address space fragmented.
You'll have to do this differently.
You could keep track each mapping and how many pages of it are still allocated by the client and only free the mapping when that counter reaches zero. The middle sections would still be mapped, but it wouldn't matter since the client wouldn't be accessing that memory anyway.
Create a global dictionary of memory mappings through this interface. When a mapping request comes through, record the address, size and number of pages that are in the range. When a unmap request is made, find out which mapping owns that address and decrease the page count by the number of pages that are being freed. When that count reaches zero, really unmap the view.