首页 > 解决方案 > 使用指针修改结构

问题描述

我有两个功能:

一个是系统调用:

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);并在我的代码中调用它(

./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)传递结构指针和传递指针有什么区别syscall(335, newMeminfo)

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

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

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

标签: cfunctionpointersstructsystem-calls

解决方案


您不能__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;
}

推荐阅读