catコマンドをカーネルモジュールとして実装しようとしています。私はファイルI/Oがカーネルモジュールで行われてはならないことを知っています。 insmod module.ko
を使用するたびに、出力はkilled
となります。どうすれば修正できますか?また、コードを改善するにはどうすればよいですか?
カーネルバージョン - 4.4
コード:insmodを使用してカーネルモジュールを無効にしました
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/unistd.h>
#include <linux/syscalls.h>
#include <linux/fcntl.h>
#include <asm/uaccess.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/file.h>
static char* argv[10];
static int argc = 1;
module_param_array(argv, int, &argc , 0);
static void cat(int f, char *s)
{
char buf[8192];
struct file *file;
loff_t pos = 0;
long n;
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
while((n = vfs_read(f, buf, (long)sizeof buf, &pos)) > 0)
{
//write(1, buf, n);
file = fget(f);
if (file) {
vfs_write(file, buf, (long)sizeof buf, &pos);
fput(file);
}
}
set_fs(old_fs);
}
static void __init hello_init(void)
{
int f, i;
if(argc == 1)
cat(0, "<stdin>");
else for(i=1; i<argc; i++)
{
f = filp_open(argv[i], O_RDONLY, 0);
if(f < 0)
printk("error");
else{
cat(f, argv[i]);
filp_close(f);
}
}
}
static void __exit hello_cleanup(void)
{
printk(KERN_INFO "Cleaning up module.\n");
}
module_init(hello_init);
module_exit(hello_cleanup);
ここでは、単にファイルを読み込み、上記のコードの簡易版です。 vfs_read
の部分をコメントアウトすると、私はそれをinsmodすることができますが、vfs_read
でそれは殺されたことを示します。
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/fcntl.h>
#include <asm/uaccess.h>
static void read_file(char *filename)
{
int fd;
char buf[1];
loff_t f_pos = 0;
mm_segment_t old_fs = get_fs();
set_fs(KERNEL_DS);
fd = filp_open(filename, O_RDONLY, 0);
if (fd >= 0) {
printk(KERN_DEBUG);
while (vfs_read(fd, buf, 1, &f_pos) == 1) //if this
printk("%c", buf[0]); //and this is removed I'm able to insmod it
printk("\n");
sys_close(fd);
}
set_fs(old_fs);
}
static int __init init(void)
{
read_file("/etc/shadow");
return 0;
}
static void __exit exit(void)
{ }
module_init(init);
module_exit(exit);
**あなたはコードをデバッグしようとしましたか?デバッグカーネルコードでは、あるポイントの後に 'printk()'を追加することができます。また、コードがクラッシュした場合、 'dmesg'はそれに関する追加情報を与えるかもしれません。 – Tsyvarev
dmesgはRIP []を返します。vfs_read + 0x5/0x130とfbcon_switch:未処理のfb_set_parエラーを検出しました –
user7498777
'hello_init'関数のどの枝が実行されますか? ( 'cat(0)'、 'cat(f)')ですか?あなたのモジュールは**ポインタの配列**を受け入れますが、これはおそらくあなたが期待しているものではないことに注意してください。つまり、 'argv [i]'はガーベジへのポインタであり、 'filp_open()'呼び出しのような)逆参照は**間違いです**。 – Tsyvarev