1

システム コール write は次のように定義されています。

SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, size_t, count)
{
     struct file *file;
     ssize_t ret = -EBADF;
     int fput_needed;

     file = fget_light(fd, &fput_needed);
     if (file) {
             loff_t pos = file_pos_read(file);
             ret = vfs_write(file, buf, count, &pos);
             file_pos_write(file, pos);
             fput_light(file, fput_needed);
     }

     return ret;
}

変数bufをコピーしてコンテンツを変更し、この新しい変数を次の場所で使用したいと思います:

vfs_write(file, new_buf, count, &pos);

を使用して char ポインター変数にメモリを割り当てようとしましたが、) をkmalloc使用copy_from_user(してコピーを行いました。最後に、新しい変数 at を使用しましたvfs_write()。カーネルを再コンパイルしてシステムを再起動すると、カーネル パニック エラー メッセージが表示されます。

カーネル パニック エラー メッセージを生成する実装は次のとおりです。

SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, size_t, count){
    struct file *file;
    ssize_t ret = -EBADF;
    int fput_needed;
    char *data;

    data = kmalloc(count, GFP_KERNEL);
    if(!data)
        return ret;

    copy_from_user(data, buf, count);

    file = fget_light(fd, &fput_needed);
    if (file) {
        loff_t pos = file_pos_read(file);
        ret = vfs_write(file, data, count, &pos);
        file_pos_write(file, pos);
        fput_light(file, fput_needed);
    }

    return ret;
}

このコピーをカーネル モードで行うにはどうすればよいですか?

Linux Mint 12 を使用しています - カーネル バージョン: 3.0.30

4

1 に答える 1

0

おそらくコードも投稿する必要があります。writeつまり、エラーの場所を特定するためにシステム コールに加えた変更です。

とはいえ、システム コールにカーネル メモリを使用できないようにするためのチェックが行われています。プロセスのユーザーアドレス空間にバッファを割り当てるか(悪い)、チェックを無効にする必要があります(それほど悪くはありません)。

私は3.0カーネルに精通していませんが、この答えは有望に見えます:

mm_segment_t old_fs;

old_fs = get_fs();
set_fs(KERNEL_DS);
/* Your syscall here */
set_fs(old_fs);
于 2013-03-20T02:39:31.050 に答える