使用指针修改结构

Using a pointer to modify a struct

我有两个功能:

一个是系统调用:

asmlinkage long sys_memstats(struct meminfo __user *info){

我在哪里修改 meminfo 结构中的值,如下所示:

    info->mFree_pages = tempFreePages;
    info->mActive_pages =tempActivePages;
    info->mInactive_pages=tempInactivePages;

并且它没有将正确的值传递给此测试文件中的 meminfo 结构:

        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;
    }

所以我在我的系统调用测试文件中创建了以下函数来查看我是否正确地修改了结构:

void testPointerParamFunc(struct meminfo*  temp){
  temp->mFree_pages =10;
  temp->mActive_pages=21;
  temp->mInactive_pages=12;
}

并在我的代码中调用它 (testPointerParamFunc(newMemInfo);) 而不是系统调用,当 运行 测试函数时,我得到了 meminfo 结构中那些成员的正确输出:

./test4
Free Pages: 10
 Active Pages:21
 Inactive Pages:12

我对系统调用和函数使用相同的指针逻辑,但是当使用系统调用时,newMemInfo 没有改变,我仍然得到与在 main() 中声明的相同的值: ./test4 免费页面:0 活跃 Pages:0 不活动 Pages:0

我知道以下值:

  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);

都是有效的 long 类型,因为我在系统调用的内核日志中打印了这个:

Jul 30 12:14:54 localhost kernel: TOTAL||||Free pages = 831134 | Active Pages: 360990 | Inactive Pages: 715557 |

testPointerParamFunc(newMemInfo)中传递struct指针和在syscall(335, newMeminfo)中传递指针有什么区别?

我知道 __user 宏指定指针 *info 存在于用户 space 中,但它的作用不止于此吗?

如何更改系统调用参数以便将这些值传递给指针参数的结构?

编辑:1:18PM EST 2020 年 7 月 30 日我修复了 malloc 只分配一个指针作为 @MikeCAT 和 @"Vlad from moscow" 建议,但这似乎不是原因系统调用不会更改结构的值,但测试文件中的测试函数会。

您不能直接访问 __user 内存,而必须通过 copy_to_user()(或 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;
}