Confused use of memcpy in ext2fs library - malloc

I am reading the source code implementation of libext2fs, which is part of the project e2fsprogs used to debug Ext2/3/4 file systems. And came across one confused point about the use of method memcpy as follows.
In the library, it maintains one function ext2fs_get_mem which is used to allocate dynamic memories:
_INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void *ptr)
{
void *pp;
pp = malloc(size);
if (!pp)
return EXT2_ET_NO_MEMORY;
memcpy(ptr, &pp, sizeof (pp));
return 0;
}
The caller will call it like:
retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs)
In the above case, variable fs is just type of struct struct_ext2_filsys, all right.
The confused point is why the function ext2fs_get_mem need to call memcpy and what's the purpose? Why not directly allocate memory to the pointer void *ptr by malloc?

Related

Detours recursive behavior, Minhook works as expected. (dxgi Present call)

Trying to hook to the Present call in Dx12/Dxgi. Is not possible to get the function address via GetProcAddress and some people already figured it out how to obtain the offset directly.
Using Minhook/Kiero (https://github.com/Rebzzel/kiero) it works correctly, say:
typedef HRESULT(APIENTRY* Present12) (IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags);
static Present12 oPresent = NULL;
HRESULT APIENTRY ownPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
{
return oPresent(pSwapChain,SyncInterval, Flags);
}
// On the actual hook part:
void* target = (void*)g_methodsTable[_index];
MH_CreateHook(target, _function, _original);
MH_EnableHook(target);
// Where target is the pointer to the offset where the actual function is located
// _function is the detour function, my ownPresent
// _original will be pointing to the original function
This works as expected, from my own Present:
HRESULT APIENTRY ownPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
{
return oPresent(pSwapChain,SyncInterval, Flags);
}
All good, the original Present is called at the end.
However, tried to migrate this to Detours and the comparable code would be:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
void* target = (void*)g_methodsTable[_index];
DetourAttach(&(PVOID&)target, _function);
if (_original)
{
*_original = target;
}
DetourTransactionCommit();
It works in the sense that the detour function is being called, however, seems that now the target pointer has the code modified to perform the jump, because now ownPresent calls to ownPresent again, it's recursive.
Not sure if Detours stores a copy of the original code the same way MinHook does, so I can point to the original function and avoid this recursive behavior.
Please let me know if I am using detours incorrectly. Not really sure how to proceed.
Thanks in advance!

Is it possible to link a static library with linux kernel?

If I write a simple library, e.g.
void swap(int *a, int *b) {
int temp;
temp = *a;
*a = *b;
*b = temp;
}
After compiled to a static library, say "swap.a", is it possible to call this function and link from a kernel code?
This question says linking shared library in kernel is impossible, because loading a shared library demands a loader, which is running on user space. But I don't understand why static library cannot be used in kernel space, as the loader is not needed.

Linux kernel datastructures

I am new to module writing and need a circular buffer[1] and a vector. Since the Linux kernel apparently provides some data structures (lib) (list, trees), I was wondering if there is a vector equivalent?
While I think I am well capable to write my own, I prefer libraries for such things to prevent the duplication of code and to avoid errors.
[1] Found while composing the question, kfifo, also Queues in the Linux Kernel might be of interest.
As far as I know there is no implementation of vectors till 4.1 Linux kernel. And it does not make any sense to have one as vectors can be designed with the basic data structures whose implementation is already provided in Linux kernel.
I'm a bit late, but if anyone needs to implement a generalized vector in C, it can be done using void pointers and a sizeof operator on initialization. It would look something like this:
struct MyVec {
void *data;
size_t stored_sizeof;
size_t size;
size_t allocated_size
};
#define STARTING_ALLOCATED_SIZE 10
void MyVec_init(struct MyVec *self, size_t sizeof_data_type) {
self->stored_sizeof = sizeof_data_type;
self->data = malloc(self->stored_sizeof * STARTING_ALLOCATED_SIZE);
self->size = 0;
self->allocated_size = STARTING_ALLOCATED_SIZE;
}
void MyVec_deinit(struct MyVec *self) {
free(self->data);
}
bool MyVec_at(struct MyVec *self, size_t index, void *to_fill) {
if (index >= size)
return false;
memcpy(to_fill, self->data + (index * self->stored_sizeof), self->stored_sizeof);
return true;
}
and all the other methods that you might need, just being sure to use stored_sizeof whenever indexing, adding/removing elements, and the like.

How to free up memory after converting a managed string to UTF-8 encoded unmanaged char*?

I'm not familiar with C++/CLI so not sure how to free up the memory when using the code below (got the solution here and modified a little):
char* ManagedStringToUnmanagedUTF8Char( String^ s )
{
array<unsigned char> ^bytes = Encoding::UTF8->GetBytes( s );
pin_ptr<unsigned char> pinnedPtr = &bytes[0];
return (char*)pinnedPtr;
}
The above code is working when I tested it by writing the char in a text file. Please let me know if I'm missing something (need to clean up pinnedPtr?).
Now when I use it:
char* foobar = ManagedStringToUnmanagedUTF8Char("testing");
//do something with foobar
//do I need to free up memory by deleting foobar here?
//I tried 'delete foobar' or free(foobar) but it crashes my program
Hans Passant's comment is correct that the returned pointer to the buffer can be moved in memory by the garbage collector. This is because, when the function stack unwinds, pin_ptr will unpin the pointer.
The solution is to
Obtain the System::String buffer and pin it so that the GC cannot
move it.
Allocate memory on the unmanaged heap (or just heap) where
it is not under the GC's jurisdiction, and cannot be moved by the
GC.
Copy memory (and convert to desired encoding) from the
System::String buffer to the buffer allocated on the unmanaged heap.
Unpin the pointer so the GC can once again move the System::String
in memory. (This is done when pin_ptr goes out of the function
scope.)
Sample code:
char* ManagedStringToUnmanagedUTF8Char(String^ str)
{
// obtain the buffer from System::String and pin it
pin_ptr<const wchar_t> wch = PtrToStringChars(str);
// get number of bytes required
int nBytes = ::WideCharToMultiByte(CP_UTF8, NULL, wch, -1, NULL, 0, NULL, NULL);
assert(nBytes >= 0);
// allocate memory in C++ where GC cannot move
char* lpszBuffer = new char[nBytes];
// initialize buffer to null
ZeroMemory(lpszBuffer, (nBytes) * sizeof(char));
// Convert wchar_t* to char*, specify UTF-8 encoding
nBytes = ::WideCharToMultiByte(CP_UTF8, NULL, wch, -1, lpszBuffer, nBytes, NULL, NULL);
assert(nBytes >= 0);
// return the buffer
return lpszBuffer;
}
Now, when using:
char* foobar = ManagedStringToUnmanagedUTF8Char("testing");
//do something with foobar
//when foobar is no longer needed, you need to delete it
//because ManagedStringToUnmanagedUTF8Char has allocated it on the unmanaged heap.
delete foobar;
I'm not familiar with Visual-C++ either, but according to this article
Pinning pointers cannot be used as: [...] the return type of a function
I'm not sure whether the pointer will be valid when the function ends (even though it's disguised as a char*.
It seems that you declare some local variables in the function that you want to pass to the calling scope. 'However, possibly these will be out of scope anyway when you return from the function.
Maybe you should reconsider what you are trying to achieve in the first place?
Note, that in the article you have referenced a std::string (passed by value, i.e. by copy) is used as return parameter.
std::string managedStringToStlString( System::String ^s )
{
Encoding ^u8 = Encoding::UTF8;
array<unsigned char> ^bytes = u8->GetBytes( s );
pin_ptr<unsigned char> pinnedPtr = &bytes[0];
return string( (char*)pinnedPtr );
}
Thereby no local variables are passed out of their scope. The string is handled over by copy as an unmanaged std::string. This is exactly what this post suggests.
When you need a const char* later, you can use the string::c_str() method to get one. Note, that you can also write std::string to a file using file streams.
Is this an option for you?

Question about pthreads & pointers

Here is an example of thread creation code that is often seen. pthread_create uses a lot of pointers/addresses and I was wondering why this is so.
pthread_t threads[NUM_THREADS];
long t;
for(t=0; t<NUM_THREADS; t++){
rc = pthread_create(&threads[t], NULL, &someMethod, (void *)t);
}
Is there a major advantage or difference for using the '&' to refer to the variable array 'threads' as well as 'someMethod' (as opposed to just 'threads' and just 'someMethod')? And also, why is 't' usually passed as a void pointer instead of just 't'?
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg);
You need to pass a pointer to a pthread_t variable to pthread_create. &threads[t] and threads+t achieve this. threads[t] does not. pthread_create requires a pointer so it can return a value through it.
someMethod is a suitable expression for the third argument, since it's the address of the function. I think &someMethod is redundantly equivalent, but I'm not sure.
You are casting t to void * in order to jam a long into a void *. I don't think a long is guaranteed to fit in a void *. It's definitely a suboptimal solution even if the guarantee exists. You should be passing a pointer to t (&t, no cast required) for clarity and to ensure compatibility with the expected void *. Don't forget to adjust someMethod accordingly.
pthread_t threads[NUM_THREADS];
long t;
for (t=0; t<NUM_THREADS; t++) {
rc = pthread_create(&threads[t], NULL, someMethod, &t);
}

Resources