【问题标题】:Using a pointer to modify a struct使用指针修改结构
【发布时间】:2020-11-20 11:23:42
【问题描述】:

我有两个功能:

一个是系统调用:

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 活动页面:0 非活动页面: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 类型,因为我在系统调用的内核日志中打印了这个:

7 月 30 日 12:14:54 本地主机内核:TOTAL||||免费页面 = 831134 | 活动页面:360990 |非活动页面:715557 |

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

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

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

编辑:20 年 7 月 30 日美国东部标准时间下午 1:18 我修复了 malloc 仅分配指针的问题,正如 @MikeCAT 和 @"Vlad from moscow" 建议的那样,但这似乎不是系统调用没有的原因更改结构的值,但测试文件中的测试函数会。

【问题讨论】:

  • 没有很好地阅读您的问题,newMemInfo =(struct meminfo*) malloc(sizeof(struct meminfo* )); 不好,因为只分配了一个指针的大小而不是结构的大小。
  • 检查系统调用是否成功。
  • 在您的系统中,从用户应用程序访问用户内存的地址值和从内核访问用户内存的地址值是否相同?
  • @MikeCAT 好的,我看看我是否将其分配为 'newMemInfo =(struct memInfo*) malloc(sizeof(struct meminfo));'回答你的第二个问题:系统调用成功,我让它打印到内核日志,它显示了'tempFreePages'、'tempActivePages'和'tempInactivePages'的所有值。
  • @MikeCAT “是从用户应用程序访问用户内存的地址值和从内核访问用户内存的地址值相同吗?”,据我了解,内核内存与用户内存是分开的,在感觉它们存储在内存中的不同部分。

标签: c function pointers struct system-calls


【解决方案1】:

您不能直接访问__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;
}

【讨论】:

  • 我认为您的回答在这里是正确的。我无法让它工作。而不是 'res = (struct meminfo) { .mFree_pages = tempFreePages, /* ... */ }; ' 我可以只声明 meminfo 结构变量,例如:'res.mFree_pages= tempFreePages' 等吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-13
  • 1970-01-01
  • 2020-10-25
  • 1970-01-01
相关资源
最近更新 更多