编写我自己的系统调用来计算字符串指针中出现的o数量

问题描述 投票:2回答:1

所以我的任务是在linux中编写自己的系统调用。此系统调用将采用指向字符数组的指针并将所有o替换为0。系统调用将返回执行的替换次数。如果字符串大小大于128个字节,则返回-1。所以我已经实现了一个不同的系统调用,按照此链接中的步骤完全正常工作。 https://medium.com/anubhav-shrimal/adding-a-hello-world-system-call-to-linux-kernel-dad32875872。我已经仔细检查了一切,一切似乎都很好,所以我认为在我编写的系统调用或测试时它都有问题。假设是这种情况,我的系统调用有什么问题吗?我认为它可能与字符指针或某种类似的东西有关。

这是我的系统调用。

#include <linux/kernel.h>

asmlinkage int sys_my_syscall2(char * string){
    if(sizeof(string) > 128){
        return -1;
    }
    int x, count = 0;
    for(x = 0; x < sizeof(string); x++){
        if(string[x] == 'o'){
            string[x] = '0';
            count++;
        }
    }
    return count;
}

这是我的测试文件。

#include <stdio.h>
#include <linux/kernel.h>
#include <sys/syscall.h>
#include <unistd.h>
int main() {
    int syscall2 = syscall(333, "Hello World");
    printf("Syscall 333 printed %d", syscall2); 
    return 0;
}

333是我的系统调用号码。运行测试文件后,它会暂停一段非常大的时间并且似乎冻结了。即使在尝试控制-C之后,该程序似乎仍在运行。这些文件有问题吗?

c linux system-calls
1个回答
2
投票

正确的方法是:

  • 将指向字符串的指针传递给系统调用
  • 做一个strlen_user(string)来找出字符串的大小
  • 提供足够大的缓冲区来容纳字符串(例如使用kmalloc()
  • 使用copy_from_user()将字符串从用户空间复制到内核缓冲区(检查调用是否成功!)
  • 在内核缓冲区上执行替换操作
  • 使用copy_to_user()将字符串复制回用户空间
  • 如果您使用kmalloc()分配了缓冲区,请释放缓冲区。

您不应该直接访问用户空间,因为如果指针指向的内存不可用(即换出)或受保护以进行读/写,内核可能会跳过。例如,你的程序就是这种情况;尝试直接写入此内存(没有copy_to_user)将导致内核页面错误。注意:直接访问可以工作,但不安全!

此外,在使用字符串操作时,必须使用strlen(string)(或strlen(string)+1来说明终止零字节)。

© www.soinside.com 2019 - 2024. All rights reserved.