编写我自己的系统调用来计算字符串指针中出现了多少个 o
Writing my own system call to count how many o's appear in string pointer
所以我的任务是在 linux 中编写自己的系统调用。该系统调用将采用指向字符数组的指针并将所有 o 替换为 0。系统调用将 return 执行的替换次数。如果字符串大小大于 128 字节,它将 return -1。所以我已经实现了一个不同的系统调用,它可以按照 link 中的步骤完全正常工作。
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 是我的系统调用的编号。 运行测试文件后,它停顿了很长一段时间,似乎冻结了。即使在尝试使用 control-C 之后,程序似乎仍然 运行。这些文件有问题吗?
正确的方法是:
将指向字符串的指针传递给系统调用
做一个strlen_user(string)
找出字符串的大小
提供一个足够大的缓冲区来容纳字符串(例如 kmalloc()
)
使用copy_from_user()
将字符串从用户空间复制到内核缓冲区(检查调用是否成功!)
对内核缓冲区执行替换操作
使用copy_to_user()
将字符串复制回用户空间
如果您使用 kmalloc()
分配缓冲区,请释放缓冲区。
你不应该直接访问用户空间,因为如果你的指针指向的内存不可用(即换出)或受 read/write 保护,内核可能会出错。例如,您的程序就是这种情况;尝试直接写入此内存(没有 copy_to_user)将导致内核页面错误。 注意:直接访问可以工作,但不安全!
此外,在操作字符串时,您必须使用 strlen(string)
(或 strlen(string)+1
来说明终止零字节)。
所以我的任务是在 linux 中编写自己的系统调用。该系统调用将采用指向字符数组的指针并将所有 o 替换为 0。系统调用将 return 执行的替换次数。如果字符串大小大于 128 字节,它将 return -1。所以我已经实现了一个不同的系统调用,它可以按照 link 中的步骤完全正常工作。 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 是我的系统调用的编号。 运行测试文件后,它停顿了很长一段时间,似乎冻结了。即使在尝试使用 control-C 之后,程序似乎仍然 运行。这些文件有问题吗?
正确的方法是:
将指向字符串的指针传递给系统调用
做一个
strlen_user(string)
找出字符串的大小提供一个足够大的缓冲区来容纳字符串(例如
kmalloc()
)使用
copy_from_user()
将字符串从用户空间复制到内核缓冲区(检查调用是否成功!)对内核缓冲区执行替换操作
使用
copy_to_user()
将字符串复制回用户空间如果您使用
kmalloc()
分配缓冲区,请释放缓冲区。
你不应该直接访问用户空间,因为如果你的指针指向的内存不可用(即换出)或受 read/write 保护,内核可能会出错。例如,您的程序就是这种情况;尝试直接写入此内存(没有 copy_to_user)将导致内核页面错误。 注意:直接访问可以工作,但不安全!
此外,在操作字符串时,您必须使用 strlen(string)
(或 strlen(string)+1
来说明终止零字节)。