據我瞭解系統控制變量,kernel.printk
中的第一個值是內核消息必須小於要寫入控制檯的數量。所以,如果是4
,那麼由此產生的消息纔可見與dmesg
:什麼讓printk()寫入控制檯,即使它以KERN_INFO開頭?
printk(KERN_INFO "This is a kernel message.");
將出現在控制檯上的消息的唯一情況是如果它是由KERN_ERR
,KERN_CRIT
,KERN_INFO
,或KERN_EMERG
前面。即使內核模塊發生問題,我也希望像上面這樣的消息不會出現在我的屏幕上。
我正在嘗試的一件事是系統調用攔截。有些人完美無瑕,其他人沒有。但有幾次,我的不成功的內核模塊標有KERN_INFO
的消息堵塞了我的控制檯,並沒有給我足夠的時間在消息之間卸載它們。螺釘向上在這些代碼行中某處出現:
…
#define INODE_IS_DEVICE(inode) (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode))
#define INODE_IS_RAW(inode) (imajor(inode) == RAW_MAJOR)
#define INODE_IS_RAW_DEVICE(inode) (INODE_IS_DEVICE(inode) || INODE_IS_RAW(inode))
#define TEST_OPEN_FLAGS(flags) ((flags & O_WRONLY) || (flags & O_RDWR))
…
struct inode *current_inode;
…
struct inode* get_inode_from_pathname(const char pathname) {
struct path path;
kern_path(pathname, LOOKUP_FOLLOW, &path);
return path.dentry->d_inode;
}
asmlinkage int (*real_open)(const char* __user, int, int);
asmlinkage int custom_open(const char* __user file_name, int flags, int mode) {
current_inode = get_inode_from_pathname(file_name);
printk(KERN_INFO "intercepted: open(\"%s\", %X, %X)\n", file_name, flags, mode);
if (INODE_IS_RAW_DEVICE(inode) && TEST_OPEN_FLAGS(flags)) {
printk(KERN_INFO "Intercepted call to write to block device %s.\n", file_name);
}
return real_open(file_name, flags, mode);
}
…
void hack(void) {
make_rw((unsigned_long)sys_call_table);
real_open = (void*)*(sys_call_table + __NR_open);
*(sys_call_table + __NR_open) = (unsigned_long)custom_open;
make_ro((unsigned_long)sys_call_table);
}
void restore(void) {
make_rw((unsigned_long)sys_call_table);
*(sys_call_table + __NR_open) = (unsigned_long)real_open;
make_ro((unsigned_long)sys_call_table);
}
的代碼make_rw
和make_ro
是相同的那些發現here。編譯這段代碼給了我沒有任何錯誤,但是加載模塊會導致消息被放到控制檯以及某種類型的崩潰或錯誤。請注意,當代碼裏面custom_open
塊替換
printk(KERN_INFO "intercepted: open(\"%s\", %X, %X)\n", file_name, flags, mode);
if (file_name == "/dev/sda" && TEST_OPEN_FLAGS(flags)) {
printk("Intercepted call to write to block device.");
return -EPERM;
}
return real_open(file_name, flags, mode);
一切正常,我想它的方式。用print(KERN_INFO "i_mode of %s: %hu\n", file_name, current_inode->i_mode);
代替custom_open
的控制流程語句會產生完全相同的問題。
我不確定這裏產生的錯誤是什麼。任何見解?
'cat/proc/sys/kernel/printk'說什麼? – Armali