Reputation: 3
I have two functions:
one is a system call:
asmlinkage long sys_memstats(struct meminfo __user *info){
Where I modify the values in meminfo struct like so:
info->mFree_pages = tempFreePages;
info->mActive_pages =tempActivePages;
info->mInactive_pages=tempInactivePages;
And it was not passing the correct values to the meminfo struct in this test file:
int main (void){
struct meminfo *newMemInfo;
newMemInfo =(struct meminfo*) malloc(sizeof(struct meminfo* ));
newwMemInfo->mFree_pages =0;
newMemInfo->mActive_pages=0;
newMemInfo->mInactive_pages=0;
int status;
status = syscall(335, newMemInfo);
//testPointerParamFunc(newMemInfo);
printf("Free Pages: %ld \n Active Pages:%ld \n Inactive Pages:%ld ", newMemInfo->mFree_pages, newMemInfo->mActive_pages, newMemInfo->mInactive_pages );
free(newMemInfo);
return 0;
}
So I created a the following function inside my systemcall test file to see if I was modifying the struct correctly:
void testPointerParamFunc(struct meminfo* temp){
temp->mFree_pages =10;
temp->mActive_pages=21;
temp->mInactive_pages=12;
}
And called it (testPointerParamFunc(newMemInfo);
) instead of the systemcall in my code and I get the correct output for those members in the meminfo struct when running the test function:
./test4
Free Pages: 10
Active Pages:21
Inactive Pages:12
I'm using the same pointer logic for both the system call and the function, but when using the system call, the newMemInfo isn't changed, I still get the same values I declared in main(): ./test4 Free Pages: 0 Active Pages:0 Inactive Pages:0
I know that the values for:
info->mFree_pages = tempFreePages;
info->mActive_pages =tempActivePages;
info->mInactive_pages=tempInactivePages;
printk(KERN_INFO "TOTAL||||Free pages = %ld | Active Pages: %ld | Inactive Pages: %ld |\n", tempFreePages,tempActivePages,tempInactivePages);
Are all valid long
types because I print out this in the kernel log from the system call:
Jul 30 12:14:54 localhost kernel: TOTAL||||Free pages = 831134 | Active Pages: 360990 | Inactive Pages: 715557 |
What is the difference between passing the struct pointer in testPointerParamFunc(newMemInfo)
and passing the pointer in syscall(335, newMeminfo)
?
I know the __user macro specified that the pointer *info exists in user space, but does it do more than that?
How do I change my systemcall parameters so that I pass those values to the struct of the pointer parameter?
EDIT: 1:18PM EST 7/30/20 I fixed the malloc only allocating for a pointer as @MikeCAT and @"Vlad from moscow" suggested, but that does not seem to be the cause for why systemcall doesn't change the struct's values, but the test function within the test file does.
Upvotes: 0
Views: 75
Reputation: 6984
you must not access __user
memory directly but have to wrap it through copy_to_user()
(or copy_from_user()
.
asmlinkage long sys_memstats(struct meminfo __user *info)
{
struct meminfo res;
/* ... */
res = (struct meminfo) {
.mFree_pages = tempFreePages,
/* ... */
};
if (copy_to_user(info, &res, sizeof res))
return -EFAULT;
}
Upvotes: 1