Пишу свой собственный системный вызов, чтобы подсчитать, сколько o появилось в указателе строки - PullRequest
2 голосов
/ 26 марта 2019

Итак, мне было поручено написать собственный системный вызов в Linux.Этот системный вызов возьмет указатель на массив символов и заменит все 0 на 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 программа все еще кажется запущенной.Есть ли проблема с этими файлами?

1 Ответ

2 голосов
/ 26 марта 2019

Правильный способ:

  • Передать указатель на строку в системный вызов

  • сделать strlen_user(string), чтобы узнать размерстроки

  • Предоставьте достаточно большой буфер для хранения строки (например, с kmalloc())

  • , используйте copy_from_user() для копированиястрока из пространства пользователя в буфер ядра (проверьте, успешно ли выполнен вызов!)

  • Выполните операцию замены в буфере ядра

  • use copy_to_user() чтобы скопировать строку обратно в пространство пользователя

  • Освободить буфер, если вы выделите его с помощью kmalloc().

Вы не должны получать доступ к пространству пользователянапрямую, так как ядро ​​может работать, если указанная вашим указателем память недоступна (т.е. выгружена) или защищена для чтения / записи.Это, например, случай в вашей программе;Попытка записи в эту память напрямую (без copy_to_user) приведет к ошибке страницы ядра. Примечание: Прямой доступ может работать, но это не безопасно!

Кроме того, вы должны использовать strlen(string) (или strlen(string)+1 для учета завершающего нулевого байта) при работе со строками.

...